WebGLRenderer.js 150.1 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

10 11 12
	// By default you can use just up to 4 directional / point lights total.
	// ANGLE implementation (Chrome/Firefox on Windows) is bound to
	// 10 varying vectors due to DirectX9 limitation.
M
Mr.doob 已提交
13

14
	var _this = this,
15
	_gl, _programs = [],
16 17
	_currentProgram = null,
	_currentFramebuffer = null,
M
Mr.doob 已提交
18 19 20
	_currentMaterialId = -1,
	_currentGeometryGroupHash = null,
	_geometryGroupCounter = 0,
M
Mr.doob 已提交
21

A
alteredq 已提交
22
	// gl state cache
23

24 25
	_oldDoubleSided = null,
	_oldFlipSided = null,
A
alteredq 已提交
26
	_oldBlending = null,
M
Mr.doob 已提交
27 28
	_oldDepthTest = null,
	_oldDepthWrite = null,
29 30 31
	_oldPolygonOffset = null,
	_oldPolygonOffsetFactor = null,
	_oldPolygonOffsetUnits = null,
A
alteredq 已提交
32
	_oldLineWidth = null,
M
Mikael Emtinger 已提交
33
	_cullEnabled = true,
34

35 36 37 38 39
	_viewportX = 0,
	_viewportY = 0,
	_viewportWidth = 0,
	_viewportHeight = 0,

40
	// camera matrices caches
41 42

	_frustum = [
43 44 45 46 47 48 49 50
		new THREE.Vector4(),
		new THREE.Vector4(),
		new THREE.Vector4(),
		new THREE.Vector4(),
		new THREE.Vector4(),
		new THREE.Vector4()
	 ],

51
	_projScreenMatrix = new THREE.Matrix4(),
52
	_projectionMatrixArray = new Float32Array( 16 ),
53
	_viewMatrixArray = new Float32Array( 16 ),
54

55
	_vector3 = new THREE.Vector4(),
56

A
alteredq 已提交
57
	// light arrays cache
58

A
alteredq 已提交
59 60
	_lights = {

61
		ambient: [ 0, 0, 0 ],
A
alteredq 已提交
62
		directional: { length: 0, colors: new Array(), positions: new Array() },
63
		point: { length: 0, colors: new Array(), positions: new Array(), distances: new Array() }
A
alteredq 已提交
64 65 66

	},

67
	// parameters
68

69
	parameters = parameters || {},
M
Mr.doob 已提交
70

71 72
	_canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElement( 'canvas' ),
	_stencil = parameters.stencil !== undefined ? parameters.stencil : true,
73
	_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false,
74 75
	_antialias = parameters.antialias !== undefined ? parameters.antialias : false,
	_clearColor = parameters.clearColor !== undefined ? new THREE.Color( parameters.clearColor ) : new THREE.Color( 0x000000 ),
M
Mr.doob 已提交
76
	_clearAlpha = parameters.clearAlpha !== undefined ? parameters.clearAlpha : 0,
77
	_maxLights = parameters.maxLights !== undefined ? parameters.maxLights : 4;
M
Mr.doob 已提交
78

M
Mr.doob 已提交
79
	this.info = {
80

M
Mr.doob 已提交
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
		memory: {

			programs: 0,
			geometries: 0,
			textures: 0

		},

		render: {

			calls: 0,
			vertices: 0,
			faces: 0

		}
96

97
	};
M
Mr.doob 已提交
98

99
	this.maxMorphTargets = 8;
N
Nicolas Garcia Belmonte 已提交
100
	this.domElement = _canvas;
M
Mr.doob 已提交
101

N
Nicolas Garcia Belmonte 已提交
102
	this.autoClear = true;
M
Mr.doob 已提交
103 104 105 106
	this.autoClearColor = true;
	this.autoClearDepth = true;
	this.autoClearStencil = true;

107
	this.sortObjects = true;
N
Nicolas Garcia Belmonte 已提交
108

109
	this.autoUpdateObjects = true;
110
	this.autoUpdateScene = true;
111 112 113 114 115 116 117

	// physically based shading

	this.gammaInput = false;
	this.gammaOutput = false;
	this.physicallyBasedShading = false;

118 119 120 121 122 123 124 125 126 127 128
	// shadow map

	this.shadowMapBias = 0.0039;
	this.shadowMapDarkness = 0.5;
	this.shadowMapWidth = 512;
	this.shadowMapHeight = 512;

	this.shadowCameraNear = 1;
	this.shadowCameraFar = 5000;
	this.shadowCameraFov = 50;

129
	this.shadowMap = [];
130

131
	this.shadowMapEnabled = false;
132
	this.shadowMapAutoUpdate = true;
133
	this.shadowMapSoft = true;
134

M
Mr.doob 已提交
135
	var _cameraLight, _shadowMatrix = [];
136 137 138 139

	var depthShader = THREE.ShaderLib[ "depthRGBA" ];
	var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms );

M
Mr.doob 已提交
140
	var _depthMaterial = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms } );
141

M
Mr.doob 已提交
142
	var _depthMaterialMorph = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, morphTargets: true } );
143 144 145 146

	_depthMaterial._shadowPass = true;
	_depthMaterialMorph._shadowPass = true;

147 148 149 150
	// Init GL

	try {

151
		if ( ! ( _gl = _canvas.getContext( 'experimental-webgl', { antialias: _antialias, stencil: _stencil, preserveDrawingBuffer: _preserveDrawingBuffer } ) ) ) {
152 153 154 155 156

			throw 'Error creating WebGL context.';

		}

M
Mr.doob 已提交
157 158 159 160 161 162 163 164
		console.log(
			navigator.userAgent + " | " +
			_gl.getParameter( _gl.VERSION ) + " | " +
			_gl.getParameter( _gl.VENDOR ) + " | " +
			_gl.getParameter( _gl.RENDERER ) + " | " +
			_gl.getParameter( _gl.SHADING_LANGUAGE_VERSION )
		);

165 166 167 168 169 170 171 172
	} catch ( error ) {

		console.error( error );

	}

	_gl.clearColor( 0, 0, 0, 1 );
	_gl.clearDepth( 1 );
173
	_gl.clearStencil( 0 );
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190

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

	_gl.frontFace( _gl.CCW );
	_gl.cullFace( _gl.BACK );
	_gl.enable( _gl.CULL_FACE );

	_gl.enable( _gl.BLEND );
	_gl.blendEquation( _gl.FUNC_ADD );
	_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA );

	_gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );

	_cullEnabled = true;

	//
M
Mr.doob 已提交
191

M
Mr.doob 已提交
192
	this.context = _gl;
193

A
alteredq 已提交
194
	var _supportsVertexTextures = ( maxVertexTextures() > 0 );
M
Mikael Emtinger 已提交
195

M
Mikael Emtinger 已提交
196
	// prepare sprites
M
Mr.doob 已提交
197 198

	var _sprite = {};
M
Mikael Emtinger 已提交
199 200 201 202

	_sprite.vertices = new Float32Array( 8 + 8 );
	_sprite.faces    = new Uint16Array( 6 );

M
Mr.doob 已提交
203
	var i = 0;
M
Mr.doob 已提交
204 205 206 207 208 209 210 211 212 213 214 215

	_sprite.vertices[ i++ ] = -1; _sprite.vertices[ i++ ] = -1;	// vertex 0
	_sprite.vertices[ i++ ] = 0;  _sprite.vertices[ i++ ] = 1;	// uv 0

	_sprite.vertices[ i++ ] = 1;  _sprite.vertices[ i++ ] = -1;	// vertex 1
	_sprite.vertices[ i++ ] = 1;  _sprite.vertices[ i++ ] = 1;	// uv 1

	_sprite.vertices[ i++ ] = 1;  _sprite.vertices[ i++ ] = 1;	// vertex 2
	_sprite.vertices[ i++ ] = 1;  _sprite.vertices[ i++ ] = 0;	// uv 2

	_sprite.vertices[ i++ ] = -1; _sprite.vertices[ i++ ] = 1;	// vertex 3
	_sprite.vertices[ i++ ] = 0;  _sprite.vertices[ i++ ] = 0;	// uv 3
M
Mikael Emtinger 已提交
216 217

	i = 0;
M
Mr.doob 已提交
218

M
Mikael Emtinger 已提交
219 220 221 222 223 224 225
	_sprite.faces[ i++ ] = 0; _sprite.faces[ i++ ] = 1; _sprite.faces[ i++ ] = 2;
	_sprite.faces[ i++ ] = 0; _sprite.faces[ i++ ] = 2; _sprite.faces[ i++ ] = 3;

	_sprite.vertexBuffer  = _gl.createBuffer();
	_sprite.elementBuffer = _gl.createBuffer();

	_gl.bindBuffer( _gl.ARRAY_BUFFER, _sprite.vertexBuffer );
M
Mr.doob 已提交
226
	_gl.bufferData( _gl.ARRAY_BUFFER, _sprite.vertices, _gl.STATIC_DRAW );
M
Mikael Emtinger 已提交
227 228 229 230 231 232

	_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _sprite.elementBuffer );
	_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, _sprite.faces, _gl.STATIC_DRAW );


	_sprite.program = _gl.createProgram();
M
Mr.doob 已提交
233 234
	_gl.attachShader( _sprite.program, getShader( "fragment", THREE.ShaderLib.sprite.fragmentShader ) );
	_gl.attachShader( _sprite.program, getShader( "vertex",   THREE.ShaderLib.sprite.vertexShader   ) );
M
Mikael Emtinger 已提交
235 236 237 238
	_gl.linkProgram( _sprite.program );

	_sprite.attributes = {};
	_sprite.uniforms = {};
M
Mr.doob 已提交
239

240 241
	_sprite.attributes.position           = _gl.getAttribLocation ( _sprite.program, "position" );
	_sprite.attributes.uv                 = _gl.getAttribLocation ( _sprite.program, "uv" );
M
Mr.doob 已提交
242

243 244
	_sprite.uniforms.uvOffset             = _gl.getUniformLocation( _sprite.program, "uvOffset" );
	_sprite.uniforms.uvScale              = _gl.getUniformLocation( _sprite.program, "uvScale" );
M
Mr.doob 已提交
245

246 247 248
	_sprite.uniforms.rotation             = _gl.getUniformLocation( _sprite.program, "rotation" );
	_sprite.uniforms.scale                = _gl.getUniformLocation( _sprite.program, "scale" );
	_sprite.uniforms.alignment            = _gl.getUniformLocation( _sprite.program, "alignment" );
M
Mr.doob 已提交
249 250

	_sprite.uniforms.color                = _gl.getUniformLocation( _sprite.program, "color" );
251 252
	_sprite.uniforms.map                  = _gl.getUniformLocation( _sprite.program, "map" );
	_sprite.uniforms.opacity              = _gl.getUniformLocation( _sprite.program, "opacity" );
M
Mr.doob 已提交
253

254 255 256 257 258
	_sprite.uniforms.useScreenCoordinates = _gl.getUniformLocation( _sprite.program, "useScreenCoordinates" );
	_sprite.uniforms.affectedByDistance   = _gl.getUniformLocation( _sprite.program, "affectedByDistance" );
	_sprite.uniforms.screenPosition    	  = _gl.getUniformLocation( _sprite.program, "screenPosition" );
	_sprite.uniforms.modelViewMatrix      = _gl.getUniformLocation( _sprite.program, "modelViewMatrix" );
	_sprite.uniforms.projectionMatrix     = _gl.getUniformLocation( _sprite.program, "projectionMatrix" );
M
Mikael Emtinger 已提交
259

M
Mr.doob 已提交
260 261
	//_gl.enableVertexAttribArray( _sprite.attributes.position );
	//_gl.enableVertexAttribArray( _sprite.attributes.uv );
M
Mikael Emtinger 已提交
262

M
Mr.doob 已提交
263
	var _spriteAttributesEnabled = false;
M
Mikael Emtinger 已提交
264

N
Nicolas Garcia Belmonte 已提交
265 266 267 268
	this.setSize = function ( width, height ) {

		_canvas.width = width;
		_canvas.height = height;
269

270 271 272
		this.setViewport( 0, 0, _canvas.width, _canvas.height );

	};
N
Nicolas Garcia Belmonte 已提交
273

274
	this.setViewport = function ( x, y, width, height ) {
275

276 277
		_viewportX = x;
		_viewportY = y;
278

279 280
		_viewportWidth = width;
		_viewportHeight = height;
281

282
		_gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight );
283

N
Nicolas Garcia Belmonte 已提交
284
	};
285

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

288
		_gl.scissor( x, y, width, height );
289

290
	};
291

292
	this.enableScissorTest = function ( enable ) {
293

M
Mr.doob 已提交
294
		enable ? _gl.enable( _gl.SCISSOR_TEST ) : _gl.disable( _gl.SCISSOR_TEST );
295 296

	};
297

298
	this.setClearColorHex = function ( hex, alpha ) {
299

300 301 302 303
		_clearColor.setHex( hex );
		_clearAlpha = alpha;

		_gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
304

305
	};
A
alteredq 已提交
306

307
	this.setClearColor = function ( color, alpha ) {
A
alteredq 已提交
308

309 310 311 312
		_clearColor.copy( color );
		_clearAlpha = alpha;

		_gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
A
alteredq 已提交
313 314

	};
315

M
Mr.doob 已提交
316 317 318 319 320 321 322
	this.getClearColor = function () {

		return _clearColor;

	};

	this.getClearAlpha = function () {
N
Nicolas Garcia Belmonte 已提交
323

M
Mr.doob 已提交
324 325 326 327 328 329 330 331
		return _clearAlpha;

	};

	this.clear = function ( color, depth, stencil ) {

		var bits = 0;

332 333 334
		if ( color === undefined || color ) bits |= _gl.COLOR_BUFFER_BIT;
		if ( depth === undefined || depth ) bits |= _gl.DEPTH_BUFFER_BIT;
		if ( stencil === undefined || stencil ) bits |= _gl.STENCIL_BUFFER_BIT;
M
Mr.doob 已提交
335 336

		_gl.clear( bits );
N
Nicolas Garcia Belmonte 已提交
337 338 339

	};

M
Mr.doob 已提交
340 341 342 343 344 345
	this.getContext = function () {

		return _gl;

	};

346 347 348 349 350 351 352 353 354 355 356 357 358 359
	this.deallocateObject = function ( object ) {

		if ( ! object.__webglInit ) return;

		object.__webglInit = false;

		delete object._modelViewMatrix;

		delete object._normalMatrixArray;
		delete object._modelViewMatrixArray;
		delete object._objectMatrixArray;

		if ( object instanceof THREE.Mesh ) {

360
			for ( var g in object.geometry.geometryGroups ) {
361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388

				deleteMeshBuffers( object.geometry.geometryGroups[ g ] );

			}

		} else if ( object instanceof THREE.Ribbon ) {

			deleteRibbonBuffers( object.geometry );

		} else if ( object instanceof THREE.Line ) {

			deleteLineBuffers( object.geometry );

		} else if ( object instanceof THREE.ParticleSystem ) {

			deleteParticleBuffers( object.geometry );

		}

	};

	this.deallocateTexture = function ( texture ) {

		if ( ! texture.__webglInit ) return;

		texture.__webglInit = false;
		_gl.deleteTexture( texture.__webglTexture );

M
Mr.doob 已提交
389 390
		_this.info.memory.textures --;

391 392 393 394
	};

	//

M
Mr.doob 已提交
395
	function setupLights( program, lights ) {
396

397 398
		var l, ll, light, n,
		r = 0, g = 0, b = 0,
399
		color, position, intensity, distance,
M
Mr.doob 已提交
400

401
		zlights = _lights,
M
Mr.doob 已提交
402

403
		dcolors = zlights.directional.colors,
404
		dpositions = zlights.directional.positions,
405

406
		pcolors = zlights.point.colors,
407
		ppositions = zlights.point.positions,
408
		pdistances = zlights.point.distances,
409

410 411
		dlength = 0,
		plength = 0,
412

413 414
		doffset = 0,
		poffset = 0;
M
Mr.doob 已提交
415

M
Mr.doob 已提交
416
		for ( l = 0, ll = lights.length; l < ll; l ++ ) {
417

418
			light = lights[ l ];
419
			color = light.color;
420

421 422
			position = light.position;
			intensity = light.intensity;
423
			distance = light.distance;
424 425 426

			if ( light instanceof THREE.AmbientLight ) {

427 428 429 430 431 432 433 434 435 436 437 438 439
				if ( _this.gammaInput ) {

					r += color.r * color.r;
					g += color.g * color.g;
					b += color.b * color.b;

				} else {

					r += color.r;
					g += color.g;
					b += color.b;

				}
M
Mr.doob 已提交
440

441
			} else if ( light instanceof THREE.DirectionalLight ) {
442

443
				doffset = dlength * 3;
444

445 446 447 448 449 450 451 452 453 454 455 456 457
				if ( _this.gammaInput ) {

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

				} else {

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

				}
458

459
				dpositions[ doffset ]     = position.x;
460 461
				dpositions[ doffset + 1 ] = position.y;
				dpositions[ doffset + 2 ] = position.z;
462

463
				dlength += 1;
M
Mr.doob 已提交
464

465 466 467 468
			} else if ( light instanceof THREE.SpotLight ) { // hack, not a proper spotlight

				doffset = dlength * 3;

469 470 471 472 473 474 475 476 477 478 479 480 481
				if ( _this.gammaInput ) {

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

				} else {

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

				}
482 483 484 485 486 487 488 489 490

				n = 1 / position.length();

				dpositions[ doffset ]     = position.x * n;
				dpositions[ doffset + 1 ] = position.y * n;
				dpositions[ doffset + 2 ] = position.z * n;

				dlength += 1;

491 492
			} else if( light instanceof THREE.PointLight ) {

493
				poffset = plength * 3;
494

495 496 497 498 499 500 501 502 503 504 505 506 507
				if ( _this.gammaInput ) {

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

				} else {

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

				}
508

509
				ppositions[ poffset ]     = position.x;
510 511
				ppositions[ poffset + 1 ] = position.y;
				ppositions[ poffset + 2 ] = position.z;
M
Mr.doob 已提交
512

513 514
				pdistances[ plength ] = distance;

515
				plength += 1;
M
Mr.doob 已提交
516

517 518 519
			}

		}
520

521 522
		// null eventual remains from removed lights
		// (this is to avoid if in shader)
523

M
Mr.doob 已提交
524 525
		for ( l = dlength * 3, ll = dcolors.length; l < ll; l ++ ) dcolors[ l ] = 0.0;
		for ( l = plength * 3, ll = pcolors.length; l < ll; l ++ ) pcolors[ l ] = 0.0;
M
Mr.doob 已提交
526

527 528
		zlights.point.length = plength;
		zlights.directional.length = dlength;
M
Mr.doob 已提交
529

530 531 532
		zlights.ambient[ 0 ] = r;
		zlights.ambient[ 1 ] = g;
		zlights.ambient[ 2 ] = b;
M
Mr.doob 已提交
533

534
	};
M
Mr.doob 已提交
535

536 537 538
	// Buffer allocation

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

540 541
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
M
Mr.doob 已提交
542

M
Mr.doob 已提交
543 544
		_this.info.geometries ++;

545
	};
M
Mr.doob 已提交
546

547
	function createLineBuffers( geometry ) {
M
Mr.doob 已提交
548

549 550
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
M
Mr.doob 已提交
551

M
Mr.doob 已提交
552 553
		_this.info.memory.geometries ++;

554
	};
555

556
	function createRibbonBuffers( geometry ) {
A
alteredq 已提交
557

558 559
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
A
alteredq 已提交
560

M
Mr.doob 已提交
561 562
		_this.info.memory.geometries ++;

A
alteredq 已提交
563 564
	};

565
	function createMeshBuffers( geometryGroup ) {
M
Mr.doob 已提交
566

567 568 569 570 571 572
		geometryGroup.__webglVertexBuffer = _gl.createBuffer();
		geometryGroup.__webglNormalBuffer = _gl.createBuffer();
		geometryGroup.__webglTangentBuffer = _gl.createBuffer();
		geometryGroup.__webglColorBuffer = _gl.createBuffer();
		geometryGroup.__webglUVBuffer = _gl.createBuffer();
		geometryGroup.__webglUV2Buffer = _gl.createBuffer();
573

574 575 576 577 578 579 580 581 582
		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 ) {
583

584
			var m, ml;
585

M
Mr.doob 已提交
586
			geometryGroup.__webglMorphTargetsBuffers = [];
587

588
			for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
589 590 591

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

592 593 594
			}

		}
M
Mr.doob 已提交
595

M
Mr.doob 已提交
596 597
		_this.info.memory.geometries ++;

598
	};
599

600 601 602 603 604 605 606
	// Buffer deallocation

	function deleteParticleBuffers( geometry ) {

		_gl.deleteBuffer( geometry.__webglVertexBuffer );
		_gl.deleteBuffer( geometry.__webglColorBuffer );

M
Mr.doob 已提交
607 608
		_this.info.memory.geometries --;

609 610 611 612 613 614 615
	};

	function deleteLineBuffers( geometry ) {

		_gl.deleteBuffer( geometry.__webglVertexBuffer );
		_gl.deleteBuffer( geometry.__webglColorBuffer );

M
Mr.doob 已提交
616 617
		_this.info.memory.geometries --;

618 619 620 621 622 623 624
	};

	function deleteRibbonBuffers( geometry ) {

		_gl.deleteBuffer( geometry.__webglVertexBuffer );
		_gl.deleteBuffer( geometry.__webglColorBuffer );

M
Mr.doob 已提交
625 626
		_this.info.memory.geometries --;

627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647
	};

	function deleteMeshBuffers( geometryGroup ) {

		_gl.deleteBuffer( geometryGroup.__webglVertexBuffer );
		_gl.deleteBuffer( geometryGroup.__webglNormalBuffer );
		_gl.deleteBuffer( geometryGroup.__webglTangentBuffer );
		_gl.deleteBuffer( geometryGroup.__webglColorBuffer );
		_gl.deleteBuffer( geometryGroup.__webglUVBuffer );
		_gl.deleteBuffer( geometryGroup.__webglUV2Buffer );

		_gl.deleteBuffer( geometryGroup.__webglSkinVertexABuffer );
		_gl.deleteBuffer( geometryGroup.__webglSkinVertexBBuffer );
		_gl.deleteBuffer( geometryGroup.__webglSkinIndicesBuffer );
		_gl.deleteBuffer( geometryGroup.__webglSkinWeightsBuffer );

		_gl.deleteBuffer( geometryGroup.__webglFaceBuffer );
		_gl.deleteBuffer( geometryGroup.__webglLineBuffer );

		if ( geometryGroup.numMorphTargets ) {

648
			for ( var m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
649 650 651 652 653 654 655

				_gl.deleteBuffer( geometryGroup.__webglMorphTargetsBuffers[ m ] );

			}

		}

M
Mr.doob 已提交
656 657
		_this.info.memory.geometries --;

658 659 660 661
	};

	//

A
alteredq 已提交
662
	function initCustomAttributes ( geometry, object ) {
M
Mr.doob 已提交
663

664 665
		var nvertices = geometry.vertices.length;

666
		var material = object.material;
667

668
		if ( material.attributes ) {
669

670
			if ( geometry.__webglCustomAttributesList === undefined ) {
671

672
				geometry.__webglCustomAttributesList = [];
673

674
			}
675

676
			for ( var a in material.attributes ) {
677

678
				var attribute = material.attributes[ a ];
679

680
				if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
681

682
					attribute.__webglInitialized = true;
683

A
alteredq 已提交
684
					var size = 1;		// "f" and "i"
685

686 687 688 689
					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;
690

691
					attribute.size = size;
A
alteredq 已提交
692

693
					attribute.array = new Float32Array( nvertices * size );
A
alteredq 已提交
694

695 696
					attribute.buffer = _gl.createBuffer();
					attribute.buffer.belongsToAttribute = a;
697

698
					attribute.needsUpdate = true;
699

700
				}
701

702
				geometry.__webglCustomAttributesList.push( attribute );
703

704
			}
705

706
		}
707

708
	};
709

A
alteredq 已提交
710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752
	//

	function initLineBuffers ( geometry, object ) {

		var nvertices = geometry.vertices.length;

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

		geometry.__webglLineCount = nvertices;

		initCustomAttributes ( geometry, object );

	};

	function initParticleBuffers ( geometry, object ) {

		var nvertices = geometry.vertices.length;

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

		geometry.__sortArray = [];

		geometry.__webglParticleCount = nvertices;

		initCustomAttributes ( geometry, object );

	};

	function initRibbonBuffers ( geometry ) {

		var nvertices = geometry.vertices.length;

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

		geometry.__webglVertexCount = nvertices;

	};

	//

753 754 755 756 757 758 759 760 761
	function getBufferMaterial( object, geometryGroup ) {

		if ( object.material && ! ( object.material instanceof THREE.MeshFaceMaterial ) ) {

			return object.material;

		} else if ( geometryGroup.materialIndex >= 0 ) {

			return object.geometry.materials[ geometryGroup.materialIndex ];
762 763 764

		}

765 766
	};

M
Mr.doob 已提交
767
	function initMeshBuffers ( geometryGroup, object ) {
M
Mr.doob 已提交
768

769 770 771
		var geometry = object.geometry,
			faces3 = geometryGroup.faces3,
			faces4 = geometryGroup.faces4,
M
Mr.doob 已提交
772

773 774 775
			nvertices = faces3.length * 3 + faces4.length * 4,
			ntris     = faces3.length * 1 + faces4.length * 2,
			nlines    = faces3.length * 3 + faces4.length * 4,
776

777
			material = getBufferMaterial( object, geometryGroup ),
778

779 780 781
			uvType = bufferGuessUVType( material ),
			normalType = bufferGuessNormalType( material ),
			vertexColorType = bufferGuessVertexColorType( material );
A
alteredq 已提交
782

783
		//console.log( "uvType", uvType, "normalType", normalType, "vertexColorType", vertexColorType, object, geometryGroup, material );
M
Mr.doob 已提交
784

785
		geometryGroup.__vertexArray = new Float32Array( nvertices * 3 );
786

787
		if ( normalType ) {
M
Mr.doob 已提交
788

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

791
		}
792

793
		if ( geometry.hasTangents ) {
794

795
			geometryGroup.__tangentArray = new Float32Array( nvertices * 4 );
796

797
		}
798

799
		if ( vertexColorType ) {
800

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

803
		}
M
Mr.doob 已提交
804

805
		if ( uvType ) {
806

807
			if ( geometry.faceUvs.length > 0 || geometry.faceVertexUvs.length > 0 ) {
808

809 810 811 812 813
				geometryGroup.__uvArray = new Float32Array( nvertices * 2 );

			}

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

815 816 817 818 819 820 821 822 823 824 825 826 827 828 829
				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 );

		}

830
		geometryGroup.__faceArray = new Uint16Array( ntris * 3 );
831
		geometryGroup.__lineArray = new Uint16Array( nlines * 2 );
M
Mr.doob 已提交
832

833 834
		if ( geometryGroup.numMorphTargets ) {

M
Mr.doob 已提交
835
			geometryGroup.__morphTargetsArrays = [];
836

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

839 840
				geometryGroup.__morphTargetsArrays.push( new Float32Array( nvertices * 3 ) );

841 842 843
			}

		}
844

845
		geometryGroup.__needsSmoothNormals = ( normalType === THREE.SmoothShading );
846

847 848 849 850
		geometryGroup.__uvType = uvType;
		geometryGroup.__vertexColorType = vertexColorType;
		geometryGroup.__normalType = normalType;

851
		geometryGroup.__webglFaceCount = ntris * 3;
852
		geometryGroup.__webglLineCount = nlines * 2;
853

M
Mr.doob 已提交
854

855
		// custom attributes
M
Mr.doob 已提交
856

857
		if ( material.attributes ) {
858

859
			if ( geometryGroup.__webglCustomAttributesList === undefined ) {
860

861
				geometryGroup.__webglCustomAttributesList = [];
862

863
			}
864

865
			for ( var a in material.attributes ) {
M
Mr.doob 已提交
866

867 868
				// Do a shallow copy of the attribute object so different geometryGroup chunks use different
				// attribute buffers which are correctly indexed in the setMeshBuffers function
869

870
				var originalAttribute = material.attributes[ a ];
871

872
				var attribute = {};
873

874
				for ( var property in originalAttribute ) {
M
Mr.doob 已提交
875

876
					attribute[ property ] = originalAttribute[ property ];
877

878
				}
879

880
				if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
881

882
					attribute.__webglInitialized = true;
883

884
					var size = 1;		// "f" and "i"
M
Mr.doob 已提交
885

886 887 888 889
					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;
890

891
					attribute.size = size;
A
alteredq 已提交
892

893
					attribute.array = new Float32Array( nvertices * size );
A
alteredq 已提交
894

895 896
					attribute.buffer = _gl.createBuffer();
					attribute.buffer.belongsToAttribute = a;
897

898 899
					originalAttribute.needsUpdate = true;
					attribute.__original = originalAttribute;
900 901 902

				}

903 904
				geometryGroup.__webglCustomAttributesList.push( attribute );

905
			}
M
Mr.doob 已提交
906

907
		}
908

909 910
		geometryGroup.__inittedArrays = true;

911
	};
M
Mr.doob 已提交
912

913
	function setMeshBuffers( geometryGroup, object, hint, dispose ) {
914

915 916 917 918 919 920 921
		if ( ! geometryGroup.__inittedArrays ) {

			// console.log( object );
			return;

		}

M
Mr.doob 已提交
922
		var f, fl, fi, face,
923 924 925 926 927 928 929 930 931 932
		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,
933
		m, ml, i, il,
934 935
		vn, uvi, uv2i,
		vk, vkl, vka,
936
		a,
M
Mr.doob 已提交
937

938
		vertexIndex = 0,
939

940 941
		offset = 0,
		offset_uv = 0,
942
		offset_uv2 = 0,
943 944 945 946
		offset_face = 0,
		offset_normal = 0,
		offset_tangent = 0,
		offset_line = 0,
947
		offset_color = 0,
A
alteredq 已提交
948
		offset_skin = 0,
949
		offset_morphTarget = 0,
950
		offset_custom = 0,
951
		offset_customSrc = 0,
M
Mr.doob 已提交
952

953 954
		value,

955 956 957 958 959 960
		vertexArray = geometryGroup.__vertexArray,
		uvArray = geometryGroup.__uvArray,
		uv2Array = geometryGroup.__uv2Array,
		normalArray = geometryGroup.__normalArray,
		tangentArray = geometryGroup.__tangentArray,
		colorArray = geometryGroup.__colorArray,
961

962 963 964 965
		skinVertexAArray = geometryGroup.__skinVertexAArray,
		skinVertexBArray = geometryGroup.__skinVertexBArray,
		skinIndexArray = geometryGroup.__skinIndexArray,
		skinWeightArray = geometryGroup.__skinWeightArray,
M
Mr.doob 已提交
966

967 968
		morphTargetsArrays = geometryGroup.__morphTargetsArrays,

969
		customAttributes = geometryGroup.__webglCustomAttributesList,
970
		customAttribute,
971

972 973
		faceArray = geometryGroup.__faceArray,
		lineArray = geometryGroup.__lineArray,
M
Mr.doob 已提交
974

975
		needsSmoothNormals = geometryGroup.__needsSmoothNormals,
976

977
		vertexColorType = geometryGroup.__vertexColorType,
A
alteredq 已提交
978 979
		uvType = geometryGroup.__uvType,
		normalType = geometryGroup.__normalType,
980

981
		geometry = object.geometry, // this is shared for all chunks
982

983
		dirtyVertices = geometry.__dirtyVertices,
984 985 986
		dirtyElements = geometry.__dirtyElements,
		dirtyUvs = geometry.__dirtyUvs,
		dirtyNormals = geometry.__dirtyNormals,
987
		dirtyTangents = geometry.__dirtyTangents,
988
		dirtyColors = geometry.__dirtyColors,
989
		dirtyMorphTargets = geometry.__dirtyMorphTargets,
M
Mr.doob 已提交
990

991
		vertices = geometry.vertices,
992 993
		chunk_faces3 = geometryGroup.faces3,
		chunk_faces4 = geometryGroup.faces4,
994
		obj_faces = geometry.faces,
995

996 997
		obj_uvs  = geometry.faceVertexUvs[ 0 ],
		obj_uvs2 = geometry.faceVertexUvs[ 1 ],
998

A
alteredq 已提交
999
		obj_colors = geometry.colors,
1000

A
alteredq 已提交
1001 1002 1003
		obj_skinVerticesA = geometry.skinVerticesA,
		obj_skinVerticesB = geometry.skinVerticesB,
		obj_skinIndices = geometry.skinIndices,
1004
		obj_skinWeights = geometry.skinWeights,
1005

1006
		morphTargets = geometry.morphTargets;
1007

A
alteredq 已提交
1008
		if ( dirtyVertices ) {
1009

A
alteredq 已提交
1010
			for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
1011

A
alteredq 已提交
1012
				face = obj_faces[ chunk_faces3[ f ] ];
M
Mr.doob 已提交
1013

1014 1015 1016
				v1 = vertices[ face.a ].position;
				v2 = vertices[ face.b ].position;
				v3 = vertices[ face.c ].position;
M
Mr.doob 已提交
1017

1018 1019 1020
				vertexArray[ offset ]     = v1.x;
				vertexArray[ offset + 1 ] = v1.y;
				vertexArray[ offset + 2 ] = v1.z;
M
Mr.doob 已提交
1021

1022 1023 1024
				vertexArray[ offset + 3 ] = v2.x;
				vertexArray[ offset + 4 ] = v2.y;
				vertexArray[ offset + 5 ] = v2.z;
1025

1026 1027 1028
				vertexArray[ offset + 6 ] = v3.x;
				vertexArray[ offset + 7 ] = v3.y;
				vertexArray[ offset + 8 ] = v3.z;
M
Mr.doob 已提交
1029

1030
				offset += 9;
M
Mr.doob 已提交
1031

1032
			}
1033

A
alteredq 已提交
1034
			for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
M
Mr.doob 已提交
1035

A
alteredq 已提交
1036
				face = obj_faces[ chunk_faces4[ f ] ];
M
Mr.doob 已提交
1037

A
alteredq 已提交
1038 1039 1040 1041
				v1 = vertices[ face.a ].position;
				v2 = vertices[ face.b ].position;
				v3 = vertices[ face.c ].position;
				v4 = vertices[ face.d ].position;
1042

A
alteredq 已提交
1043 1044 1045
				vertexArray[ offset ]     = v1.x;
				vertexArray[ offset + 1 ] = v1.y;
				vertexArray[ offset + 2 ] = v1.z;
1046

A
alteredq 已提交
1047 1048 1049
				vertexArray[ offset + 3 ] = v2.x;
				vertexArray[ offset + 4 ] = v2.y;
				vertexArray[ offset + 5 ] = v2.z;
1050

A
alteredq 已提交
1051 1052 1053
				vertexArray[ offset + 6 ] = v3.x;
				vertexArray[ offset + 7 ] = v3.y;
				vertexArray[ offset + 8 ] = v3.z;
1054

A
alteredq 已提交
1055 1056 1057
				vertexArray[ offset + 9 ]  = v4.x;
				vertexArray[ offset + 10 ] = v4.y;
				vertexArray[ offset + 11 ] = v4.z;
1058

A
alteredq 已提交
1059
				offset += 12;
1060

A
alteredq 已提交
1061
			}
1062

A
alteredq 已提交
1063 1064
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
M
Mr.doob 已提交
1065

A
alteredq 已提交
1066
		}
M
Mr.doob 已提交
1067

A
alteredq 已提交
1068
		if ( dirtyMorphTargets ) {
M
Mr.doob 已提交
1069

A
alteredq 已提交
1070
			for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
1071

A
alteredq 已提交
1072
				face = obj_faces[ chunk_faces3[ f ]	];
1073

A
alteredq 已提交
1074
				for ( vk = 0, vkl = morphTargets.length; vk < vkl; vk ++ ) {
M
Mr.doob 已提交
1075

A
alteredq 已提交
1076 1077 1078
					v1 = morphTargets[ vk ].vertices[ face.a ].position;
					v2 = morphTargets[ vk ].vertices[ face.b ].position;
					v3 = morphTargets[ vk ].vertices[ face.c ].position;
M
Mr.doob 已提交
1079

A
alteredq 已提交
1080
					vka = morphTargetsArrays[ vk ];
M
Mr.doob 已提交
1081

A
alteredq 已提交
1082 1083 1084
					vka[ offset_morphTarget ] 	  = v1.x;
					vka[ offset_morphTarget + 1 ] = v1.y;
					vka[ offset_morphTarget + 2 ] = v1.z;
M
Mr.doob 已提交
1085

A
alteredq 已提交
1086 1087 1088
					vka[ offset_morphTarget + 3 ] = v2.x;
					vka[ offset_morphTarget + 4 ] = v2.y;
					vka[ offset_morphTarget + 5 ] = v2.z;
M
Mr.doob 已提交
1089

A
alteredq 已提交
1090 1091 1092
					vka[ offset_morphTarget + 6 ] = v3.x;
					vka[ offset_morphTarget + 7 ] = v3.y;
					vka[ offset_morphTarget + 8 ] = v3.z;
M
Mr.doob 已提交
1093

1094 1095
				}

A
alteredq 已提交
1096 1097
				offset_morphTarget += 9;

1098
			}
1099

A
alteredq 已提交
1100
			for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
1101

A
alteredq 已提交
1102
				face = obj_faces[ chunk_faces4[ f ] ];
1103

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

1106 1107 1108
					v1 = morphTargets[ vk ].vertices[ face.a ].position;
					v2 = morphTargets[ vk ].vertices[ face.b ].position;
					v3 = morphTargets[ vk ].vertices[ face.c ].position;
A
alteredq 已提交
1109
					v4 = morphTargets[ vk ].vertices[ face.d ].position;
1110

1111
					vka = morphTargetsArrays[ vk ];
1112

1113 1114 1115
					vka[ offset_morphTarget ] 	  = v1.x;
					vka[ offset_morphTarget + 1 ] = v1.y;
					vka[ offset_morphTarget + 2 ] = v1.z;
1116

1117 1118 1119
					vka[ offset_morphTarget + 3 ] = v2.x;
					vka[ offset_morphTarget + 4 ] = v2.y;
					vka[ offset_morphTarget + 5 ] = v2.z;
1120

1121 1122 1123
					vka[ offset_morphTarget + 6 ] = v3.x;
					vka[ offset_morphTarget + 7 ] = v3.y;
					vka[ offset_morphTarget + 8 ] = v3.z;
1124

A
alteredq 已提交
1125 1126 1127 1128
					vka[ offset_morphTarget + 9 ]  = v4.x;
					vka[ offset_morphTarget + 10 ] = v4.y;
					vka[ offset_morphTarget + 11 ] = v4.z;

1129 1130
				}

A
alteredq 已提交
1131 1132 1133 1134 1135 1136 1137 1138
				offset_morphTarget += 12;

			}

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

				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ vk ] );
				_gl.bufferData( _gl.ARRAY_BUFFER, morphTargetsArrays[ vk ], hint );
A
alteredq 已提交
1139

1140
			}
1141

A
alteredq 已提交
1142 1143 1144 1145 1146 1147 1148
		}

		if ( obj_skinWeights.length ) {

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

				face = obj_faces[ chunk_faces3[ f ]	];
1149

1150
				// weights
A
alteredq 已提交
1151

1152 1153 1154
				sw1 = obj_skinWeights[ face.a ];
				sw2 = obj_skinWeights[ face.b ];
				sw3 = obj_skinWeights[ face.c ];
A
alteredq 已提交
1155

1156 1157 1158 1159
				skinWeightArray[ offset_skin ]     = sw1.x;
				skinWeightArray[ offset_skin + 1 ] = sw1.y;
				skinWeightArray[ offset_skin + 2 ] = sw1.z;
				skinWeightArray[ offset_skin + 3 ] = sw1.w;
A
alteredq 已提交
1160

1161 1162 1163 1164
				skinWeightArray[ offset_skin + 4 ] = sw2.x;
				skinWeightArray[ offset_skin + 5 ] = sw2.y;
				skinWeightArray[ offset_skin + 6 ] = sw2.z;
				skinWeightArray[ offset_skin + 7 ] = sw2.w;
1165

1166 1167 1168 1169
				skinWeightArray[ offset_skin + 8 ]  = sw3.x;
				skinWeightArray[ offset_skin + 9 ]  = sw3.y;
				skinWeightArray[ offset_skin + 10 ] = sw3.z;
				skinWeightArray[ offset_skin + 11 ] = sw3.w;
A
alteredq 已提交
1170

1171
				// indices
A
alteredq 已提交
1172

1173 1174 1175
				si1 = obj_skinIndices[ face.a ];
				si2 = obj_skinIndices[ face.b ];
				si3 = obj_skinIndices[ face.c ];
A
alteredq 已提交
1176

1177 1178 1179 1180
				skinIndexArray[ offset_skin ]     = si1.x;
				skinIndexArray[ offset_skin + 1 ] = si1.y;
				skinIndexArray[ offset_skin + 2 ] = si1.z;
				skinIndexArray[ offset_skin + 3 ] = si1.w;
A
alteredq 已提交
1181

1182 1183 1184 1185
				skinIndexArray[ offset_skin + 4 ] = si2.x;
				skinIndexArray[ offset_skin + 5 ] = si2.y;
				skinIndexArray[ offset_skin + 6 ] = si2.z;
				skinIndexArray[ offset_skin + 7 ] = si2.w;
1186

1187 1188 1189 1190
				skinIndexArray[ offset_skin + 8 ]  = si3.x;
				skinIndexArray[ offset_skin + 9 ]  = si3.y;
				skinIndexArray[ offset_skin + 10 ] = si3.z;
				skinIndexArray[ offset_skin + 11 ] = si3.w;
A
alteredq 已提交
1191

1192
				// vertices A
A
alteredq 已提交
1193

1194 1195 1196
				sa1 = obj_skinVerticesA[ face.a ];
				sa2 = obj_skinVerticesA[ face.b ];
				sa3 = obj_skinVerticesA[ face.c ];
A
alteredq 已提交
1197

1198 1199 1200 1201
				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
A
alteredq 已提交
1202

1203 1204 1205 1206
				skinVertexAArray[ offset_skin + 4 ] = sa2.x;
				skinVertexAArray[ offset_skin + 5 ] = sa2.y;
				skinVertexAArray[ offset_skin + 6 ] = sa2.z;
				skinVertexAArray[ offset_skin + 7 ] = 1;
1207

1208 1209 1210 1211
				skinVertexAArray[ offset_skin + 8 ]  = sa3.x;
				skinVertexAArray[ offset_skin + 9 ]  = sa3.y;
				skinVertexAArray[ offset_skin + 10 ] = sa3.z;
				skinVertexAArray[ offset_skin + 11 ] = 1;
A
alteredq 已提交
1212

1213
				// vertices B
A
alteredq 已提交
1214

1215 1216 1217
				sb1 = obj_skinVerticesB[ face.a ];
				sb2 = obj_skinVerticesB[ face.b ];
				sb3 = obj_skinVerticesB[ face.c ];
A
alteredq 已提交
1218

1219 1220 1221 1222
				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
A
alteredq 已提交
1223

1224 1225 1226 1227
				skinVertexBArray[ offset_skin + 4 ] = sb2.x;
				skinVertexBArray[ offset_skin + 5 ] = sb2.y;
				skinVertexBArray[ offset_skin + 6 ] = sb2.z;
				skinVertexBArray[ offset_skin + 7 ] = 1;
1228

1229 1230 1231 1232
				skinVertexBArray[ offset_skin + 8 ]  = sb3.x;
				skinVertexBArray[ offset_skin + 9 ]  = sb3.y;
				skinVertexBArray[ offset_skin + 10 ] = sb3.z;
				skinVertexBArray[ offset_skin + 11 ] = 1;
1233

1234
				offset_skin += 12;
1235

1236
			}
1237

A
alteredq 已提交
1238
			for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
1239

A
alteredq 已提交
1240
				face = obj_faces[ chunk_faces4[ f ] ];
1241

A
alteredq 已提交
1242
				// weights
1243

A
alteredq 已提交
1244 1245 1246 1247
				sw1 = obj_skinWeights[ face.a ];
				sw2 = obj_skinWeights[ face.b ];
				sw3 = obj_skinWeights[ face.c ];
				sw4 = obj_skinWeights[ face.d ];
1248

A
alteredq 已提交
1249 1250 1251 1252
				skinWeightArray[ offset_skin ]     = sw1.x;
				skinWeightArray[ offset_skin + 1 ] = sw1.y;
				skinWeightArray[ offset_skin + 2 ] = sw1.z;
				skinWeightArray[ offset_skin + 3 ] = sw1.w;
1253

A
alteredq 已提交
1254 1255 1256 1257
				skinWeightArray[ offset_skin + 4 ] = sw2.x;
				skinWeightArray[ offset_skin + 5 ] = sw2.y;
				skinWeightArray[ offset_skin + 6 ] = sw2.z;
				skinWeightArray[ offset_skin + 7 ] = sw2.w;
1258

A
alteredq 已提交
1259 1260 1261 1262
				skinWeightArray[ offset_skin + 8 ]  = sw3.x;
				skinWeightArray[ offset_skin + 9 ]  = sw3.y;
				skinWeightArray[ offset_skin + 10 ] = sw3.z;
				skinWeightArray[ offset_skin + 11 ] = sw3.w;
1263

A
alteredq 已提交
1264 1265 1266 1267
				skinWeightArray[ offset_skin + 12 ] = sw4.x;
				skinWeightArray[ offset_skin + 13 ] = sw4.y;
				skinWeightArray[ offset_skin + 14 ] = sw4.z;
				skinWeightArray[ offset_skin + 15 ] = sw4.w;
1268

A
alteredq 已提交
1269
				// indices
1270

A
alteredq 已提交
1271 1272 1273 1274
				si1 = obj_skinIndices[ face.a ];
				si2 = obj_skinIndices[ face.b ];
				si3 = obj_skinIndices[ face.c ];
				si4 = obj_skinIndices[ face.d ];
1275

A
alteredq 已提交
1276 1277 1278 1279
				skinIndexArray[ offset_skin ]     = si1.x;
				skinIndexArray[ offset_skin + 1 ] = si1.y;
				skinIndexArray[ offset_skin + 2 ] = si1.z;
				skinIndexArray[ offset_skin + 3 ] = si1.w;
1280

A
alteredq 已提交
1281 1282 1283 1284
				skinIndexArray[ offset_skin + 4 ] = si2.x;
				skinIndexArray[ offset_skin + 5 ] = si2.y;
				skinIndexArray[ offset_skin + 6 ] = si2.z;
				skinIndexArray[ offset_skin + 7 ] = si2.w;
M
Mr.doob 已提交
1285

A
alteredq 已提交
1286 1287 1288 1289
				skinIndexArray[ offset_skin + 8 ]  = si3.x;
				skinIndexArray[ offset_skin + 9 ]  = si3.y;
				skinIndexArray[ offset_skin + 10 ] = si3.z;
				skinIndexArray[ offset_skin + 11 ] = si3.w;
M
Mr.doob 已提交
1290

A
alteredq 已提交
1291 1292 1293 1294
				skinIndexArray[ offset_skin + 12 ] = si4.x;
				skinIndexArray[ offset_skin + 13 ] = si4.y;
				skinIndexArray[ offset_skin + 14 ] = si4.z;
				skinIndexArray[ offset_skin + 15 ] = si4.w;
M
Mr.doob 已提交
1295

A
alteredq 已提交
1296
				// vertices A
M
Mr.doob 已提交
1297

A
alteredq 已提交
1298 1299 1300 1301
				sa1 = obj_skinVerticesA[ face.a ];
				sa2 = obj_skinVerticesA[ face.b ];
				sa3 = obj_skinVerticesA[ face.c ];
				sa4 = obj_skinVerticesA[ face.d ];
1302

A
alteredq 已提交
1303 1304 1305 1306
				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
M
Mr.doob 已提交
1307

A
alteredq 已提交
1308 1309 1310 1311
				skinVertexAArray[ offset_skin + 4 ] = sa2.x;
				skinVertexAArray[ offset_skin + 5 ] = sa2.y;
				skinVertexAArray[ offset_skin + 6 ] = sa2.z;
				skinVertexAArray[ offset_skin + 7 ] = 1;
1312

A
alteredq 已提交
1313 1314 1315 1316
				skinVertexAArray[ offset_skin + 8 ]  = sa3.x;
				skinVertexAArray[ offset_skin + 9 ]  = sa3.y;
				skinVertexAArray[ offset_skin + 10 ] = sa3.z;
				skinVertexAArray[ offset_skin + 11 ] = 1;
1317

A
alteredq 已提交
1318 1319 1320 1321
				skinVertexAArray[ offset_skin + 12 ] = sa4.x;
				skinVertexAArray[ offset_skin + 13 ] = sa4.y;
				skinVertexAArray[ offset_skin + 14 ] = sa4.z;
				skinVertexAArray[ offset_skin + 15 ] = 1;
M
Mr.doob 已提交
1322

A
alteredq 已提交
1323
				// vertices B
M
Mr.doob 已提交
1324

A
alteredq 已提交
1325 1326 1327 1328
				sb1 = obj_skinVerticesB[ face.a ];
				sb2 = obj_skinVerticesB[ face.b ];
				sb3 = obj_skinVerticesB[ face.c ];
				sb4 = obj_skinVerticesB[ face.d ];
M
Mr.doob 已提交
1329

A
alteredq 已提交
1330 1331 1332 1333
				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
M
Mr.doob 已提交
1334

A
alteredq 已提交
1335 1336 1337 1338
				skinVertexBArray[ offset_skin + 4 ] = sb2.x;
				skinVertexBArray[ offset_skin + 5 ] = sb2.y;
				skinVertexBArray[ offset_skin + 6 ] = sb2.z;
				skinVertexBArray[ offset_skin + 7 ] = 1;
1339

A
alteredq 已提交
1340 1341 1342 1343
				skinVertexBArray[ offset_skin + 8 ]  = sb3.x;
				skinVertexBArray[ offset_skin + 9 ]  = sb3.y;
				skinVertexBArray[ offset_skin + 10 ] = sb3.z;
				skinVertexBArray[ offset_skin + 11 ] = 1;
1344

A
alteredq 已提交
1345 1346 1347 1348
				skinVertexBArray[ offset_skin + 12 ] = sb4.x;
				skinVertexBArray[ offset_skin + 13 ] = sb4.y;
				skinVertexBArray[ offset_skin + 14 ] = sb4.z;
				skinVertexBArray[ offset_skin + 15 ] = 1;
1349

A
alteredq 已提交
1350
				offset_skin += 16;
M
Mr.doob 已提交
1351

A
alteredq 已提交
1352
			}
M
Mr.doob 已提交
1353

A
alteredq 已提交
1354
			if ( offset_skin > 0 ) {
M
Mr.doob 已提交
1355

A
alteredq 已提交
1356 1357
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexAArray, hint );
M
Mr.doob 已提交
1358

A
alteredq 已提交
1359 1360 1361 1362 1363 1364 1365 1366
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexBArray, hint );

				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, skinIndexArray, hint );

				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, skinWeightArray, hint );
1367

1368
			}
1369

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

A
alteredq 已提交
1372
		if ( dirtyColors && vertexColorType ) {
M
Mr.doob 已提交
1373

A
alteredq 已提交
1374
			for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
M
Mr.doob 已提交
1375

A
alteredq 已提交
1376
				face = obj_faces[ chunk_faces3[ f ]	];
M
Mr.doob 已提交
1377

A
alteredq 已提交
1378 1379
				vertexColors = face.vertexColors;
				faceColor = face.color;
1380

A
alteredq 已提交
1381
				if ( vertexColors.length === 3 && vertexColorType === THREE.VertexColors ) {
1382

A
alteredq 已提交
1383 1384 1385
					c1 = vertexColors[ 0 ];
					c2 = vertexColors[ 1 ];
					c3 = vertexColors[ 2 ];
1386

A
alteredq 已提交
1387
				} else {
1388

A
alteredq 已提交
1389 1390 1391
					c1 = faceColor;
					c2 = faceColor;
					c3 = faceColor;
1392

A
alteredq 已提交
1393
				}
1394

A
alteredq 已提交
1395 1396 1397
				colorArray[ offset_color ]     = c1.r;
				colorArray[ offset_color + 1 ] = c1.g;
				colorArray[ offset_color + 2 ] = c1.b;
1398

A
alteredq 已提交
1399 1400 1401
				colorArray[ offset_color + 3 ] = c2.r;
				colorArray[ offset_color + 4 ] = c2.g;
				colorArray[ offset_color + 5 ] = c2.b;
1402

A
alteredq 已提交
1403 1404 1405
				colorArray[ offset_color + 6 ] = c3.r;
				colorArray[ offset_color + 7 ] = c3.g;
				colorArray[ offset_color + 8 ] = c3.b;
1406

A
alteredq 已提交
1407
				offset_color += 9;
M
Mr.doob 已提交
1408

A
alteredq 已提交
1409
			}
M
Mr.doob 已提交
1410

A
alteredq 已提交
1411
			for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
M
Mr.doob 已提交
1412

A
alteredq 已提交
1413
				face = obj_faces[ chunk_faces4[ f ] ];
M
Mr.doob 已提交
1414

A
alteredq 已提交
1415 1416
				vertexColors = face.vertexColors;
				faceColor = face.color;
M
Mr.doob 已提交
1417

A
alteredq 已提交
1418
				if ( vertexColors.length === 4 && vertexColorType === THREE.VertexColors ) {
M
Mr.doob 已提交
1419

A
alteredq 已提交
1420 1421 1422 1423
					c1 = vertexColors[ 0 ];
					c2 = vertexColors[ 1 ];
					c3 = vertexColors[ 2 ];
					c4 = vertexColors[ 3 ];
1424

A
alteredq 已提交
1425
				} else {
M
Mr.doob 已提交
1426

A
alteredq 已提交
1427 1428 1429 1430
					c1 = faceColor;
					c2 = faceColor;
					c3 = faceColor;
					c4 = faceColor;
M
Mr.doob 已提交
1431

A
alteredq 已提交
1432
				}
1433

A
alteredq 已提交
1434 1435 1436
				colorArray[ offset_color ]     = c1.r;
				colorArray[ offset_color + 1 ] = c1.g;
				colorArray[ offset_color + 2 ] = c1.b;
1437

A
alteredq 已提交
1438 1439 1440
				colorArray[ offset_color + 3 ] = c2.r;
				colorArray[ offset_color + 4 ] = c2.g;
				colorArray[ offset_color + 5 ] = c2.b;
M
Mr.doob 已提交
1441

A
alteredq 已提交
1442 1443 1444
				colorArray[ offset_color + 6 ] = c3.r;
				colorArray[ offset_color + 7 ] = c3.g;
				colorArray[ offset_color + 8 ] = c3.b;
M
Mr.doob 已提交
1445

A
alteredq 已提交
1446 1447 1448
				colorArray[ offset_color + 9 ]  = c4.r;
				colorArray[ offset_color + 10 ] = c4.g;
				colorArray[ offset_color + 11 ] = c4.b;
M
Mr.doob 已提交
1449

A
alteredq 已提交
1450
				offset_color += 12;
1451

1452
			}
1453

A
alteredq 已提交
1454
			if ( offset_color > 0 ) {
M
Mr.doob 已提交
1455

A
alteredq 已提交
1456 1457
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
M
Mr.doob 已提交
1458

1459
			}
1460

A
alteredq 已提交
1461
		}
M
Mr.doob 已提交
1462

A
alteredq 已提交
1463
		if ( dirtyTangents && geometry.hasTangents ) {
M
Mr.doob 已提交
1464

A
alteredq 已提交
1465
			for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
1466

A
alteredq 已提交
1467
				face = obj_faces[ chunk_faces3[ f ]	];
1468

A
alteredq 已提交
1469
				vertexTangents = face.vertexTangents;
M
Mr.doob 已提交
1470

A
alteredq 已提交
1471 1472 1473
				t1 = vertexTangents[ 0 ];
				t2 = vertexTangents[ 1 ];
				t3 = vertexTangents[ 2 ];
1474

A
alteredq 已提交
1475 1476 1477 1478
				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 已提交
1479

A
alteredq 已提交
1480 1481 1482 1483
				tangentArray[ offset_tangent + 4 ] = t2.x;
				tangentArray[ offset_tangent + 5 ] = t2.y;
				tangentArray[ offset_tangent + 6 ] = t2.z;
				tangentArray[ offset_tangent + 7 ] = t2.w;
1484

A
alteredq 已提交
1485 1486 1487 1488
				tangentArray[ offset_tangent + 8 ]  = t3.x;
				tangentArray[ offset_tangent + 9 ]  = t3.y;
				tangentArray[ offset_tangent + 10 ] = t3.z;
				tangentArray[ offset_tangent + 11 ] = t3.w;
1489

A
alteredq 已提交
1490
				offset_tangent += 12;
1491

1492
			}
1493

A
alteredq 已提交
1494
			for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
1495

A
alteredq 已提交
1496
				face = obj_faces[ chunk_faces4[ f ] ];
1497

A
alteredq 已提交
1498
				vertexTangents = face.vertexTangents;
1499

A
alteredq 已提交
1500 1501 1502 1503
				t1 = vertexTangents[ 0 ];
				t2 = vertexTangents[ 1 ];
				t3 = vertexTangents[ 2 ];
				t4 = vertexTangents[ 3 ];
1504

A
alteredq 已提交
1505 1506 1507 1508
				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 已提交
1509

A
alteredq 已提交
1510 1511 1512 1513
				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 已提交
1514

A
alteredq 已提交
1515 1516 1517 1518
				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 已提交
1519

A
alteredq 已提交
1520 1521 1522 1523
				tangentArray[ offset_tangent + 12 ] = t4.x;
				tangentArray[ offset_tangent + 13 ] = t4.y;
				tangentArray[ offset_tangent + 14 ] = t4.z;
				tangentArray[ offset_tangent + 15 ] = t4.w;
1524

A
alteredq 已提交
1525
				offset_tangent += 16;
1526

A
alteredq 已提交
1527
			}
1528

A
alteredq 已提交
1529 1530
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint );
1531

A
alteredq 已提交
1532
		}
1533

A
alteredq 已提交
1534
		if ( dirtyNormals && normalType ) {
1535

A
alteredq 已提交
1536
			for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
1537

A
alteredq 已提交
1538
				face = obj_faces[ chunk_faces3[ f ]	];
1539

A
alteredq 已提交
1540 1541
				vertexNormals = face.vertexNormals;
				faceNormal = face.normal;
1542

A
alteredq 已提交
1543
				if ( vertexNormals.length === 3 && needsSmoothNormals ) {
1544

A
alteredq 已提交
1545
					for ( i = 0; i < 3; i ++ ) {
M
Mr.doob 已提交
1546

A
alteredq 已提交
1547
						vn = vertexNormals[ i ];
M
Mr.doob 已提交
1548

A
alteredq 已提交
1549 1550 1551
						normalArray[ offset_normal ]     = vn.x;
						normalArray[ offset_normal + 1 ] = vn.y;
						normalArray[ offset_normal + 2 ] = vn.z;
1552

A
alteredq 已提交
1553
						offset_normal += 3;
1554

A
alteredq 已提交
1555
					}
1556

A
alteredq 已提交
1557
				} else {
M
Mr.doob 已提交
1558

A
alteredq 已提交
1559
					for ( i = 0; i < 3; i ++ ) {
M
Mr.doob 已提交
1560

A
alteredq 已提交
1561 1562 1563
						normalArray[ offset_normal ]     = faceNormal.x;
						normalArray[ offset_normal + 1 ] = faceNormal.y;
						normalArray[ offset_normal + 2 ] = faceNormal.z;
1564

A
alteredq 已提交
1565
						offset_normal += 3;
M
Mr.doob 已提交
1566

A
alteredq 已提交
1567
					}
1568

A
alteredq 已提交
1569
				}
1570

A
alteredq 已提交
1571
			}
1572

A
alteredq 已提交
1573
			for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
1574

A
alteredq 已提交
1575
				face = obj_faces[ chunk_faces4[ f ] ];
1576

A
alteredq 已提交
1577 1578
				vertexNormals = face.vertexNormals;
				faceNormal = face.normal;
1579

A
alteredq 已提交
1580
				if ( vertexNormals.length === 4 && needsSmoothNormals ) {
1581

A
alteredq 已提交
1582
					for ( i = 0; i < 4; i ++ ) {
1583

A
alteredq 已提交
1584
						vn = vertexNormals[ i ];
1585

A
alteredq 已提交
1586 1587 1588
						normalArray[ offset_normal ]     = vn.x;
						normalArray[ offset_normal + 1 ] = vn.y;
						normalArray[ offset_normal + 2 ] = vn.z;
1589

A
alteredq 已提交
1590
						offset_normal += 3;
1591

A
alteredq 已提交
1592
					}
M
Mr.doob 已提交
1593

A
alteredq 已提交
1594
				} else {
1595

A
alteredq 已提交
1596
					for ( i = 0; i < 4; i ++ ) {
1597

A
alteredq 已提交
1598 1599 1600
						normalArray[ offset_normal ]     = faceNormal.x;
						normalArray[ offset_normal + 1 ] = faceNormal.y;
						normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
1601

A
alteredq 已提交
1602
						offset_normal += 3;
M
Mr.doob 已提交
1603

A
alteredq 已提交
1604
					}
1605

A
alteredq 已提交
1606
				}
1607

A
alteredq 已提交
1608
			}
M
Mr.doob 已提交
1609

A
alteredq 已提交
1610 1611
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
M
Mr.doob 已提交
1612

A
alteredq 已提交
1613
		}
M
Mr.doob 已提交
1614

A
alteredq 已提交
1615
		if ( dirtyUvs && obj_uvs && uvType ) {
1616

A
alteredq 已提交
1617
			for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
1618

A
alteredq 已提交
1619
				fi = chunk_faces3[ f ];
1620

A
alteredq 已提交
1621 1622
				face = obj_faces[ fi ];
				uv = obj_uvs[ fi ];
1623

A
alteredq 已提交
1624
				if ( uv === undefined ) continue;
1625

A
alteredq 已提交
1626
				for ( i = 0; i < 3; i ++ ) {
1627

A
alteredq 已提交
1628
					uvi = uv[ i ];
1629

A
alteredq 已提交
1630 1631
					uvArray[ offset_uv ]     = uvi.u;
					uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
1632

A
alteredq 已提交
1633
					offset_uv += 2;
M
Mr.doob 已提交
1634

A
alteredq 已提交
1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655
				}

			}

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

				fi = chunk_faces4[ f ];

				face = obj_faces[ fi ];
				uv = obj_uvs[ fi ];

				if ( uv === undefined ) continue;

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

					uvi = uv[ i ];

					uvArray[ offset_uv ]     = uvi.u;
					uvArray[ offset_uv + 1 ] = uvi.v;

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

1657 1658
				}

1659
			}
1660

A
alteredq 已提交
1661
			if ( offset_uv > 0 ) {
1662

A
alteredq 已提交
1663 1664
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
1665

A
alteredq 已提交
1666
			}
1667

A
alteredq 已提交
1668
		}
1669

A
alteredq 已提交
1670
		if ( dirtyUvs && obj_uvs2 && uvType ) {
1671

A
alteredq 已提交
1672
			for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
1673

A
alteredq 已提交
1674
				fi = chunk_faces3[ f ];
1675

A
alteredq 已提交
1676 1677
				face = obj_faces[ fi ];
				uv2 = obj_uvs2[ fi ];
1678

A
alteredq 已提交
1679 1680 1681 1682 1683 1684 1685 1686 1687 1688
				if ( uv2 === undefined ) continue;

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

					uv2i = uv2[ i ];

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

					offset_uv2 += 2;
1689

1690 1691
				}

A
alteredq 已提交
1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712
			}

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

				fi = chunk_faces4[ f ];

				face = obj_faces[ fi ];
				uv2 = obj_uvs2[ fi ];

				if ( uv2 === undefined ) continue;

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

					uv2i = uv2[ i ];

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

					offset_uv2 += 2;

				}
1713

1714
			}
1715

A
alteredq 已提交
1716
			if ( offset_uv2 > 0 ) {
1717

A
alteredq 已提交
1718 1719
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, uv2Array, hint );
1720

A
alteredq 已提交
1721
			}
1722

A
alteredq 已提交
1723
		}
1724

A
alteredq 已提交
1725
		if ( dirtyElements ) {
1726

A
alteredq 已提交
1727
			for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
1728

A
alteredq 已提交
1729
				face = obj_faces[ chunk_faces3[ f ]	];
1730

A
alteredq 已提交
1731 1732 1733
				faceArray[ offset_face ] 	 = vertexIndex;
				faceArray[ offset_face + 1 ] = vertexIndex + 1;
				faceArray[ offset_face + 2 ] = vertexIndex + 2;
1734

A
alteredq 已提交
1735
				offset_face += 3;
1736

A
alteredq 已提交
1737 1738
				lineArray[ offset_line ]     = vertexIndex;
				lineArray[ offset_line + 1 ] = vertexIndex + 1;
1739

A
alteredq 已提交
1740 1741
				lineArray[ offset_line + 2 ] = vertexIndex;
				lineArray[ offset_line + 3 ] = vertexIndex + 2;
1742

A
alteredq 已提交
1743 1744
				lineArray[ offset_line + 4 ] = vertexIndex + 1;
				lineArray[ offset_line + 5 ] = vertexIndex + 2;
1745

A
alteredq 已提交
1746
				offset_line += 6;
1747

A
alteredq 已提交
1748
				vertexIndex += 3;
1749

A
alteredq 已提交
1750
			}
1751

A
alteredq 已提交
1752
			for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
1753

A
alteredq 已提交
1754
				face = obj_faces[ chunk_faces4[ f ] ];
1755

A
alteredq 已提交
1756 1757 1758
				faceArray[ offset_face ]     = vertexIndex;
				faceArray[ offset_face + 1 ] = vertexIndex + 1;
				faceArray[ offset_face + 2 ] = vertexIndex + 3;
1759

A
alteredq 已提交
1760 1761 1762
				faceArray[ offset_face + 3 ] = vertexIndex + 1;
				faceArray[ offset_face + 4 ] = vertexIndex + 2;
				faceArray[ offset_face + 5 ] = vertexIndex + 3;
1763

A
alteredq 已提交
1764
				offset_face += 6;
1765

A
alteredq 已提交
1766 1767
				lineArray[ offset_line ]     = vertexIndex;
				lineArray[ offset_line + 1 ] = vertexIndex + 1;
1768

A
alteredq 已提交
1769 1770
				lineArray[ offset_line + 2 ] = vertexIndex;
				lineArray[ offset_line + 3 ] = vertexIndex + 3;
1771

A
alteredq 已提交
1772 1773
				lineArray[ offset_line + 4 ] = vertexIndex + 1;
				lineArray[ offset_line + 5 ] = vertexIndex + 2;
1774

A
alteredq 已提交
1775 1776
				lineArray[ offset_line + 6 ] = vertexIndex + 2;
				lineArray[ offset_line + 7 ] = vertexIndex + 3;
1777

A
alteredq 已提交
1778
				offset_line += 8;
1779

A
alteredq 已提交
1780
				vertexIndex += 4;
1781

1782
			}
1783

A
alteredq 已提交
1784 1785
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint );
1786

A
alteredq 已提交
1787 1788
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
1789

A
alteredq 已提交
1790
		}
1791

A
alteredq 已提交
1792
		if ( customAttributes ) {
1793

A
alteredq 已提交
1794
			for ( i = 0, il = customAttributes.length; i < il; i ++ ) {
1795

1796
				customAttribute = customAttributes[ i ];
1797

1798
				if ( ! customAttribute.__original.needsUpdate ) continue;
1799

1800 1801
				offset_custom = 0;
				offset_customSrc = 0;
1802

1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859
				if ( customAttribute.size === 1 ) {

					if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {

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

							face = obj_faces[ chunk_faces3[ f ]	];

							customAttribute.array[ offset_custom ] 	   = customAttribute.value[ face.a ];
							customAttribute.array[ offset_custom + 1 ] = customAttribute.value[ face.b ];
							customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ face.c ];

							offset_custom += 3;

						}

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

							face = obj_faces[ chunk_faces4[ f ] ];

							customAttribute.array[ offset_custom ] 	   = 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 + 3 ] = customAttribute.value[ face.d ];

							offset_custom += 4;

						}

					} else if ( customAttribute.boundTo === "faces" ) {

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

							value = customAttribute.value[ offset_customSrc ];

							customAttribute.array[ offset_custom ] 	   = value;
							customAttribute.array[ offset_custom + 1 ] = value;
							customAttribute.array[ offset_custom + 2 ] = value;

							offset_custom += 3;
							offset_customSrc += 1;

						}

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

							value = customAttribute.value[ offset_customSrc ];

							customAttribute.array[ offset_custom ] 	   = value;
							customAttribute.array[ offset_custom + 1 ] = value;
							customAttribute.array[ offset_custom + 2 ] = value;
							customAttribute.array[ offset_custom + 3 ] = value;

							offset_custom += 4;
							offset_customSrc += 1;

						}
1860

1861
					} else if ( customAttribute.boundTo === "faceVertices" ) {
1862

1863
						for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
1864

1865 1866 1867
							customAttribute.array[ offset_custom ] 	   = customAttribute.value[ offset_customSrc ];
							customAttribute.array[ offset_custom + 1 ] = customAttribute.value[ offset_customSrc + 1 ];
							customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ offset_customSrc + 2 ];
1868

1869 1870
							offset_custom += 3;
							offset_customSrc += 3;
M
Mr.doob 已提交
1871

1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904
						}

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

							customAttribute.array[ offset_custom ] 	   = customAttribute.value[ offset_customSrc ];
							customAttribute.array[ offset_custom + 1 ] = customAttribute.value[ offset_customSrc + 1 ];
							customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ offset_customSrc + 2 ];
							customAttribute.array[ offset_custom + 3 ] = customAttribute.value[ offset_customSrc + 3 ];

							offset_custom += 4;
							offset_customSrc += 4;

						}

					}

				} else if ( customAttribute.size === 2 ) {

					if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {

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

							face = obj_faces[ chunk_faces3[ f ]	];

							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];

							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;

							customAttribute.array[ offset_custom + 2 ] = v2.x;
							customAttribute.array[ offset_custom + 3 ] = v2.y;
A
alteredq 已提交
1905

1906 1907
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
1908

1909
							offset_custom += 6;
A
alteredq 已提交
1910

1911
						}
A
alteredq 已提交
1912

1913
						for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
A
alteredq 已提交
1914

1915
							face = obj_faces[ chunk_faces4[ f ] ];
A
alteredq 已提交
1916

1917 1918 1919 1920
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
							v4 = customAttribute.value[ face.d ];
A
alteredq 已提交
1921

1922 1923
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
1924

1925 1926
							customAttribute.array[ offset_custom + 2 ] = v2.x;
							customAttribute.array[ offset_custom + 3 ] = v2.y;
A
alteredq 已提交
1927

1928 1929
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
1930

1931 1932
							customAttribute.array[ offset_custom + 6 ] = v4.x;
							customAttribute.array[ offset_custom + 7 ] = v4.y;
A
alteredq 已提交
1933

1934
							offset_custom += 8;
A
alteredq 已提交
1935

1936
						}
A
alteredq 已提交
1937

1938
					} else if ( customAttribute.boundTo === "faces" ) {
A
alteredq 已提交
1939

1940
						for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
A
alteredq 已提交
1941

1942
							value = customAttribute.value[ offset_customSrc ];
A
alteredq 已提交
1943

1944 1945 1946
							v1 = value;
							v2 = value;
							v3 = value;
A
alteredq 已提交
1947

1948 1949
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
1950

1951 1952
							customAttribute.array[ offset_custom + 2 ] = v2.x;
							customAttribute.array[ offset_custom + 3 ] = v2.y;
A
alteredq 已提交
1953

1954 1955
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
1956

1957 1958
							offset_custom += 6;
							offset_customSrc += 1;
A
alteredq 已提交
1959

1960
						}
A
alteredq 已提交
1961

1962
						for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
A
alteredq 已提交
1963

1964
							value = customAttribute.value[ offset_customSrc ];
A
alteredq 已提交
1965

1966 1967 1968 1969
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
A
alteredq 已提交
1970

1971 1972
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
1973

1974 1975
							customAttribute.array[ offset_custom + 2 ] = v2.x;
							customAttribute.array[ offset_custom + 3 ] = v2.y;
A
alteredq 已提交
1976

1977 1978
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
1979

1980 1981
							customAttribute.array[ offset_custom + 6 ] = v4.x;
							customAttribute.array[ offset_custom + 7 ] = v4.y;
M
Mr.doob 已提交
1982

1983 1984
							offset_custom += 8;
							offset_customSrc += 1;
M
Mr.doob 已提交
1985

1986
						}
M
Mr.doob 已提交
1987

1988
					} else if ( customAttribute.boundTo === "faceVertices" ) {
M
Mr.doob 已提交
1989

1990
						for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
M
Mr.doob 已提交
1991

1992 1993 1994
							v1 = customAttribute.value[ offset_customSrc ];
							v2 = customAttribute.value[ offset_customSrc + 1 ];
							v3 = customAttribute.value[ offset_customSrc + 2 ];
M
Mr.doob 已提交
1995

1996 1997
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
1998

1999 2000
							customAttribute.array[ offset_custom + 2 ] = v2.x;
							customAttribute.array[ offset_custom + 3 ] = v2.y;
2001

2002 2003
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
M
Mr.doob 已提交
2004

2005 2006
							offset_custom += 6;
							offset_customSrc += 3;
M
Mr.doob 已提交
2007

2008
						}
M
Mr.doob 已提交
2009

2010
						for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
M
Mr.doob 已提交
2011

2012 2013 2014 2015
							v1 = customAttribute.value[ offset_customSrc ];
							v2 = customAttribute.value[ offset_customSrc + 1 ];
							v3 = customAttribute.value[ offset_customSrc + 2 ];
							v4 = customAttribute.value[ offset_customSrc + 3 ];
2016

2017 2018
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
2019

2020 2021
							customAttribute.array[ offset_custom + 2 ] = v2.x;
							customAttribute.array[ offset_custom + 3 ] = v2.y;
2022

2023 2024
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
M
Mr.doob 已提交
2025

2026 2027
							customAttribute.array[ offset_custom + 6 ] = v4.x;
							customAttribute.array[ offset_custom + 7 ] = v4.y;
M
Mr.doob 已提交
2028

2029 2030
							offset_custom += 8;
							offset_customSrc += 4;
A
alteredq 已提交
2031 2032

						}
M
Mr.doob 已提交
2033 2034

					}
M
Mr.doob 已提交
2035

2036
				} else if ( customAttribute.size === 3 ) {
2037

2038
					var pp;
2039

2040
					if ( customAttribute.type === "c" ) {
M
Mr.doob 已提交
2041

2042
						pp = [ "r", "g", "b" ];
M
Mr.doob 已提交
2043

2044
					} else {
M
Mr.doob 已提交
2045

2046
						pp = [ "x", "y", "z" ];
2047

2048
					}
2049

2050
					if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {
2051

2052
						for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
2053

2054
							face = obj_faces[ chunk_faces3[ f ]	];
2055

2056 2057 2058
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
2059

2060 2061 2062
							customAttribute.array[ offset_custom ] 	   = v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
2063

2064 2065 2066
							customAttribute.array[ offset_custom + 3 ] = v2[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 4 ] = v2[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 5 ] = v2[ pp[ 2 ] ];
2067

2068 2069 2070
							customAttribute.array[ offset_custom + 6 ] = v3[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 7 ] = v3[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 8 ] = v3[ pp[ 2 ] ];
M
Mr.doob 已提交
2071

2072
							offset_custom += 9;
M
Mr.doob 已提交
2073

2074
						}
M
Mr.doob 已提交
2075

2076
						for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
M
Mr.doob 已提交
2077

2078
							face = obj_faces[ chunk_faces4[ f ] ];
M
Mr.doob 已提交
2079

2080 2081 2082 2083
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
							v4 = customAttribute.value[ face.d ];
M
Mr.doob 已提交
2084

2085 2086 2087
							customAttribute.array[ offset_custom  ] 	= v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1  ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2  ] = v1[ pp[ 2 ] ];
M
Mr.doob 已提交
2088

2089 2090 2091
							customAttribute.array[ offset_custom + 3  ] = v2[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 4  ] = v2[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 5  ] = v2[ pp[ 2 ] ];
M
Mr.doob 已提交
2092

2093 2094 2095
							customAttribute.array[ offset_custom + 6  ] = v3[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 7  ] = v3[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 8  ] = v3[ pp[ 2 ] ];
M
Mr.doob 已提交
2096

2097 2098 2099
							customAttribute.array[ offset_custom + 9  ] = v4[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 10 ] = v4[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 11 ] = v4[ pp[ 2 ] ];
M
Mr.doob 已提交
2100

2101 2102
							offset_custom += 12;
							offset_customSrc += 1;
M
Mr.doob 已提交
2103

2104
						}
M
Mr.doob 已提交
2105

2106
					} else if ( customAttribute.boundTo === "faces" ) {
M
Mr.doob 已提交
2107

2108
						for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
2109

2110
							value = customAttribute.value[ offset_customSrc ];
2111

2112 2113 2114
							v1 = value;
							v2 = value;
							v3 = value;
M
Mr.doob 已提交
2115

2116 2117 2118
							customAttribute.array[ offset_custom ] 	   = v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
M
Mr.doob 已提交
2119

2120 2121 2122
							customAttribute.array[ offset_custom + 3 ] = v2[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 4 ] = v2[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 5 ] = v2[ pp[ 2 ] ];
M
Mr.doob 已提交
2123

2124 2125 2126
							customAttribute.array[ offset_custom + 6 ] = v3[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 7 ] = v3[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 8 ] = v3[ pp[ 2 ] ];
M
Mr.doob 已提交
2127

2128 2129
							offset_custom += 9;
							offset_customSrc += 1;
M
Mr.doob 已提交
2130

2131
						}
2132

2133
						for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
2134

2135
							value = customAttribute.value[ offset_customSrc ];
2136

2137 2138 2139 2140
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
2141

2142 2143 2144
							customAttribute.array[ offset_custom  ] 	= v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1  ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2  ] = v1[ pp[ 2 ] ];
2145

2146 2147 2148
							customAttribute.array[ offset_custom + 3  ] = v2[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 4  ] = v2[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 5  ] = v2[ pp[ 2 ] ];
2149

2150 2151 2152
							customAttribute.array[ offset_custom + 6  ] = v3[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 7  ] = v3[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 8  ] = v3[ pp[ 2 ] ];
2153

2154 2155 2156
							customAttribute.array[ offset_custom + 9  ] = v4[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 10 ] = v4[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 11 ] = v4[ pp[ 2 ] ];
2157

2158 2159
							offset_custom += 12;
							offset_customSrc += 1;
2160

2161
						}
2162

2163
					} else if ( customAttribute.boundTo === "faceVertices" ) {
2164

2165
						for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
2166

2167 2168 2169
							v1 = customAttribute.value[ offset_customSrc ];
							v2 = customAttribute.value[ offset_customSrc + 1 ];
							v3 = customAttribute.value[ offset_customSrc + 2 ];
2170

2171 2172 2173
							customAttribute.array[ offset_custom ] 	   = v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
2174

2175 2176 2177
							customAttribute.array[ offset_custom + 3 ] = v2[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 4 ] = v2[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 5 ] = v2[ pp[ 2 ] ];
M
Mr.doob 已提交
2178

2179 2180 2181
							customAttribute.array[ offset_custom + 6 ] = v3[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 7 ] = v3[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 8 ] = v3[ pp[ 2 ] ];
M
Mr.doob 已提交
2182

2183 2184
							offset_custom += 9;
							offset_customSrc += 3;
2185

2186
						}
2187

2188
						for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
M
Mr.doob 已提交
2189

2190 2191 2192 2193
							v1 = customAttribute.value[ offset_customSrc ];
							v2 = customAttribute.value[ offset_customSrc + 1 ];
							v3 = customAttribute.value[ offset_customSrc + 2 ];
							v4 = customAttribute.value[ offset_customSrc + 3 ];
2194

2195 2196 2197
							customAttribute.array[ offset_custom  ] 	= v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1  ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2  ] = v1[ pp[ 2 ] ];
M
Mr.doob 已提交
2198

2199 2200 2201
							customAttribute.array[ offset_custom + 3  ] = v2[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 4  ] = v2[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 5  ] = v2[ pp[ 2 ] ];
M
Mr.doob 已提交
2202

2203 2204 2205
							customAttribute.array[ offset_custom + 6  ] = v3[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 7  ] = v3[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 8  ] = v3[ pp[ 2 ] ];
M
Mr.doob 已提交
2206

2207 2208 2209
							customAttribute.array[ offset_custom + 9  ] = v4[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 10 ] = v4[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 11 ] = v4[ pp[ 2 ] ];
2210

2211 2212
							offset_custom += 12;
							offset_customSrc += 4;
2213

A
alteredq 已提交
2214
						}
2215

A
alteredq 已提交
2216
					}
M
Mr.doob 已提交
2217

2218
				} else if ( customAttribute.size === 4 ) {
2219

2220
					if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {
M
Mr.doob 已提交
2221

2222
						for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
2223

2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357
							face = obj_faces[ chunk_faces3[ f ]	];

							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];

							customAttribute.array[ offset_custom  ] 	= 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;

							offset_custom += 12;

						}

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

							face = obj_faces[ chunk_faces4[ f ] ];

							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
							v4 = customAttribute.value[ face.d ];

							customAttribute.array[ offset_custom  ] 	= 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;

							offset_custom += 16;

						}

					} else if ( customAttribute.boundTo === "faces" ) {

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

							value = customAttribute.value[ offset_customSrc ];

							v1 = value;
							v2 = value;
							v3 = value;

							customAttribute.array[ offset_custom  ] 	= 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;

							offset_custom += 12;
							offset_customSrc += 1;

						}

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

							value = customAttribute.value[ offset_customSrc ];

							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;

							customAttribute.array[ offset_custom  ] 	= 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;

							offset_custom += 16;
							offset_customSrc += 1;

						}

					} else if ( customAttribute.boundTo === "faceVertices" ) {

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

							v1 = customAttribute.value[ offset_customSrc ];
							v2 = customAttribute.value[ offset_customSrc + 1 ];
							v3 = customAttribute.value[ offset_customSrc + 2 ];

							customAttribute.array[ offset_custom  ] 	= v1.x;
							customAttribute.array[ offset_custom + 1  ] = v1.y;
							customAttribute.array[ offset_custom + 2  ] = v1.z;
							customAttribute.array[ offset_custom + 3  ] = v1.w;
2358

2359 2360 2361 2362
							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;
A
alteredq 已提交
2363

2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406
							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;

							offset_custom += 12;
							offset_customSrc += 3;

						}

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

							v1 = customAttribute.value[ offset_customSrc ];
							v2 = customAttribute.value[ offset_customSrc + 1 ];
							v3 = customAttribute.value[ offset_customSrc + 2 ];
							v4 = customAttribute.value[ offset_customSrc + 3 ];

							customAttribute.array[ offset_custom  ] 	= 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;

							offset_custom += 16;
							offset_customSrc += 4;

						}

					}
A
alteredq 已提交
2407

A
alteredq 已提交
2408
				}
A
alteredq 已提交
2409

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

A
alteredq 已提交
2413
			}
2414

A
alteredq 已提交
2415
		}
2416

2417
		if ( dispose ) {
2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433

			delete geometryGroup.__inittedArrays;
			delete geometryGroup.__colorArray;
			delete geometryGroup.__normalArray;
			delete geometryGroup.__tangentArray;
			delete geometryGroup.__uvArray;
			delete geometryGroup.__uv2Array;
			delete geometryGroup.__faceArray;
			delete geometryGroup.__vertexArray;
			delete geometryGroup.__lineArray;
			delete geometryGroup.__skinVertexAArray;
			delete geometryGroup.__skinVertexBArray;
			delete geometryGroup.__skinIndexArray;
			delete geometryGroup.__skinWeightArray;

		}
2434

2435
	};
2436

2437
	function setLineBuffers ( geometry, hint ) {
M
Mr.doob 已提交
2438

2439 2440
		var v, c, vertex, offset, color,

2441 2442 2443 2444
		vertices = geometry.vertices,
		colors = geometry.colors,
		vl = vertices.length,
		cl = colors.length,
M
Mr.doob 已提交
2445

2446 2447
		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,
2448

2449
		dirtyVertices = geometry.__dirtyVertices,
A
alteredq 已提交
2450 2451 2452
		dirtyColors = geometry.__dirtyColors,

		customAttributes = geometry.__webglCustomAttributesList,
2453

A
alteredq 已提交
2454 2455 2456
		i, il,
		a, ca, cal, value,
		customAttribute;
M
Mr.doob 已提交
2457

2458
		if ( dirtyVertices ) {
M
Mr.doob 已提交
2459

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

2462
				vertex = vertices[ v ].position;
M
Mr.doob 已提交
2463

2464
				offset = v * 3;
M
Mr.doob 已提交
2465

2466 2467 2468
				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;
M
Mr.doob 已提交
2469

2470 2471
			}

2472
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
A
alteredq 已提交
2473 2474
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );

2475
		}
M
Mr.doob 已提交
2476

2477 2478
		if ( dirtyColors ) {

2479
			for ( c = 0; c < cl; c ++ ) {
2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490

				color = colors[ c ];

				offset = c * 3;

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

			}

2491
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
2492 2493 2494 2495
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}

A
alteredq 已提交
2496 2497 2498 2499 2500 2501
		if ( customAttributes ) {

			for ( i = 0, il = customAttributes.length; i < il; i ++ ) {

				customAttribute = customAttributes[ i ];

2502
				if ( customAttribute.needsUpdate &&
A
alteredq 已提交
2503 2504 2505 2506 2507 2508 2509
					 ( customAttribute.boundTo === undefined ||
					   customAttribute.boundTo === "vertices" ) ) {

					offset = 0;

					cal = customAttribute.value.length;

2510
					if ( customAttribute.size === 1 ) {
A
alteredq 已提交
2511

2512
						for ( ca = 0; ca < cal; ca ++ ) {
A
alteredq 已提交
2513

2514
							customAttribute.array[ ca ] = customAttribute.value[ ca ];
A
alteredq 已提交
2515

2516 2517 2518 2519 2520
						}

					} else if ( customAttribute.size === 2 ) {

						for ( ca = 0; ca < cal; ca ++ ) {
A
alteredq 已提交
2521 2522 2523

							value = customAttribute.value[ ca ];

2524 2525
							customAttribute.array[ offset ] 	= value.x;
							customAttribute.array[ offset + 1 ] = value.y;
A
alteredq 已提交
2526

2527 2528 2529 2530 2531 2532 2533 2534 2535
							offset += 2;

						}

					} else if ( customAttribute.size === 3 ) {

						if ( customAttribute.type === "c" ) {

							for ( ca = 0; ca < cal; ca ++ ) {
A
alteredq 已提交
2536

2537
								value = customAttribute.value[ ca ];
A
alteredq 已提交
2538

2539 2540 2541
								customAttribute.array[ offset ] 	= value.r;
								customAttribute.array[ offset + 1 ] = value.g;
								customAttribute.array[ offset + 2 ] = value.b;
A
alteredq 已提交
2542

2543
								offset += 3;
A
alteredq 已提交
2544

2545
							}
A
alteredq 已提交
2546

2547
						} else {
A
alteredq 已提交
2548

2549
							for ( ca = 0; ca < cal; ca ++ ) {
A
alteredq 已提交
2550

2551
								value = customAttribute.value[ ca ];
A
alteredq 已提交
2552

2553 2554 2555
								customAttribute.array[ offset ] 	= value.x;
								customAttribute.array[ offset + 1 ] = value.y;
								customAttribute.array[ offset + 2 ] = value.z;
A
alteredq 已提交
2556

2557
								offset += 3;
A
alteredq 已提交
2558 2559 2560 2561 2562

							}

						}

2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576
					} else if ( customAttribute.size === 4 ) {

						for ( ca = 0; ca < cal; ca ++ ) {

							value = customAttribute.value[ ca ];

							customAttribute.array[ offset ] 	 = value.x;
							customAttribute.array[ offset + 1  ] = value.y;
							customAttribute.array[ offset + 2  ] = value.z;
							customAttribute.array[ offset + 3  ] = value.w;

							offset += 4;

						}
A
alteredq 已提交
2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588

					}

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

				}

			}

		}

2589
	};
M
Mr.doob 已提交
2590

2591
	function setRibbonBuffers ( geometry, hint ) {
A
alteredq 已提交
2592

2593 2594
		var v, c, vertex, offset, color,

2595 2596 2597 2598
		vertices = geometry.vertices,
		colors = geometry.colors,
		vl = vertices.length,
		cl = colors.length,
A
alteredq 已提交
2599

2600 2601
		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,
2602

2603 2604
		dirtyVertices = geometry.__dirtyVertices,
		dirtyColors = geometry.__dirtyColors;
A
alteredq 已提交
2605 2606 2607

		if ( dirtyVertices ) {

2608
			for ( v = 0; v < vl; v ++ ) {
A
alteredq 已提交
2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619

				vertex = vertices[ v ].position;

				offset = v * 3;

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

			}

2620
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
A
alteredq 已提交
2621 2622 2623 2624 2625 2626
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );

		}

		if ( dirtyColors ) {

2627
			for ( c = 0; c < cl; c ++ ) {
A
alteredq 已提交
2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638

				color = colors[ c ];

				offset = c * 3;

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

			}

2639
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
A
alteredq 已提交
2640 2641 2642 2643 2644
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}

	};
2645

2646
	function setParticleBuffers ( geometry, hint, object ) {
2647

2648 2649
		var v, c, vertex, offset, index, color,

2650 2651
		vertices = geometry.vertices,
		vl = vertices.length,
2652

2653 2654
		colors = geometry.colors,
		cl = colors.length,
2655

2656 2657
		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,
2658

2659
		sortArray = geometry.__sortArray,
2660

2661 2662
		dirtyVertices = geometry.__dirtyVertices,
		dirtyElements = geometry.__dirtyElements,
2663 2664
		dirtyColors = geometry.__dirtyColors,

2665 2666
		customAttributes = geometry.__webglCustomAttributesList,
		i, il,
2667
		a, ca, cal, value,
2668 2669
		customAttribute;

2670
		if ( object.sortParticles ) {
2671

2672
			_projScreenMatrix.multiplySelf( object.matrixWorld );
2673

2674
			for ( v = 0; v < vl; v ++ ) {
2675 2676

				vertex = vertices[ v ].position;
2677

2678 2679
				_vector3.copy( vertex );
				_projScreenMatrix.multiplyVector3( _vector3 );
2680

2681
				sortArray[ v ] = [ _vector3.z, v ];
2682

2683
			}
2684

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

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

2689
				vertex = vertices[ sortArray[v][1] ].position;
2690

2691
				offset = v * 3;
2692

2693 2694 2695
				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;
2696

2697
			}
2698

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

A
alteredq 已提交
2701
				offset = c * 3;
2702

A
alteredq 已提交
2703 2704 2705 2706 2707
				color = colors[ sortArray[c][1] ];

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

2709
			}
2710

2711 2712
			if ( customAttributes ) {

2713
				for ( i = 0, il = customAttributes.length; i < il; i ++ ) {
2714

2715
					customAttribute = customAttributes[ i ];
2716

2717 2718 2719 2720
					if ( ! ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) ) continue;

					offset = 0;

2721 2722
					cal = customAttribute.value.length;

2723
					if ( customAttribute.size === 1 ) {
2724

2725
						for ( ca = 0; ca < cal; ca ++ ) {
2726

2727
							index = sortArray[ ca ][ 1 ];
2728

2729
							customAttribute.array[ ca ] = customAttribute.value[ index ];
2730

2731 2732 2733 2734 2735 2736 2737
						}

					} else if ( customAttribute.size === 2 ) {

						for ( ca = 0; ca < cal; ca ++ ) {

							index = sortArray[ ca ][ 1 ];
2738

2739
							value = customAttribute.value[ index ];
2740

2741 2742
							customAttribute.array[ offset ] 	= value.x;
							customAttribute.array[ offset + 1 ] = value.y;
2743

2744
							offset += 2;
2745

2746
						}
2747

2748
					} else if ( customAttribute.size === 3 ) {
2749

2750
						if ( customAttribute.type === "c" ) {
2751

2752
							for ( ca = 0; ca < cal; ca ++ ) {
2753

2754
								index = sortArray[ ca ][ 1 ];
2755

2756
								value = customAttribute.value[ index ];
2757

2758 2759 2760
								customAttribute.array[ offset ]     = value.r;
								customAttribute.array[ offset + 1 ] = value.g;
								customAttribute.array[ offset + 2 ] = value.b;
2761

2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778
								offset += 3;

							}

						} else {

							for ( ca = 0; ca < cal; ca ++ ) {

								index = sortArray[ ca ][ 1 ];

								value = customAttribute.value[ index ];

								customAttribute.array[ offset ] 	= value.x;
								customAttribute.array[ offset + 1 ] = value.y;
								customAttribute.array[ offset + 2 ] = value.z;

								offset += 3;
2779 2780 2781 2782 2783

							}

						}

2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799
					} else if ( customAttribute.size === 4 ) {

						for ( ca = 0; ca < cal; ca ++ ) {

							index = sortArray[ ca ][ 1 ];

							value = customAttribute.value[ index ];

							customAttribute.array[ offset ]      = value.x;
							customAttribute.array[ offset + 1  ] = value.y;
							customAttribute.array[ offset + 2  ] = value.z;
							customAttribute.array[ offset + 3  ] = value.w;

							offset += 4;

						}
2800 2801 2802 2803 2804 2805 2806

					}

				}

			}

2807
		} else {
2808

2809 2810
			if ( dirtyVertices ) {

2811
				for ( v = 0; v < vl; v ++ ) {
2812 2813 2814 2815 2816 2817 2818 2819 2820 2821

					vertex = vertices[ v ].position;

					offset = v * 3;

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

				}
2822 2823

			}
2824

A
alteredq 已提交
2825
			if ( dirtyColors ) {
2826

2827
				for ( c = 0; c < cl; c ++ ) {
A
alteredq 已提交
2828 2829 2830 2831 2832 2833 2834 2835 2836

					color = colors[ c ];

					offset = c * 3;

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

2837
				}
2838

A
alteredq 已提交
2839
			}
2840

2841 2842
			if ( customAttributes ) {

2843
				for ( i = 0, il = customAttributes.length; i < il; i ++ ) {
2844

2845
					customAttribute = customAttributes[ i ];
2846

2847
					if ( customAttribute.needsUpdate &&
2848 2849
					     ( customAttribute.boundTo === undefined ||
						   customAttribute.boundTo === "vertices") ) {
2850 2851 2852

						cal = customAttribute.value.length;

2853 2854
						offset = 0;

2855
						if ( customAttribute.size === 1 ) {
2856

2857
							for ( ca = 0; ca < cal; ca ++ ) {
2858

2859
								customAttribute.array[ ca ] = customAttribute.value[ ca ];
2860

2861
							}
2862

2863 2864 2865
						} else if ( customAttribute.size === 2 ) {

							for ( ca = 0; ca < cal; ca ++ ) {
2866

2867
								value = customAttribute.value[ ca ];
2868

2869 2870
								customAttribute.array[ offset ] 	= value.x;
								customAttribute.array[ offset + 1 ] = value.y;
2871

2872
								offset += 2;
2873

2874 2875 2876 2877 2878
							}

						} else if ( customAttribute.size === 3 ) {

							if ( customAttribute.type === "c" ) {
2879

2880 2881 2882 2883 2884 2885 2886
								for ( ca = 0; ca < cal; ca ++ ) {

									value = customAttribute.value[ ca ];

									customAttribute.array[ offset ] 	= value.r;
									customAttribute.array[ offset + 1 ] = value.g;
									customAttribute.array[ offset + 2 ] = value.b;
2887

2888
									offset += 3;
2889

2890
								}
2891

2892
							} else {
2893

2894
								for ( ca = 0; ca < cal; ca ++ ) {
2895

2896
									value = customAttribute.value[ ca ];
2897

2898 2899 2900
									customAttribute.array[ offset ] 	= value.x;
									customAttribute.array[ offset + 1 ] = value.y;
									customAttribute.array[ offset + 2 ] = value.z;
2901

2902
									offset += 3;
2903 2904 2905 2906 2907

								}

							}

2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921
						} else if ( customAttribute.size === 4 ) {

							for ( ca = 0; ca < cal; ca ++ ) {

								value = customAttribute.value[ ca ];

								customAttribute.array[ offset ]      = value.x;
								customAttribute.array[ offset + 1  ] = value.y;
								customAttribute.array[ offset + 2  ] = value.z;
								customAttribute.array[ offset + 3  ] = value.w;

								offset += 4;

							}
2922 2923 2924 2925 2926 2927 2928 2929 2930

						}

					}

				}

			}

2931
		}
2932

A
alteredq 已提交
2933
		if ( dirtyVertices || object.sortParticles ) {
2934

2935
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
A
alteredq 已提交
2936
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
2937

A
alteredq 已提交
2938
		}
2939

A
alteredq 已提交
2940
		if ( dirtyColors || object.sortParticles ) {
2941

2942
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
A
alteredq 已提交
2943
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
2944

A
alteredq 已提交
2945
		}
2946

2947 2948
		if ( customAttributes ) {

2949
			for ( i = 0, il = customAttributes.length; i < il; i ++ ) {
2950

2951
				customAttribute = customAttributes[ i ];
2952

2953
				if ( customAttribute.needsUpdate || object.sortParticles ) {
2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964

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

				}

			}

		}


2965
	};
M
Mr.doob 已提交
2966

2967
	function setMaterialShaders( material, shaders ) {
2968

2969
		material.uniforms = THREE.UniformsUtils.clone( shaders.uniforms );
2970 2971
		material.vertexShader = shaders.vertexShader;
		material.fragmentShader = shaders.fragmentShader;
2972

M
Mr.doob 已提交
2973
	};
2974

2975
	function refreshUniformsCommon( uniforms, material ) {
M
Mr.doob 已提交
2976

A
alteredq 已提交
2977
		uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
2978

2979 2980 2981 2982 2983 2984 2985 2986 2987 2988
		if ( _this.gammaInput ) {

			uniforms.diffuse.value.copyGammaToLinear( material.color );

		} else {

			uniforms.diffuse.value = material.color;

		}

A
alteredq 已提交
2989
		uniforms.map.texture = material.map;
2990

2991
		if ( material.map ) {
M
Mr.doob 已提交
2992

2993 2994 2995
			uniforms.offsetRepeat.value.set( material.map.offset.x, material.map.offset.y, material.map.repeat.x, material.map.repeat.y );

		}
2996

2997
		uniforms.lightMap.texture = material.lightMap;
2998

2999
		uniforms.envMap.texture = material.envMap;
3000
		uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : -1;
3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012

		if ( _this.gammaInput ) {

			//uniforms.reflectivity.value = material.reflectivity * material.reflectivity;
			uniforms.reflectivity.value = material.reflectivity;

		} else {

			uniforms.reflectivity.value = material.reflectivity;

		}

3013
		uniforms.refractionRatio.value = material.refractionRatio;
A
alteredq 已提交
3014
		uniforms.combine.value = material.combine;
3015
		uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
3016

3017
	};
3018

3019
	function refreshUniformsLine( uniforms, material ) {
3020

M
Mr.doob 已提交
3021
		uniforms.diffuse.value = material.color;
A
alteredq 已提交
3022
		uniforms.opacity.value = material.opacity;
3023 3024

	};
M
Mr.doob 已提交
3025

3026
	function refreshUniformsParticle( uniforms, material ) {
3027

M
Mr.doob 已提交
3028
		uniforms.psColor.value = material.color;
A
alteredq 已提交
3029 3030
		uniforms.opacity.value = material.opacity;
		uniforms.size.value = material.size;
M
Mr.doob 已提交
3031
		uniforms.scale.value = _canvas.height / 2.0; // TODO: Cache this.
3032

A
alteredq 已提交
3033
		uniforms.map.texture = material.map;
3034

A
alteredq 已提交
3035
	};
3036

3037
	function refreshUniformsFog( uniforms, fog ) {
3038

M
Mr.doob 已提交
3039
		uniforms.fogColor.value = fog.color;
3040

A
alteredq 已提交
3041
		if ( fog instanceof THREE.Fog ) {
3042

A
alteredq 已提交
3043 3044
			uniforms.fogNear.value = fog.near;
			uniforms.fogFar.value = fog.far;
3045

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

A
alteredq 已提交
3048
			uniforms.fogDensity.value = fog.density;
3049 3050

		}
3051

3052 3053
	};

3054
	function refreshUniformsPhong( uniforms, material ) {
M
Mr.doob 已提交
3055

A
alteredq 已提交
3056
		uniforms.shininess.value = material.shininess;
M
Mr.doob 已提交
3057

3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069
		if ( _this.gammaInput ) {

			uniforms.ambient.value.copyGammaToLinear( material.ambient );
			uniforms.specular.value.copyGammaToLinear( material.specular );

		} else {

			uniforms.ambient.value = material.ambient;
			uniforms.specular.value = material.specular;

		}

3070
	};
M
Mr.doob 已提交
3071

3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084
	function refreshUniformsLambert( uniforms, material ) {

		if ( _this.gammaInput ) {

			uniforms.ambient.value.copyGammaToLinear( material.ambient );

		} else {

			uniforms.ambient.value = material.ambient;

		}

	};
M
Mr.doob 已提交
3085

3086
	function refreshUniformsLights( uniforms, lights ) {
M
Mr.doob 已提交
3087

A
alteredq 已提交
3088 3089
		uniforms.enableLighting.value = lights.directional.length + lights.point.length;
		uniforms.ambientLightColor.value = lights.ambient;
3090

A
alteredq 已提交
3091 3092
		uniforms.directionalLightColor.value = lights.directional.colors;
		uniforms.directionalLightDirection.value = lights.directional.positions;
3093

A
alteredq 已提交
3094 3095
		uniforms.pointLightColor.value = lights.point.colors;
		uniforms.pointLightPosition.value = lights.point.positions;
3096
		uniforms.pointLightDistance.value = lights.point.distances;
M
Mr.doob 已提交
3097

A
alteredq 已提交
3098
	};
M
Mr.doob 已提交
3099

3100 3101 3102 3103
	function refreshUniformsShadow( uniforms, material ) {

		if ( uniforms.shadowMatrix ) {

3104 3105 3106 3107 3108 3109 3110
			for ( var i = 0; i < _shadowMatrix.length; i ++ ) {

				uniforms.shadowMatrix.value[ i ] = _shadowMatrix[ i ];
				uniforms.shadowMap.texture[ i ] = _this.shadowMap[ i ];


			}
3111 3112 3113 3114 3115 3116 3117 3118

			uniforms.shadowDarkness.value = _this.shadowMapDarkness;
			uniforms.shadowBias.value = _this.shadowMapBias;

		}

	};

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

3121
		var u, a, identifiers, i, parameters, maxLightCount, maxBones, maxShadows, shaderID;
3122

A
alteredq 已提交
3123
		if ( material instanceof THREE.MeshDepthMaterial ) {
3124

3125
			shaderID = 'depth';
3126

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

3129
			shaderID = 'normal';
3130

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

3133
			shaderID = 'basic';
3134

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

3137
			shaderID = 'lambert';
M
Mr.doob 已提交
3138

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

3141
			shaderID = 'phong';
M
Mr.doob 已提交
3142

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

3145
			shaderID = 'basic';
3146

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

3149 3150 3151 3152 3153 3154 3155
			shaderID = 'particle_basic';

		}

		if ( shaderID ) {

			setMaterialShaders( material, THREE.ShaderLib[ shaderID ] );
3156

A
alteredq 已提交
3157
		}
3158

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

3162
		maxLightCount = allocateLights( lights );
3163

3164 3165
		maxShadows = allocateShadows( lights );

3166
		maxBones = allocateBones( object );
M
Mr.doob 已提交
3167

3168
		parameters = {
3169

M
Mr.doob 已提交
3170
			map: !!material.map, envMap: !!material.envMap, lightMap: !!material.lightMap,
3171
			vertexColors: material.vertexColors,
M
Mr.doob 已提交
3172 3173
			fog: fog, useFog: material.fog,
			sizeAttenuation: material.sizeAttenuation,
3174 3175
			skinning: material.skinning,
			morphTargets: material.morphTargets,
3176
			maxMorphTargets: this.maxMorphTargets,
3177
			maxDirLights: maxLightCount.directional, maxPointLights: maxLightCount.point,
3178
			maxBones: maxBones,
3179
			shadowMapEnabled: this.shadowMapEnabled && object.receiveShadow,
3180 3181 3182
			shadowMapSoft: this.shadowMapSoft,
			shadowMapWidth: this.shadowMapWidth,
			shadowMapHeight: this.shadowMapHeight,
3183
			maxShadows: maxShadows,
3184 3185 3186
			alphaTest: material.alphaTest,
			metal: material.metal,
			perPixel: material.perPixel
3187

3188
		};
M
Mikael Emtinger 已提交
3189

3190
		material.program = buildProgram( shaderID, material.fragmentShader, material.vertexShader, material.uniforms, material.attributes, parameters );
3191

3192
		var attributes = material.program.attributes;
3193

3194
		if ( attributes.position >= 0 ) _gl.enableVertexAttribArray( attributes.position );
3195 3196 3197
		if ( attributes.color >= 0 ) _gl.enableVertexAttribArray( attributes.color );
		if ( attributes.normal >= 0 ) _gl.enableVertexAttribArray( attributes.normal );
		if ( attributes.tangent >= 0 ) _gl.enableVertexAttribArray( attributes.tangent );
3198

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

3203 3204 3205 3206
			_gl.enableVertexAttribArray( attributes.skinVertexA );
			_gl.enableVertexAttribArray( attributes.skinVertexB );
			_gl.enableVertexAttribArray( attributes.skinIndex );
			_gl.enableVertexAttribArray( attributes.skinWeight );
3207

3208
		}
3209

3210
		if ( material.attributes ) {
M
Mr.doob 已提交
3211

3212
			for ( a in material.attributes ) {
M
Mr.doob 已提交
3213

3214
				if( attributes[ a ] !== undefined && attributes[ a ] >= 0 ) _gl.enableVertexAttribArray( attributes[ a ] );
M
Mr.doob 已提交
3215

3216
			}
M
Mr.doob 已提交
3217

3218
		}
3219

3220
		if ( material.morphTargets ) {
3221

3222
			material.numSupportedMorphTargets = 0;
3223

3224
			var id, base = "morphTarget";
3225

3226
			for ( i = 0; i < this.maxMorphTargets; i ++ ) {
3227

3228
				id = base + i;
3229

3230
				if ( attributes[ id ] >= 0 ) {
3231

3232 3233
					_gl.enableVertexAttribArray( attributes[ id ] );
					material.numSupportedMorphTargets ++;
3234

3235
				}
3236

3237
			}
3238

3239
		}
M
Mr.doob 已提交
3240

M
Mr.doob 已提交
3241 3242 3243 3244 3245 3246 3247 3248
		material.uniformsList = [];

		for ( u in material.uniforms ) {

			material.uniformsList.push( [ material.uniforms[ u ], u ] );

		}

3249
	};
3250

3251
	function setProgram( camera, lights, fog, material, object ) {
3252

3253
		if ( ! material.program ) {
3254 3255 3256 3257

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

		}
M
Mr.doob 已提交
3258

3259 3260 3261 3262 3263 3264
		if ( material.morphTargets ) {

			if ( ! object.__webglMorphTargetInfluences ) {

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

3265
				for ( var i = 0, il = _this.maxMorphTargets; i < il; i ++ ) {
3266 3267 3268 3269 3270 3271 3272 3273 3274

					object.__webglMorphTargetInfluences[ i ] = 0;

				}

			}

		}

M
Mr.doob 已提交
3275 3276
		var refreshMaterial = false;

3277
		var program = material.program,
A
alteredq 已提交
3278 3279
			p_uniforms = program.uniforms,
			m_uniforms = material.uniforms;
3280

3281
		if ( program !== _currentProgram ) {
M
Mr.doob 已提交
3282

M
Mr.doob 已提交
3283
			_gl.useProgram( program );
3284
			_currentProgram = program;
3285

M
Mr.doob 已提交
3286 3287
			refreshMaterial = true;

M
Mr.doob 已提交
3288
		}
3289

3290
		if ( material.id !== _currentMaterialId ) {
3291

M
Mr.doob 已提交
3292 3293
			_currentMaterialId = material.id;
			refreshMaterial = true;
3294

M
Mr.doob 已提交
3295
		}
3296

M
Mr.doob 已提交
3297
		if ( refreshMaterial ) {
3298

M
Mr.doob 已提交
3299
			_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, _projectionMatrixArray );
M
Mr.doob 已提交
3300

M
Mr.doob 已提交
3301
			// refresh uniforms common to several materials
3302

M
Mr.doob 已提交
3303
			if ( fog && material.fog ) {
M
Mr.doob 已提交
3304

M
Mr.doob 已提交
3305
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
3306

M
Mr.doob 已提交
3307
			}
M
Mr.doob 已提交
3308

M
Mr.doob 已提交
3309 3310 3311
			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material.lights ) {
M
Mr.doob 已提交
3312

M
Mr.doob 已提交
3313 3314
				setupLights( program, lights );
				refreshUniformsLights( m_uniforms, _lights );
M
Mr.doob 已提交
3315

M
Mr.doob 已提交
3316
			}
3317

M
Mr.doob 已提交
3318 3319 3320
			if ( material instanceof THREE.MeshBasicMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
3321

M
Mr.doob 已提交
3322
				refreshUniformsCommon( m_uniforms, material );
3323

M
Mr.doob 已提交
3324
			}
3325

M
Mr.doob 已提交
3326
			// refresh single material specific uniforms
3327

M
Mr.doob 已提交
3328
			if ( material instanceof THREE.LineBasicMaterial ) {
M
Mr.doob 已提交
3329

M
Mr.doob 已提交
3330
				refreshUniformsLine( m_uniforms, material );
M
Mr.doob 已提交
3331

M
Mr.doob 已提交
3332
			} else if ( material instanceof THREE.ParticleBasicMaterial ) {
M
Mr.doob 已提交
3333

M
Mr.doob 已提交
3334
				refreshUniformsParticle( m_uniforms, material );
3335

M
Mr.doob 已提交
3336
			} else if ( material instanceof THREE.MeshPhongMaterial ) {
3337

M
Mr.doob 已提交
3338
				refreshUniformsPhong( m_uniforms, material );
3339

3340 3341 3342 3343
			} else if ( material instanceof THREE.MeshLambertMaterial ) {

				refreshUniformsLambert( m_uniforms, material );

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

M
Mr.doob 已提交
3346 3347 3348
				m_uniforms.mNear.value = camera.near;
				m_uniforms.mFar.value = camera.far;
				m_uniforms.opacity.value = material.opacity;
3349

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

M
Mr.doob 已提交
3352
				m_uniforms.opacity.value = material.opacity;
3353

M
Mr.doob 已提交
3354
			}
3355

M
Mr.doob 已提交
3356
			if ( object.receiveShadow && ! material._shadowPass ) {
3357

M
Mr.doob 已提交
3358
				refreshUniformsShadow( m_uniforms, material );
3359

M
Mr.doob 已提交
3360
			}
3361

M
Mr.doob 已提交
3362
			// load common uniforms
M
Mr.doob 已提交
3363

M
Mr.doob 已提交
3364
			loadUniformsGeneric( program, material.uniformsList );
M
Mr.doob 已提交
3365

M
Mr.doob 已提交
3366 3367
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)
3368

M
Mr.doob 已提交
3369 3370 3371
			if ( material instanceof THREE.ShaderMaterial ||
				 material instanceof THREE.MeshPhongMaterial ||
				 material.envMap ) {
3372

M
Mr.doob 已提交
3373
				if( p_uniforms.cameraPosition !== null ) {
3374

M
Mr.doob 已提交
3375
					_gl.uniform3f( p_uniforms.cameraPosition, camera.position.x, camera.position.y, camera.position.z );
M
Mr.doob 已提交
3376

M
Mr.doob 已提交
3377
				}
M
Mr.doob 已提交
3378

3379
			}
3380

M
Mr.doob 已提交
3381 3382 3383 3384
			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material instanceof THREE.ShaderMaterial ||
				 material.skinning ) {
3385

M
Mr.doob 已提交
3386
				if( p_uniforms.viewMatrix !== null ) {
3387

M
Mr.doob 已提交
3388
					_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, _viewMatrixArray );
M
Mr.doob 已提交
3389

M
Mr.doob 已提交
3390 3391 3392 3393 3394 3395 3396
				}

			}

			if ( material.skinning ) {

				loadUniformsSkinning( p_uniforms, object );
M
Mr.doob 已提交
3397 3398

			}
3399

A
alteredq 已提交
3400
		}
3401

M
Mr.doob 已提交
3402 3403 3404 3405 3406 3407 3408 3409 3410 3411
		loadUniformsMatrices( p_uniforms, object );

		if ( material instanceof THREE.ShaderMaterial ||
			 material.envMap ||
			 material.skinning ||
			 object.receiveShadow ) {

			if ( p_uniforms.objectMatrix !== null ) {

				_gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object._objectMatrixArray );
3412

M
Mr.doob 已提交
3413
			}
3414

A
alteredq 已提交
3415
		}
3416

A
alteredq 已提交
3417
		return program;
3418

A
alteredq 已提交
3419
	};
3420

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

3423
		if ( material.opacity === 0 ) return;
3424

3425
		var program, attributes, linewidth, primitives, a, attribute, i, il;
A
alteredq 已提交
3426

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

3429
		attributes = program.attributes;
M
Mr.doob 已提交
3430

M
Mr.doob 已提交
3431
		var updateBuffers = false,
3432 3433
			wireframeBit = material.wireframe ? 1 : 0,
			geometryGroupHash = ( geometryGroup.id * 0xffffff ) + ( program.id * 2 ) + wireframeBit;
M
Mr.doob 已提交
3434

3435
		if ( geometryGroupHash !== _currentGeometryGroupHash ) {
M
Mr.doob 已提交
3436 3437 3438 3439 3440 3441

			_currentGeometryGroupHash = geometryGroupHash;
			updateBuffers = true;

		}

3442
		// vertices
M
Mr.doob 已提交
3443

3444
		if ( !material.morphTargets && attributes.position >= 0 ) {
3445

M
Mr.doob 已提交
3446 3447 3448 3449 3450 3451
			if ( updateBuffers ) {

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

			}
3452

3453
		} else {
3454

3455 3456 3457 3458 3459
			if ( object.morphTargetBase ) {

				setupMorphTargets( material, geometryGroup, object );

			}
3460

3461 3462
		}

3463

M
Mr.doob 已提交
3464
		if ( updateBuffers ) {
3465

M
Mr.doob 已提交
3466
			// custom attributes
3467

M
Mr.doob 已提交
3468
			// Use the per-geometryGroup custom attribute arrays which are setup in initMeshBuffers
M
Mr.doob 已提交
3469

3470
			if ( geometryGroup.__webglCustomAttributesList ) {
M
Mr.doob 已提交
3471

3472
				for ( i = 0, il = geometryGroup.__webglCustomAttributesList.length; i < il; i ++ ) {
M
Mr.doob 已提交
3473

3474
					attribute = geometryGroup.__webglCustomAttributesList[ i ];
M
Mr.doob 已提交
3475

3476
					if( attributes[ attribute.buffer.belongsToAttribute ] >= 0 ) {
M
Mr.doob 已提交
3477 3478

						_gl.bindBuffer( _gl.ARRAY_BUFFER, attribute.buffer );
3479
						_gl.vertexAttribPointer( attributes[ attribute.buffer.belongsToAttribute ], attribute.size, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
3480 3481

					}
M
Mr.doob 已提交
3482

3483
				}
M
Mr.doob 已提交
3484

3485
			}
M
Mr.doob 已提交
3486

3487

M
Mr.doob 已提交
3488
			// colors
3489

M
Mr.doob 已提交
3490
			if ( attributes.color >= 0 ) {
A
alteredq 已提交
3491

M
Mr.doob 已提交
3492 3493
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
				_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
3494

M
Mr.doob 已提交
3495
			}
A
alteredq 已提交
3496

M
Mr.doob 已提交
3497
			// normals
A
alteredq 已提交
3498

M
Mr.doob 已提交
3499
			if ( attributes.normal >= 0 ) {
M
Mr.doob 已提交
3500

M
Mr.doob 已提交
3501 3502
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
				_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
3503

M
Mr.doob 已提交
3504
			}
3505

M
Mr.doob 已提交
3506
			// tangents
3507

M
Mr.doob 已提交
3508
			if ( attributes.tangent >= 0 ) {
3509

M
Mr.doob 已提交
3510 3511
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
				_gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
3512

M
Mr.doob 已提交
3513
			}
3514

M
Mr.doob 已提交
3515
			// uvs
3516

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

M
Mr.doob 已提交
3519
				if ( geometryGroup.__webglUVBuffer ) {
M
Mr.doob 已提交
3520

M
Mr.doob 已提交
3521 3522
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
					_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
3523

M
Mr.doob 已提交
3524
					_gl.enableVertexAttribArray( attributes.uv );
3525

M
Mr.doob 已提交
3526
				} else {
3527

M
Mr.doob 已提交
3528
					_gl.disableVertexAttribArray( attributes.uv );
3529

M
Mr.doob 已提交
3530
				}
M
Mr.doob 已提交
3531

3532
			}
3533

M
Mr.doob 已提交
3534
			if ( attributes.uv2 >= 0 ) {
3535

M
Mr.doob 已提交
3536
				if ( geometryGroup.__webglUV2Buffer ) {
3537

M
Mr.doob 已提交
3538 3539
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
					_gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );
3540

M
Mr.doob 已提交
3541
					_gl.enableVertexAttribArray( attributes.uv2 );
3542

M
Mr.doob 已提交
3543
				} else {
3544

M
Mr.doob 已提交
3545
					_gl.disableVertexAttribArray( attributes.uv2 );
3546

M
Mr.doob 已提交
3547
				}
3548 3549 3550

			}

M
Mr.doob 已提交
3551 3552 3553
			if ( material.skinning &&
				 attributes.skinVertexA >= 0 && attributes.skinVertexB >= 0 &&
				 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
3554

M
Mr.doob 已提交
3555 3556
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
				_gl.vertexAttribPointer( attributes.skinVertexA, 4, _gl.FLOAT, false, 0, 0 );
3557

M
Mr.doob 已提交
3558 3559
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
				_gl.vertexAttribPointer( attributes.skinVertexB, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
3560

M
Mr.doob 已提交
3561 3562
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
				_gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
3563

M
Mr.doob 已提交
3564 3565
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
				_gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
3566

M
Mr.doob 已提交
3567
			}
3568

A
alteredq 已提交
3569
		}
3570

3571
		// render mesh
M
Mr.doob 已提交
3572

3573
		if ( object instanceof THREE.Mesh ) {
3574

3575
			// wireframe
3576

3577
			if ( material.wireframe ) {
M
Mr.doob 已提交
3578

A
alteredq 已提交
3579
				setLineWidth( material.wireframeLinewidth );
M
Mr.doob 已提交
3580 3581

				if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
3582
				_gl.drawElements( _gl.LINES, geometryGroup.__webglLineCount, _gl.UNSIGNED_SHORT, 0 );
3583

3584
			// triangles
3585

3586
			} else {
3587

M
Mr.doob 已提交
3588
				if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
3589 3590
				_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );

3591
			}
3592

M
Mr.doob 已提交
3593 3594 3595
			_this.info.render.calls ++;
			_this.info.render.vertices += geometryGroup.__webglFaceCount;
			_this.info.render.faces += geometryGroup.__webglFaceCount / 3;
3596

3597
		// render lines
3598

3599
		} else if ( object instanceof THREE.Line ) {
3600

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

A
alteredq 已提交
3603 3604
			setLineWidth( material.linewidth );

3605
			_gl.drawArrays( primitives, 0, geometryGroup.__webglLineCount );
3606

M
Mr.doob 已提交
3607
			_this.info.render.calls ++;
3608

3609
		// render particles
3610

3611
		} else if ( object instanceof THREE.ParticleSystem ) {
3612

3613
			_gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webglParticleCount );
3614

M
Mr.doob 已提交
3615
			_this.info.render.calls ++;
3616

A
alteredq 已提交
3617
		// render ribbon
3618

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

3621
			_gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webglVertexCount );
3622

M
Mr.doob 已提交
3623
			_this.info.render.calls ++;
3624

3625 3626 3627 3628
		}

	};

M
Mikael Emtinger 已提交
3629
	function setupMorphTargets( material, geometryGroup, object ) {
3630

M
Mikael Emtinger 已提交
3631
		// set base
3632

M
Mikael Emtinger 已提交
3633
		var attributes = material.program.attributes;
3634

3635
		if ( object.morphTargetBase !== - 1 ) {
3636 3637

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

3640
		} else if ( attributes.position >= 0 ) {
3641 3642

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

M
Mikael Emtinger 已提交
3645
		}
3646

3647
		if ( object.morphTargetForcedOrder.length ) {
M
Mikael Emtinger 已提交
3648 3649

			// set forced order
3650

M
Mikael Emtinger 已提交
3651 3652 3653
			var m = 0;
			var order = object.morphTargetForcedOrder;
			var influences = object.morphTargetInfluences;
3654 3655 3656 3657

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

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

3660
				object.__webglMorphTargetInfluences[ m ] = influences[ order[ m ] ];
3661 3662 3663

				m ++;
			}
3664

M
Mikael Emtinger 已提交
3665
		} else {
3666

M
Mikael Emtinger 已提交
3667
			// find most influencing
3668

M
Mikael Emtinger 已提交
3669
			var used = [];
3670
			var candidateInfluence = - 1;
M
Mikael Emtinger 已提交
3671 3672 3673 3674
			var candidate = 0;
			var influences = object.morphTargetInfluences;
			var i, il = influences.length;
			var m = 0;
3675

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

M
Mikael Emtinger 已提交
3678
				used[ object.morphTargetBase ] = true;
3679

M
Mikael Emtinger 已提交
3680
			}
3681 3682 3683

			while ( m < material.numSupportedMorphTargets ) {

3684
				for ( i = 0; i < il; i ++ ) {
3685 3686 3687

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

M
Mikael Emtinger 已提交
3688 3689
						candidate = i;
						candidateInfluence = influences[ candidate ];
3690

M
Mikael Emtinger 已提交
3691
					}
3692

M
Mikael Emtinger 已提交
3693
				}
3694 3695

				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ candidate ] );
M
Mikael Emtinger 已提交
3696
				_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
3697 3698 3699

				object.__webglMorphTargetInfluences[ m ] = candidateInfluence;

M
Mikael Emtinger 已提交
3700 3701
				used[ candidate ] = 1;
				candidateInfluence = -1;
3702
				m ++;
3703

M
Mikael Emtinger 已提交
3704
			}
3705

M
Mikael Emtinger 已提交
3706 3707 3708
		}

		// load updated influences uniform
3709

3710
		if( material.program.uniforms.morphTargetInfluences !== null ) {
M
Mr.doob 已提交
3711

3712
			_gl.uniform1fv( material.program.uniforms.morphTargetInfluences, object.__webglMorphTargetInfluences );
M
Mr.doob 已提交
3713

3714 3715
		}

M
Mikael Emtinger 已提交
3716 3717 3718
	}


3719
	function renderBufferImmediate( object, program, shading ) {
3720

3721 3722
		if ( ! object.__webglVertexBuffer ) object.__webglVertexBuffer = _gl.createBuffer();
		if ( ! object.__webglNormalBuffer ) object.__webglNormalBuffer = _gl.createBuffer();
3723

A
alteredq 已提交
3724
		if ( object.hasPos ) {
3725

3726 3727 3728 3729
			_gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglVertexBuffer );
			_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 );
3730

A
alteredq 已提交
3731
		}
3732

A
alteredq 已提交
3733
		if ( object.hasNormal ) {
3734

3735
			_gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglNormalBuffer );
3736

3737
			if ( shading === THREE.FlatShading ) {
3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763

				var nx, ny, nz,
					nax, nbx, ncx, nay, nby, ncy, naz, nbz, ncz,
					normalArray,
					i, il = object.count * 3;

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

					normalArray = object.normalArray;

					nax  = normalArray[ i ];
					nay  = normalArray[ i + 1 ];
					naz  = normalArray[ i + 2 ];

					nbx  = normalArray[ i + 3 ];
					nby  = normalArray[ i + 4 ];
					nbz  = normalArray[ i + 5 ];

					ncx  = normalArray[ i + 6 ];
					ncy  = normalArray[ i + 7 ];
					ncz  = normalArray[ i + 8 ];

					nx = ( nax + nbx + ncx ) / 3;
					ny = ( nay + nby + ncy ) / 3;
					nz = ( naz + nbz + ncz ) / 3;

M
Mr.doob 已提交
3764
					normalArray[ i ] 	 = nx;
3765 3766 3767
					normalArray[ i + 1 ] = ny;
					normalArray[ i + 2 ] = nz;

M
Mr.doob 已提交
3768
					normalArray[ i + 3 ] = nx;
3769 3770 3771
					normalArray[ i + 4 ] = ny;
					normalArray[ i + 5 ] = nz;

M
Mr.doob 已提交
3772
					normalArray[ i + 6 ] = nx;
3773 3774 3775 3776 3777 3778 3779
					normalArray[ i + 7 ] = ny;
					normalArray[ i + 8 ] = nz;

				}

			}

3780 3781 3782
			_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 );
3783

A
alteredq 已提交
3784
		}
3785

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

A
alteredq 已提交
3788
		object.count = 0;
3789

A
alteredq 已提交
3790
	};
3791

A
alteredq 已提交
3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803
	function setLineWidth( width ) {

		if ( width !== _oldLineWidth ) {

			_gl.lineWidth( width );

			_oldLineWidth = width;

		}

	};

3804
	function setObjectFaces( object ) {
3805

3806
		if ( _oldDoubleSided !== object.doubleSided ) {
3807

3808
			if( object.doubleSided ) {
3809

3810
				_gl.disable( _gl.CULL_FACE );
3811

3812
			} else {
3813

A
alteredq 已提交
3814
				_gl.enable( _gl.CULL_FACE );
3815

A
alteredq 已提交
3816
			}
3817

3818
			_oldDoubleSided = object.doubleSided;
3819

3820
		}
3821

3822
		if ( _oldFlipSided !== object.flipSided ) {
3823

3824 3825 3826 3827
			if( object.flipSided ) {

				_gl.frontFace( _gl.CW );

3828
			} else {
3829 3830 3831 3832

				_gl.frontFace( _gl.CCW );

			}
3833

3834
			_oldFlipSided = object.flipSided;
3835 3836

		}
3837

3838
	};
3839

M
Mr.doob 已提交
3840
	function setDepthTest( depthTest ) {
3841

3842
		if ( _oldDepthTest !== depthTest ) {
A
alteredq 已提交
3843

M
Mr.doob 已提交
3844
			if( depthTest ) {
3845

A
alteredq 已提交
3846
				_gl.enable( _gl.DEPTH_TEST );
3847

A
alteredq 已提交
3848
			} else {
3849

A
alteredq 已提交
3850
				_gl.disable( _gl.DEPTH_TEST );
3851

A
alteredq 已提交
3852
			}
3853

M
Mr.doob 已提交
3854 3855 3856 3857 3858 3859 3860 3861
			_oldDepthTest = depthTest;

		}

	};

	function setDepthWrite( depthWrite ) {

3862
		if ( _oldDepthWrite !== depthWrite ) {
M
Mr.doob 已提交
3863 3864 3865

			_gl.depthMask( depthWrite );
			_oldDepthWrite = depthWrite;
A
alteredq 已提交
3866 3867

		}
3868

A
alteredq 已提交
3869
	};
M
Mr.doob 已提交
3870 3871 3872

	function setPolygonOffset ( polygonoffset, factor, units ) {

3873
		if ( _oldPolygonOffset !== polygonoffset ) {
M
Mr.doob 已提交
3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888

			if ( polygonoffset ) {

				_gl.enable( _gl.POLYGON_OFFSET_FILL );

			} else {

				_gl.disable( _gl.POLYGON_OFFSET_FILL );

			}

			_oldPolygonOffset = polygonoffset;

		}

3889
		if ( polygonoffset && ( _oldPolygonOffsetFactor !== factor || _oldPolygonOffsetUnits !== units ) ) {
M
Mr.doob 已提交
3890 3891 3892 3893 3894 3895 3896 3897 3898

			_gl.polygonOffset( factor, units );

			_oldPolygonOffsetFactor = factor;
			_oldPolygonOffsetUnits = units;

		}

	};
3899

M
Mr.doob 已提交
3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935
	function computeFrustum( m ) {

		_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;

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

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

		}

	};

	function isInFrustum( object ) {

		var distance, matrix = object.matrixWorld,
		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;

	};

3936
	function addToFixedArray( where, what ) {
3937

3938 3939
		where.list[ where.count ] = what;
		where.count += 1;
3940

3941
	};
3942

3943
	function unrollImmediateBufferMaterial( globject ) {
3944

3945 3946
		var object = globject.object,
			material = object.material;
3947

3948
		if ( material.transparent ) {
3949

3950 3951
			globject.transparent = material;
			globject.opaque = null;
3952

3953 3954 3955 3956
		} else {

			globject.opaque = material;
			globject.transparent = null;
3957

3958
		}
3959

3960
	};
3961

3962
	function unrollBufferMaterial( globject ) {
3963

3964
		var object = globject.object,
3965
			buffer = globject.buffer,
3966 3967 3968 3969 3970 3971 3972
			material, materialIndex, meshMaterial;

		meshMaterial = object.material;

		if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {

			materialIndex = buffer.materialIndex;
3973

3974
			if ( materialIndex >= 0 ) {
3975

3976
				material = object.geometry.materials[ materialIndex ];
3977

3978
				if ( material.transparent ) {
3979

3980 3981
					globject.transparent = material;
					globject.opaque = null;
3982

3983
				} else {
3984

3985 3986
					globject.opaque = material;
					globject.transparent = null;
3987 3988 3989

				}

3990 3991 3992
			}

		} else {
3993

3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008
			material = meshMaterial;

			if ( material ) {

				if ( material.transparent ) {

					globject.transparent = material;
					globject.opaque = null;

				} else {

					globject.opaque = material;
					globject.transparent = null;

				}
4009

4010 4011 4012
			}

		}
4013

4014
	};
4015

4016
	function painterSort( a, b ) {
4017

4018
		return b.z - a.z;
4019 4020

	};
4021

4022 4023 4024
	function renderShadowMap( scene, camera ) {

		var i, il, light,
4025 4026
			j = 0,
			shadowMap, shadowMatrix,
4027 4028
			oil,
			material,
4029
			program, buffer,
4030
			o, ol, webglObject, object,
4031
			lights = scene.lights,
4032 4033 4034 4035
			fog = null;

		if ( ! _cameraLight ) {

M
Mr.doob 已提交
4036
			_cameraLight = new THREE.PerspectiveCamera( _this.shadowCameraFov, _this.shadowMapWidth / _this.shadowMapHeight, _this.shadowCameraNear, _this.shadowCameraFar );
4037 4038 4039 4040 4041 4042 4043 4044 4045

		}

		for ( i = 0, il = lights.length; i < il; i ++ ) {

			light = lights[ i ];

			if ( light instanceof THREE.SpotLight && light.castShadow ) {

M
Mr.doob 已提交
4046 4047
				_currentMaterialId = -1;

4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063
				if ( ! _this.shadowMap[ j ] ) {

					var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat };
					_this.shadowMap[ j ] = new THREE.WebGLRenderTarget( _this.shadowMapWidth, _this.shadowMapHeight, pars );

				}

				if ( ! _shadowMatrix[ j ] ) {

					_shadowMatrix[ j ] = new THREE.Matrix4();

				}

				shadowMap = _this.shadowMap[ j ];
				shadowMatrix = _shadowMatrix[ j ];

4064
				_cameraLight.position.copy( light.position );
M
Mr.doob 已提交
4065
				_cameraLight.lookAt( light.target.position );
4066

A
alteredq 已提交
4067
				if ( _cameraLight.parent == null ) {
4068

A
alteredq 已提交
4069 4070 4071 4072 4073
					console.warn( "Camera is not on the Scene. Adding it..." );
					scene.add( _cameraLight );

				}

4074
				if ( this.autoUpdateScene ) scene.updateMatrixWorld();
A
alteredq 已提交
4075 4076

				_cameraLight.matrixWorldInverse.getInverse( _cameraLight.matrixWorld );
4077

4078 4079
				// compute shadow matrix

4080 4081 4082 4083
				shadowMatrix.set( 0.5, 0.0, 0.0, 0.5,
								  0.0, 0.5, 0.0, 0.5,
								  0.0, 0.0, 0.5, 0.5,
								  0.0, 0.0, 0.0, 1.0 );
4084

4085 4086
				shadowMatrix.multiplySelf( _cameraLight.projectionMatrix );
				shadowMatrix.multiplySelf( _cameraLight.matrixWorldInverse );
4087 4088 4089 4090 4091 4092 4093 4094 4095

				// render shadow map

				_cameraLight.matrixWorldInverse.flattenToArray( _viewMatrixArray );
				_cameraLight.projectionMatrix.flattenToArray( _projectionMatrixArray );

				_projScreenMatrix.multiply( _cameraLight.projectionMatrix, _cameraLight.matrixWorldInverse );
				computeFrustum( _projScreenMatrix );

4096
				setRenderTarget( shadowMap );
4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120

				// using arbitrary clear color in depth pass
				// creates variance in shadows

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

				_this.clear();

				_gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );


				// set matrices & frustum culling

				ol = scene.__webglObjects.length;
				oil = scene.__webglObjectsImmediate.length;

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

					webglObject = scene.__webglObjects[ o ];
					object = webglObject.object;

					if ( object.visible && object.castShadow ) {

A
alteredq 已提交
4121
						if ( ! ( object instanceof THREE.Mesh ) || ! ( object.frustumCulled ) || isInFrustum( object ) ) {
4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158

							object.matrixWorld.flattenToArray( object._objectMatrixArray );

							setupMatrices( object, _cameraLight, false );

							webglObject.render = true;

						} else {

							webglObject.render = false;

						}

					} else {

						webglObject.render = false;

					}

				}

				setDepthTest( true );
				setBlending( THREE.NormalBlending ); // maybe blending should be just disabled?

				//_gl.cullFace( _gl.FRONT );

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

					webglObject = scene.__webglObjects[ o ];

					if ( webglObject.render ) {

						object = webglObject.object;
						buffer = webglObject.buffer;

						setObjectFaces( object );

4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171
						if ( object.customDepthMaterial ) {

							material =  object.customDepthMaterial;

						} else if ( object.geometry.morphTargets.length ) {

							material =  _depthMaterialMorph;

						} else {

							material = _depthMaterial;

						}
4172 4173 4174 4175 4176 4177 4178 4179

						renderBuffer( _cameraLight, lights, fog, material, buffer, object );

					}

				}


4180
				for ( o = 0; o < oil; o ++ ) {
4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192

					webglObject = scene.__webglObjectsImmediate[ o ];
					object = webglObject.object;

					if ( object.visible && object.castShadow ) {

						if( object.matrixAutoUpdate ) {

							object.matrixWorld.flattenToArray( object._objectMatrixArray );

						}

M
Mr.doob 已提交
4193 4194
						_currentGeometryGroupHash = -1;

4195 4196 4197 4198 4199
						setupMatrices( object, _cameraLight, false );

						setObjectFaces( object );

						program = setProgram( _cameraLight, lights, fog, _depthMaterial, object );
M
Mr.doob 已提交
4200 4201 4202 4203 4204 4205 4206 4207 4208 4209

						if ( object.immediateRenderCallback ) {

							object.immediateRenderCallback( program, _gl, _frustum );

						} else {

							object.render( function( object ) { renderBufferImmediate( object, program, _depthMaterial.shading ); } );

						}
4210 4211 4212 4213 4214 4215 4216

					}

				}

				//_gl.cullFace( _gl.BACK );

4217 4218
				j ++;

4219 4220 4221 4222 4223 4224
			}

		}

	};

M
Mr.doob 已提交
4225
	this.clearTarget = function ( renderTarget, color, depth, stencil ) {
4226 4227

		setRenderTarget( renderTarget );
M
Mr.doob 已提交
4228
		this.clear( color, depth, stencil );
4229 4230 4231

	};

4232 4233 4234 4235 4236 4237
	this.updateShadowMap = function ( scene, camera ) {

		renderShadowMap( scene, camera );

	};

4238
	this.render = function( scene, camera, renderTarget, forceClear ) {
4239

4240
		var i, program, material,
4241
			o, ol, oil, webglObject, object, buffer,
4242
			lights = scene.lights,
N
Nicholas Kinsey 已提交
4243
			fog = scene.fog;
4244

M
Mr.doob 已提交
4245 4246
		_currentMaterialId = -1;

4247 4248 4249
		if ( this.autoUpdateObjects ) this.initWebGLObjects( scene );

		if ( this.shadowMapEnabled && this.shadowMapAutoUpdate ) renderShadowMap( scene, camera );
4250

M
Mr.doob 已提交
4251 4252 4253
		_this.info.render.calls = 0;
		_this.info.render.vertices = 0;
		_this.info.render.faces = 0;
4254

M
Mr.doob 已提交
4255 4256 4257 4258 4259 4260
		if ( camera.parent === undefined ) {

			console.warn( 'DEPRECATED: Camera hasn\'t been added to a Scene. Adding it...' );
			scene.add( camera );

		}
4261

M
Mr.doob 已提交
4262
		if ( this.autoUpdateScene ) scene.updateMatrixWorld();
A
alteredq 已提交
4263 4264

		camera.matrixWorldInverse.getInverse( camera.matrixWorld );
M
Mr.doob 已提交
4265
		camera.matrixWorldInverse.flattenToArray( _viewMatrixArray );
4266
		camera.projectionMatrix.flattenToArray( _projectionMatrixArray );
M
Mr.doob 已提交
4267

M
Mr.doob 已提交
4268
		_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
M
Mr.doob 已提交
4269
		computeFrustum( _projScreenMatrix );
4270

M
Mr.doob 已提交
4271
		setRenderTarget( renderTarget );
M
Mr.doob 已提交
4272

M
Mr.doob 已提交
4273
		if ( this.autoClear || forceClear ) {
M
Mr.doob 已提交
4274

M
Mr.doob 已提交
4275
			this.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil );
M
Mr.doob 已提交
4276

4277 4278
		}

4279
		// set matrices
4280

4281
		ol = scene.__webglObjects.length;
4282

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

4285 4286
			webglObject = scene.__webglObjects[ o ];
			object = webglObject.object;
M
Mr.doob 已提交
4287

4288
			if ( object.visible ) {
4289

A
alteredq 已提交
4290
				if ( ! ( object instanceof THREE.Mesh ) || ! ( object.frustumCulled ) || isInFrustum( object ) ) {
4291

4292
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
4293

4294
					setupMatrices( object, camera, true );
4295

4296
					unrollBufferMaterial( webglObject );
4297

4298
					webglObject.render = true;
4299

4300
					if ( this.sortObjects ) {
4301

4302
						if ( object.renderDepth ) {
M
Mr.doob 已提交
4303

4304
							webglObject.z = object.renderDepth;
M
Mr.doob 已提交
4305

4306
						} else {
M
Mr.doob 已提交
4307

4308 4309
							_vector3.copy( object.position );
							_projScreenMatrix.multiplyVector3( _vector3 );
M
Mr.doob 已提交
4310

4311
							webglObject.z = _vector3.z;
M
Mr.doob 已提交
4312

4313
						}
4314

4315
					}
4316

4317
				} else {
4318

4319
					webglObject.render = false;
4320

4321
				}
4322

4323
			} else {
4324

4325
				webglObject.render = false;
4326

4327
			}
4328

4329
		}
4330

4331
		if ( this.sortObjects ) {
4332

4333
			scene.__webglObjects.sort( painterSort );
4334

4335
		}
4336

4337
		oil = scene.__webglObjectsImmediate.length;
4338

4339
		for ( o = 0; o < oil; o ++ ) {
4340

4341 4342
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
4343

4344
			if ( object.visible ) {
4345 4346 4347

				if( object.matrixAutoUpdate ) {

4348
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
4349

A
alteredq 已提交
4350
				}
4351

4352
				setupMatrices( object, camera, true );
4353

4354
				unrollImmediateBufferMaterial( webglObject );
4355

4356
			}
4357

4358
		}
A
alteredq 已提交
4359

M
Mr.doob 已提交
4360
		if ( scene.overrideMaterial ) {
4361

M
Mr.doob 已提交
4362 4363
			setDepthTest( scene.overrideMaterial.depthTest );
			setBlending( scene.overrideMaterial.blending );
4364

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

M
Mr.doob 已提交
4367 4368 4369
				webglObject = scene.__webglObjects[ o ];

				if ( webglObject.render ) {
4370

M
Mr.doob 已提交
4371 4372
					object = webglObject.object;
					buffer = webglObject.buffer;
4373

M
Mr.doob 已提交
4374 4375 4376 4377 4378 4379 4380 4381
					setObjectFaces( object );

					renderBuffer( camera, lights, fog, scene.overrideMaterial, buffer, object );

				}

			}

4382
			for ( o = 0; o < oil; o ++ ) {
M
Mr.doob 已提交
4383 4384

				webglObject = scene.__webglObjectsImmediate[ o ];
4385
				object = webglObject.object;
4386

M
Mr.doob 已提交
4387 4388
				if ( object.visible ) {

M
Mr.doob 已提交
4389 4390
					_currentGeometryGroupHash = -1;

M
Mr.doob 已提交
4391 4392 4393
					setObjectFaces( object );

					program = setProgram( camera, lights, fog, scene.overrideMaterial, object );
M
Mr.doob 已提交
4394 4395 4396 4397 4398 4399 4400 4401 4402 4403

					if ( object.immediateRenderCallback ) {

						object.immediateRenderCallback( program, _gl, _frustum );

					} else {

						object.render( function( object ) { renderBufferImmediate( object, program, scene.overrideMaterial.shading ); } );

					}
M
Mr.doob 已提交
4404 4405 4406 4407 4408 4409 4410 4411

				}

			}

		} else {

			// opaque pass
4412
			// (front-to-back order)
M
Mr.doob 已提交
4413 4414 4415

			setBlending( THREE.NormalBlending );

4416
			for ( o = ol - 1; o >= 0; o -- ) {
M
Mr.doob 已提交
4417 4418 4419 4420 4421 4422 4423

				webglObject = scene.__webglObjects[ o ];

				if ( webglObject.render ) {

					object = webglObject.object;
					buffer = webglObject.buffer;
4424
					material = webglObject.opaque;
4425

4426
					if ( ! material ) continue;
4427

4428
					setObjectFaces( object );
4429

4430 4431 4432 4433
					setDepthTest( material.depthTest );
					setDepthWrite( material.depthWrite );
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
					renderBuffer( camera, lights, fog, material, buffer, object );
4434

4435
				}
4436 4437 4438

			}

M
Mr.doob 已提交
4439
			// opaque pass (immediate simulator)
4440

4441
			for ( o = 0; o < oil; o ++ ) {
4442

M
Mr.doob 已提交
4443 4444
				webglObject = scene.__webglObjectsImmediate[ o ];
				object = webglObject.object;
4445

M
Mr.doob 已提交
4446
				if ( object.visible ) {
4447

M
Mr.doob 已提交
4448 4449
					_currentGeometryGroupHash = -1;

4450
					material = webglObject.opaque;
4451

4452
					if ( ! material ) continue;
4453

4454
					setObjectFaces( object );
4455

4456 4457 4458
					setDepthTest( material.depthTest );
					setDepthWrite( material.depthWrite );
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
M
Mr.doob 已提交
4459

4460
					program = setProgram( camera, lights, fog, material, object );
M
Mr.doob 已提交
4461

4462
					if ( object.immediateRenderCallback ) {
M
Mr.doob 已提交
4463

4464
						object.immediateRenderCallback( program, _gl, _frustum );
M
Mr.doob 已提交
4465

4466
					} else {
M
Mr.doob 已提交
4467

4468
						object.render( function( object ) { renderBufferImmediate( object, program, material.shading ); } );
4469

M
Mr.doob 已提交
4470
					}
4471

4472
				}
4473

A
alteredq 已提交
4474
			}
4475

M
Mr.doob 已提交
4476
			// transparent pass
4477
			// (back-to-front order)
A
alteredq 已提交
4478

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

M
Mr.doob 已提交
4481
				webglObject = scene.__webglObjects[ o ];
4482

M
Mr.doob 已提交
4483
				if ( webglObject.render ) {
4484

M
Mr.doob 已提交
4485 4486
					object = webglObject.object;
					buffer = webglObject.buffer;
4487
					material = webglObject.transparent;
4488

4489
					if ( ! material ) continue;
4490

4491
					setObjectFaces( object );
4492

4493 4494 4495 4496
					setBlending( material.blending );
					setDepthTest( material.depthTest );
					setDepthWrite( material.depthWrite );
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
4497

4498
					renderBuffer( camera, lights, fog, material, buffer, object );
4499

4500
				}
4501

4502
			}
M
Mr.doob 已提交
4503

M
Mr.doob 已提交
4504
			// transparent pass (immediate simulator)
M
Mr.doob 已提交
4505

4506
			for ( o = 0; o < oil; o ++ ) {
4507

M
Mr.doob 已提交
4508 4509
				webglObject = scene.__webglObjectsImmediate[ o ];
				object = webglObject.object;
4510

M
Mr.doob 已提交
4511
				if ( object.visible ) {
4512

M
Mr.doob 已提交
4513 4514
					_currentGeometryGroupHash = -1;

4515
					material = webglObject.transparent;
4516

4517
					if ( ! material ) continue;
4518

4519
					setObjectFaces( object );
4520

4521 4522 4523 4524
					setBlending( material.blending );
					setDepthTest( material.depthTest );
					setDepthWrite( material.depthWrite );
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
M
Mr.doob 已提交
4525

4526
					program = setProgram( camera, lights, fog, material, object );
M
Mr.doob 已提交
4527

4528
					if ( object.immediateRenderCallback ) {
M
Mr.doob 已提交
4529

4530
						object.immediateRenderCallback( program, _gl, _frustum );
M
Mr.doob 已提交
4531

4532
					} else {
M
Mr.doob 已提交
4533

4534
						object.render( function( object ) { renderBufferImmediate( object, program, material.shading ); } );
4535

M
Mr.doob 已提交
4536
					}
4537

4538
				}
4539

4540
			}
4541

4542
		}
4543

M
Mikael Emtinger 已提交
4544
		// render 2d
4545

M
Mr.doob 已提交
4546
		if ( scene.__webglSprites.length ) {
4547

4548
			renderSprites( scene, camera );
4549

M
Mikael Emtinger 已提交
4550 4551
		}

M
Mikael Emtinger 已提交
4552 4553 4554 4555 4556 4557 4558 4559
		// Generate mipmap if we're using any kind of mipmap filtering

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

			updateRenderTargetMipmap( renderTarget );

		}

4560
		//_gl.finish();
4561

M
Mikael Emtinger 已提交
4562 4563
	};

4564 4565
	/*
	 * Render sprites
M
Mr.doob 已提交
4566
	 *
4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581
	 */

	function renderSprites( scene, camera ) {

		var o, ol, object;
		var attributes = _sprite.attributes;
		var uniforms = _sprite.uniforms;
		var invAspect = _viewportHeight / _viewportWidth;
		var size, scale = [];
		var screenPosition;
		var halfViewportWidth = _viewportWidth * 0.5;
		var halfViewportHeight = _viewportHeight * 0.5;
		var mergeWith3D = true;

		// setup gl
4582

4583 4584
		_gl.useProgram( _sprite.program );
		_currentProgram = _sprite.program;
4585
		_oldBlending = -1;
M
Mr.doob 已提交
4586 4587
		_oldDepthTest = -1;
		_currentGeometryGroupHash = -1;
4588

M
Mr.doob 已提交
4589
		if ( !_spriteAttributesEnabled ) {
4590

M
Mr.doob 已提交
4591 4592
			_gl.enableVertexAttribArray( _sprite.attributes.position );
			_gl.enableVertexAttribArray( _sprite.attributes.uv );
4593

M
Mr.doob 已提交
4594 4595 4596
			_spriteAttributesEnabled = true;

		}
4597

4598
		_gl.disable( _gl.CULL_FACE );
4599
		_gl.enable( _gl.BLEND );
4600
		_gl.depthMask( true );
4601 4602 4603 4604 4605 4606

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

		_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _sprite.elementBuffer );
4607

4608 4609 4610 4611
		_gl.uniformMatrix4fv( uniforms.projectionMatrix, false, _projectionMatrixArray );

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

4613
		// update positions and sort
4614

M
Mr.doob 已提交
4615
		for( o = 0, ol = scene.__webglSprites.length; o < ol; o ++ ) {
4616

4617
			object = scene.__webglSprites[ o ];
4618

4619
			if ( !object.visible || object.opacity === 0 ) continue;
M
Mr.doob 已提交
4620

4621
			if( !object.useScreenCoordinates ) {
4622

4623 4624
				object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
				object.z = -object._modelViewMatrix.n34;
4625

4626
			} else {
4627

4628
				object.z = -object.position.z;
4629

4630
			}
4631

4632 4633 4634
		}

		scene.__webglSprites.sort( painterSort );
4635

M
Mr.doob 已提交
4636
		// render all sprites
4637

M
Mr.doob 已提交
4638
		for ( o = 0, ol = scene.__webglSprites.length; o < ol; o ++ ) {
4639 4640 4641

			object = scene.__webglSprites[ o ];

4642
			if ( !object.visible || object.opacity === 0 ) continue;
4643

M
Mr.doob 已提交
4644
			if ( object.map && object.map.image && object.map.image.width ) {
4645

M
Mr.doob 已提交
4646
				if ( object.useScreenCoordinates ) {
4647

M
Mr.doob 已提交
4648 4649 4650 4651
					_gl.uniform1i( uniforms.useScreenCoordinates, 1 );
					_gl.uniform3f( uniforms.screenPosition, ( object.position.x - halfViewportWidth  ) / halfViewportWidth,
															( halfViewportHeight - object.position.y ) / halfViewportHeight,
															  Math.max( 0, Math.min( 1, object.position.z )));
4652

M
Mr.doob 已提交
4653
				} else {
4654

M
Mr.doob 已提交
4655 4656 4657
					_gl.uniform1i( uniforms.useScreenCoordinates, 0 );
					_gl.uniform1i( uniforms.affectedByDistance, object.affectedByDistance ? 1 : 0 );
					_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray );
4658

M
Mr.doob 已提交
4659
				}
4660

M
Mr.doob 已提交
4661
				size = object.map.image.width / ( object.scaleByViewport ? _viewportHeight : 1 );
4662

M
Mr.doob 已提交
4663 4664
				scale[ 0 ] = size * invAspect * object.scale.x;
				scale[ 1 ] = size * object.scale.y;
4665

M
Mr.doob 已提交
4666 4667 4668
				_gl.uniform2f( uniforms.uvScale, object.uvScale.x, object.uvScale.y );
				_gl.uniform2f( uniforms.uvOffset, object.uvOffset.x, object.uvOffset.y );
				_gl.uniform2f( uniforms.alignment, object.alignment.x, object.alignment.y );
4669

M
Mr.doob 已提交
4670 4671
				_gl.uniform1f( uniforms.opacity, object.opacity );
				_gl.uniform3f( uniforms.color, object.color.r, object.color.g, object.color.b );
4672

M
Mr.doob 已提交
4673 4674
				_gl.uniform1f( uniforms.rotation, object.rotation );
				_gl.uniform2fv( uniforms.scale, scale );
4675

M
Mr.doob 已提交
4676
				if ( object.mergeWith3D && !mergeWith3D ) {
4677

M
Mr.doob 已提交
4678 4679
					_gl.enable( _gl.DEPTH_TEST );
					mergeWith3D = true;
4680

M
Mr.doob 已提交
4681
				} else if ( !object.mergeWith3D && mergeWith3D ) {
4682

M
Mr.doob 已提交
4683 4684
					_gl.disable( _gl.DEPTH_TEST );
					mergeWith3D = false;
4685

4686
				}
4687

M
Mr.doob 已提交
4688 4689
				setBlending( object.blending );
				setTexture( object.map, 0 );
4690

M
Mr.doob 已提交
4691
				_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
4692

4693
			}
4694

4695 4696 4697 4698 4699 4700 4701
		}


		// restore gl

		_gl.enable( _gl.CULL_FACE );
		_gl.enable( _gl.DEPTH_TEST );
M
Mr.doob 已提交
4702
		_gl.depthMask( _oldDepthWrite );
4703 4704 4705

	}

4706
	function setupMatrices( object, camera, computeNormalMatrix ) {
4707

4708
		object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
4709 4710 4711 4712 4713 4714

		if ( computeNormalMatrix ) {

			THREE.Matrix4.makeInvert3x3( object._modelViewMatrix ).transposeIntoArray( object._normalMatrixArray );

		}
4715

M
Mr.doob 已提交
4716
	}
4717

A
alteredq 已提交
4718
	this.initWebGLObjects = function ( scene ) {
4719

4720
		if ( !scene.__webglObjects ) {
4721

4722 4723
			scene.__webglObjects = [];
			scene.__webglObjectsImmediate = [];
M
Mikael Emtinger 已提交
4724
			scene.__webglSprites = [];
4725

4726 4727
		}

M
Mr.doob 已提交
4728
		while ( scene.__objectsAdded.length ) {
4729

M
Mr.doob 已提交
4730 4731
			addObject( scene.__objectsAdded[ 0 ], scene );
			scene.__objectsAdded.splice( 0, 1 );
4732 4733 4734

		}

M
Mr.doob 已提交
4735
		while ( scene.__objectsRemoved.length ) {
4736

M
Mr.doob 已提交
4737 4738
			removeObject( scene.__objectsRemoved[ 0 ], scene );
			scene.__objectsRemoved.splice( 0, 1 );
4739 4740

		}
4741

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

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

4746
			updateObject( scene.__webglObjects[ o ].object );
A
alteredq 已提交
4747 4748

		}
4749

4750
	};
4751

M
Mr.doob 已提交
4752
	function addObject( object, scene ) {
4753

M
Mr.doob 已提交
4754
		var g, geometry, geometryGroup;
4755

M
Mr.doob 已提交
4756
		if ( ! object.__webglInit ) {
4757

M
Mr.doob 已提交
4758
			object.__webglInit = true;
M
Mr.doob 已提交
4759

M
Mr.doob 已提交
4760
			object._modelViewMatrix = new THREE.Matrix4();
A
alteredq 已提交
4761

M
Mr.doob 已提交
4762 4763 4764
			object._normalMatrixArray = new Float32Array( 9 );
			object._modelViewMatrixArray = new Float32Array( 16 );
			object._objectMatrixArray = new Float32Array( 16 );
4765

M
Mr.doob 已提交
4766
			object.matrixWorld.flattenToArray( object._objectMatrixArray );
4767

M
Mr.doob 已提交
4768
			if ( object instanceof THREE.Mesh ) {
4769

M
Mr.doob 已提交
4770
				geometry = object.geometry;
4771

4772
				if ( geometry.geometryGroups === undefined ) {
A
alteredq 已提交
4773

M
Mr.doob 已提交
4774
					sortFacesByMaterial( geometry );
A
alteredq 已提交
4775

M
Mr.doob 已提交
4776
				}
M
Mr.doob 已提交
4777

M
Mr.doob 已提交
4778
				// create separate VBOs per geometry chunk
M
Mr.doob 已提交
4779

M
Mr.doob 已提交
4780
				for ( g in geometry.geometryGroups ) {
M
Mr.doob 已提交
4781

M
Mr.doob 已提交
4782
					geometryGroup = geometry.geometryGroups[ g ];
A
alteredq 已提交
4783

M
Mr.doob 已提交
4784
					// initialise VBO on the first access
M
Mr.doob 已提交
4785

M
Mr.doob 已提交
4786
					if ( ! geometryGroup.__webglVertexBuffer ) {
4787

M
Mr.doob 已提交
4788 4789
						createMeshBuffers( geometryGroup );
						initMeshBuffers( geometryGroup, object );
M
Mr.doob 已提交
4790

M
Mr.doob 已提交
4791 4792 4793 4794 4795 4796 4797
						geometry.__dirtyVertices = true;
						geometry.__dirtyMorphTargets = true;
						geometry.__dirtyElements = true;
						geometry.__dirtyUvs = true;
						geometry.__dirtyNormals = true;
						geometry.__dirtyTangents = true;
						geometry.__dirtyColors = true;
A
alteredq 已提交
4798

M
Mr.doob 已提交
4799
					}
4800

M
Mr.doob 已提交
4801
				}
A
alteredq 已提交
4802

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

M
Mr.doob 已提交
4805
				geometry = object.geometry;
A
alteredq 已提交
4806

M
Mr.doob 已提交
4807
				if( ! geometry.__webglVertexBuffer ) {
A
alteredq 已提交
4808

M
Mr.doob 已提交
4809 4810
					createRibbonBuffers( geometry );
					initRibbonBuffers( geometry );
M
Mr.doob 已提交
4811

M
Mr.doob 已提交
4812 4813
					geometry.__dirtyVertices = true;
					geometry.__dirtyColors = true;
4814

M
Mr.doob 已提交
4815
				}
M
Mr.doob 已提交
4816

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

M
Mr.doob 已提交
4819
				geometry = object.geometry;
M
Mr.doob 已提交
4820

M
Mr.doob 已提交
4821
				if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
4822

M
Mr.doob 已提交
4823
					createLineBuffers( geometry );
A
alteredq 已提交
4824
					initLineBuffers( geometry, object );
A
alteredq 已提交
4825

M
Mr.doob 已提交
4826 4827
					geometry.__dirtyVertices = true;
					geometry.__dirtyColors = true;
A
alteredq 已提交
4828

M
Mr.doob 已提交
4829
				}
A
alteredq 已提交
4830

M
Mr.doob 已提交
4831
			} else if ( object instanceof THREE.ParticleSystem ) {
A
alteredq 已提交
4832

M
Mr.doob 已提交
4833
				geometry = object.geometry;
4834

M
Mr.doob 已提交
4835
				if ( ! geometry.__webglVertexBuffer ) {
4836

M
Mr.doob 已提交
4837 4838
					createParticleBuffers( geometry );
					initParticleBuffers( geometry, object );
M
Mr.doob 已提交
4839

M
Mr.doob 已提交
4840 4841
					geometry.__dirtyVertices = true;
					geometry.__dirtyColors = true;
M
Mr.doob 已提交
4842

M
Mr.doob 已提交
4843
				}
M
Mr.doob 已提交
4844

M
Mr.doob 已提交
4845
			}
M
Mr.doob 已提交
4846

M
Mr.doob 已提交
4847
		}
M
Mr.doob 已提交
4848

M
Mr.doob 已提交
4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867
		if ( ! object.__webglActive ) {

			if ( object instanceof THREE.Mesh ) {

				geometry = object.geometry;

				for ( g in geometry.geometryGroups ) {

					geometryGroup = geometry.geometryGroups[ g ];

					addBuffer( scene.__webglObjects, geometryGroup, object );

				}

			} else if ( object instanceof THREE.Ribbon ||
						object instanceof THREE.Line ||
						object instanceof THREE.ParticleSystem ) {

				geometry = object.geometry;
4868
				addBuffer( scene.__webglObjects, geometry, object );
M
Mr.doob 已提交
4869

M
Mr.doob 已提交
4870
			} else if ( THREE.MarchingCubes !== undefined && object instanceof THREE.MarchingCubes || object.immediateRenderCallback ) {
A
alteredq 已提交
4871

4872
				addBufferImmediate( scene.__webglObjectsImmediate, object );
A
alteredq 已提交
4873

4874
			} else if ( object instanceof THREE.Sprite ) {
4875

4876
				scene.__webglSprites.push( object );
4877

4878
			}
4879

M
Mr.doob 已提交
4880
			object.__webglActive = true;
4881 4882

		}
A
alteredq 已提交
4883 4884 4885

	};

4886
	function areCustomAttributesDirty( material ) {
4887

4888
		for ( var a in material.attributes ) {
4889

4890
			if ( material.attributes[ a ].needsUpdate ) return true;
4891 4892 4893 4894 4895 4896 4897

		}

		return false;

	};

4898
	function clearCustomAttributes( material ) {
4899

4900
		for ( var a in material.attributes ) {
4901

4902
			material.attributes[ a ].needsUpdate = false;
4903 4904 4905 4906 4907

		}

	};

4908
	function updateObject( object ) {
A
alteredq 已提交
4909

4910 4911
		var geometry = object.geometry,
			geometryGroup, customAttributesDirty, material;
A
alteredq 已提交
4912 4913 4914 4915 4916

		if ( object instanceof THREE.Mesh ) {

			// check all geometry groups

4917
			for( var i = 0, il = geometry.geometryGroupsList.length; i < il; i ++ ) {
A
alteredq 已提交
4918

4919
				geometryGroup = geometry.geometryGroupsList[ i ];
A
alteredq 已提交
4920

4921 4922 4923
				material = getBufferMaterial( object, geometryGroup );

				customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
4924

4925
				if ( geometry.__dirtyVertices || geometry.__dirtyMorphTargets || geometry.__dirtyElements ||
4926
					 geometry.__dirtyUvs || geometry.__dirtyNormals ||
4927
					 geometry.__dirtyColors || geometry.__dirtyTangents || customAttributesDirty ) {
A
alteredq 已提交
4928

4929
					setMeshBuffers( geometryGroup, object, _gl.DYNAMIC_DRAW, !geometry.dynamic );
A
alteredq 已提交
4930 4931 4932 4933 4934

				}

			}

4935
			geometry.__dirtyVertices = false;
4936
			geometry.__dirtyMorphTargets = false;
A
alteredq 已提交
4937 4938 4939
			geometry.__dirtyElements = false;
			geometry.__dirtyUvs = false;
			geometry.__dirtyNormals = false;
4940
			geometry.__dirtyColors = false;
4941
			geometry.__dirtyTangents = false;
M
Mr.doob 已提交
4942

4943
			material.attributes && clearCustomAttributes( material );
4944

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

4947
			if ( geometry.__dirtyVertices || geometry.__dirtyColors ) {
M
Mr.doob 已提交
4948

A
alteredq 已提交
4949
				setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
4950

A
alteredq 已提交
4951 4952 4953 4954 4955 4956 4957
			}

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

		} else if ( object instanceof THREE.Line ) {

A
alteredq 已提交
4958 4959 4960 4961 4962
			material = getBufferMaterial( object, geometryGroup );

			customAttributesDirty = material.attributes && areCustomAttributesDirty( material );

			if ( geometry.__dirtyVertices ||  geometry.__dirtyColors || customAttributesDirty ) {
A
alteredq 已提交
4963 4964

				setLineBuffers( geometry, _gl.DYNAMIC_DRAW );
4965

4966
			}
4967

A
alteredq 已提交
4968 4969 4970
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;

A
alteredq 已提交
4971 4972
			material.attributes && clearCustomAttributes( material );

A
alteredq 已提交
4973 4974
		} else if ( object instanceof THREE.ParticleSystem ) {

4975
			material = getBufferMaterial( object, geometryGroup );
A
alteredq 已提交
4976

4977
			customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
4978

4979
			if ( geometry.__dirtyVertices || geometry.__dirtyColors || object.sortParticles || customAttributesDirty ) {
M
Mr.doob 已提交
4980

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

4983
			}
M
Mr.doob 已提交
4984

4985 4986
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
M
Mr.doob 已提交
4987

4988
			material.attributes && clearCustomAttributes( material );
4989

M
Mr.doob 已提交
4990
		}
4991

4992
	};
4993

4994
	function removeInstances( objlist, object ) {
M
Mr.doob 已提交
4995

4996
		for ( var o = objlist.length - 1; o >= 0; o -- ) {
M
Mr.doob 已提交
4997

4998
			if ( objlist[ o ].object === object ) {
4999

5000
				objlist.splice( o, 1 );
5001

5002
			}
5003

5004
		}
M
Mr.doob 已提交
5005

5006
	};
5007

5008 5009
	function removeInstancesDirect( objlist, object ) {

5010
		for ( var o = objlist.length - 1; o >= 0; o -- ) {
5011

5012
			if ( objlist[ o ] === object ) {
5013 5014 5015 5016 5017 5018 5019 5020 5021

				objlist.splice( o, 1 );

			}

		}

	};

5022
	function removeObject( object, scene ) {
5023

M
Mr.doob 已提交
5024
		if ( object instanceof THREE.Mesh  ||
5025 5026
			 object instanceof THREE.ParticleSystem ||
			 object instanceof THREE.Ribbon ||
5027
			 object instanceof THREE.Line ) {
5028

5029
			removeInstances( scene.__webglObjects, object );
5030

5031
		} else if ( object instanceof THREE.Sprite ) {
M
Mr.doob 已提交
5032

5033
			removeInstancesDirect( scene.__webglSprites, object );
M
Mr.doob 已提交
5034

M
Mr.doob 已提交
5035
		} else if ( object instanceof THREE.MarchingCubes || object.immediateRenderCallback ) {
5036

5037 5038 5039
			removeInstances( scene.__webglObjectsImmediate, object );

		}
M
Mr.doob 已提交
5040

M
Mr.doob 已提交
5041 5042
		object.__webglActive = false;

M
Mr.doob 已提交
5043 5044
	};

5045
	function sortFacesByMaterial( geometry ) {
5046

5047 5048 5049
		var f, fl, face, materialIndex, vertices,
			materialHash, groupHash,
			hash_map = {};
5050

5051
		var numMorphTargets = geometry.morphTargets.length;
5052 5053 5054

		geometry.geometryGroups = {};

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

			face = geometry.faces[ f ];
5058
			materialIndex = face.materialIndex;
5059

5060
			materialHash = ( materialIndex !== undefined ) ? materialIndex : -1;
5061

5062
			if ( hash_map[ materialHash ] === undefined ) {
5063

5064
				hash_map[ materialHash ] = { 'hash': materialHash, 'counter': 0 };
5065 5066 5067

			}

5068
			groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
5069

5070
			if ( geometry.geometryGroups[ groupHash ] === undefined ) {
5071

5072
				geometry.geometryGroups[ groupHash ] = { 'faces3': [], 'faces4': [], 'materialIndex': materialIndex, 'vertices': 0, 'numMorphTargets': numMorphTargets };
5073 5074 5075 5076 5077

			}

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

5078
			if ( geometry.geometryGroups[ groupHash ].vertices + vertices > 65535 ) {
5079

5080 5081
				hash_map[ materialHash ].counter += 1;
				groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
5082

5083
				if ( geometry.geometryGroups[ groupHash ] === undefined ) {
5084

5085
					geometry.geometryGroups[ groupHash ] = { 'faces3': [], 'faces4': [], 'materialIndex': materialIndex, 'vertices': 0, 'numMorphTargets': numMorphTargets };
5086 5087 5088 5089 5090

				}

			}

5091 5092 5093 5094 5095 5096 5097 5098 5099 5100
			if ( face instanceof THREE.Face3 ) {

				geometry.geometryGroups[ groupHash ].faces3.push( f );

			} else {

				geometry.geometryGroups[ groupHash ].faces4.push( f );

			}

5101
			geometry.geometryGroups[ groupHash ].vertices += vertices;
5102 5103 5104

		}

5105 5106 5107 5108
		geometry.geometryGroupsList = [];

		for ( var g in geometry.geometryGroups ) {

M
Mr.doob 已提交
5109 5110
			geometry.geometryGroups[ g ].id = _geometryGroupCounter ++;

5111 5112 5113 5114
			geometry.geometryGroupsList.push( geometry.geometryGroups[ g ] );

		}

5115 5116
	};

5117
	function addBuffer( objlist, buffer, object ) {
5118

5119 5120 5121 5122 5123 5124 5125 5126
		objlist.push(
			{
				buffer: buffer,
				object: object,
				opaque: null,
				transparent: null
			}
		);
M
Mr.doob 已提交
5127

5128
	};
5129

5130
	function addBufferImmediate( objlist, object ) {
5131

5132 5133 5134 5135 5136 5137 5138
		objlist.push(
			{
				object: object,
				opaque: null,
				transparent: null
			}
		);
5139

5140
	};
5141

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

5144
		if ( cullFace ) {
M
Mr.doob 已提交
5145

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

5148
				_gl.frontFace( _gl.CCW );
M
Mr.doob 已提交
5149

5150
			} else {
M
Mr.doob 已提交
5151

5152
				_gl.frontFace( _gl.CW );
M
Mr.doob 已提交
5153

5154
			}
M
Mr.doob 已提交
5155

5156
			if( cullFace === "back" ) {
M
Mr.doob 已提交
5157

5158
				_gl.cullFace( _gl.BACK );
M
Mr.doob 已提交
5159

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

5162
				_gl.cullFace( _gl.FRONT );
M
Mr.doob 已提交
5163

5164
			} else {
M
Mr.doob 已提交
5165

5166
				_gl.cullFace( _gl.FRONT_AND_BACK );
M
Mr.doob 已提交
5167

5168
			}
M
Mr.doob 已提交
5169

5170
			_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
5171

5172
		} else {
M
Mr.doob 已提交
5173

5174
			_gl.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
5175

5176 5177 5178
		}

	};
N
Nicolas Garcia Belmonte 已提交
5179

5180
	this.supportsVertexTextures = function () {
5181

A
alteredq 已提交
5182
		return _supportsVertexTextures;
5183

5184
	};
5185

5186
	function maxVertexTextures() {
5187

5188 5189 5190
		return _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );

	};
5191

5192
	function buildProgram( shaderID, fragmentShader, vertexShader, uniforms, attributes, parameters ) {
5193

5194
		var p, pl, program, code;
5195
		var chunks = [];
5196 5197 5198

		// Generate code

5199 5200 5201 5202 5203 5204 5205 5206 5207 5208
		if ( shaderID ) {

			chunks.push( shaderID );

		} else {

			chunks.push( fragmentShader );
			chunks.push( vertexShader );

		}
5209 5210 5211

		for ( p in parameters ) {

5212 5213
			chunks.push( p );
			chunks.push( parameters[ p ] );
5214 5215 5216

		}

5217 5218
		code = chunks.join();

5219 5220 5221 5222
		// Check if code has been already compiled

		for ( p = 0, pl = _programs.length; p < pl; p ++ ) {

5223
			if ( _programs[ p ].code === code ) {
5224 5225

				// console.log( "Code already compiled." /*: \n\n" + code*/ );
5226

5227 5228 5229 5230 5231
				return _programs[ p ].program;

			}

		}
5232

5233
		//console.log( "building new program " );
5234 5235 5236

		//

5237
		program = _gl.createProgram();
M
Mr.doob 已提交
5238

5239
		var prefix_vertex = [
M
Mr.doob 已提交
5240

A
alteredq 已提交
5241
			_supportsVertexTextures ? "#define VERTEX_TEXTURES" : "",
5242

5243 5244 5245 5246
			_this.gammaInput ? "#define GAMMA_INPUT" : "",
			_this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
			_this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",

5247 5248 5249
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

5250 5251
			"#define MAX_SHADOWS " + parameters.maxShadows,

5252 5253
			"#define MAX_BONES " + parameters.maxBones,

5254
			parameters.map ? "#define USE_MAP" : "",
5255 5256 5257
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
5258
			parameters.skinning ? "#define USE_SKINNING" : "",
5259
			parameters.morphTargets ? "#define USE_MORPHTARGETS" : "",
A
alteredq 已提交
5260
			parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",
5261

5262
			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
5263
			parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
5264

5265 5266
			parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",

M
Mr.doob 已提交
5267 5268 5269
			"uniform mat4 objectMatrix;",
			"uniform mat4 modelViewMatrix;",
			"uniform mat4 projectionMatrix;",
5270 5271
			"uniform mat4 viewMatrix;",
			"uniform mat3 normalMatrix;",
M
Mr.doob 已提交
5272
			"uniform vec3 cameraPosition;",
A
alteredq 已提交
5273 5274 5275

			"uniform mat4 cameraInverseMatrix;",

M
Mr.doob 已提交
5276 5277 5278
			"attribute vec3 position;",
			"attribute vec3 normal;",
			"attribute vec2 uv;",
5279
			"attribute vec2 uv2;",
5280

5281
			"#ifdef USE_COLOR",
5282

5283
				"attribute vec3 color;",
5284

5285 5286
			"#endif",

5287
			"#ifdef USE_MORPHTARGETS",
5288

5289 5290 5291 5292 5293 5294 5295 5296
				"attribute vec3 morphTarget0;",
				"attribute vec3 morphTarget1;",
				"attribute vec3 morphTarget2;",
				"attribute vec3 morphTarget3;",
				"attribute vec3 morphTarget4;",
				"attribute vec3 morphTarget5;",
				"attribute vec3 morphTarget6;",
				"attribute vec3 morphTarget7;",
5297

5298 5299 5300
			"#endif",

			"#ifdef USE_SKINNING",
5301

5302 5303 5304 5305
				"attribute vec4 skinVertexA;",
				"attribute vec4 skinVertexB;",
				"attribute vec4 skinIndex;",
				"attribute vec4 skinWeight;",
5306

5307
			"#endif",
5308

M
Mr.doob 已提交
5309
			""
A
alteredq 已提交
5310

M
Mr.doob 已提交
5311
		].join("\n");
5312

M
Mr.doob 已提交
5313 5314 5315 5316 5317 5318 5319 5320 5321
		var prefix_fragment = [

			"#ifdef GL_ES",
			"precision highp float;",
			"#endif",

			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

5322 5323
			"#define MAX_SHADOWS " + parameters.maxShadows,

5324 5325
			parameters.alphaTest ? "#define ALPHATEST " + parameters.alphaTest: "",

5326 5327 5328 5329
			_this.gammaInput ? "#define GAMMA_INPUT" : "",
			_this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
			_this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",

M
Mr.doob 已提交
5330 5331
			( parameters.useFog && parameters.fog ) ? "#define USE_FOG" : "",
			( parameters.useFog && parameters.fog instanceof THREE.FogExp2 ) ? "#define FOG_EXP2" : "",
M
Mr.doob 已提交
5332 5333 5334 5335 5336

			parameters.map ? "#define USE_MAP" : "",
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
5337

5338 5339 5340
			parameters.metal ? "#define METAL" : "",
			parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",

5341
			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
5342 5343 5344
			parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
			parameters.shadowMapSoft ? "#define SHADOWMAP_WIDTH " + parameters.shadowMapWidth.toFixed( 1 ) : "",
			parameters.shadowMapSoft ? "#define SHADOWMAP_HEIGHT " + parameters.shadowMapHeight.toFixed( 1 ) : "",
M
Mr.doob 已提交
5345 5346 5347 5348 5349 5350 5351

			"uniform mat4 viewMatrix;",
			"uniform vec3 cameraPosition;",
			""

		].join("\n");

5352 5353
		_gl.attachShader( program, getShader( "fragment", prefix_fragment + fragmentShader ) );
		_gl.attachShader( program, getShader( "vertex", prefix_vertex + vertexShader ) );
M
Mr.doob 已提交
5354

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

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

5359
			console.error( "Could not initialise shader\n" + "VALIDATE_STATUS: " + _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) + ", gl error [" + _gl.getError() + "]" );
M
Mr.doob 已提交
5360

N
Nicolas Garcia Belmonte 已提交
5361
		}
5362

5363 5364
		//console.log( prefix_fragment + fragmentShader );
		//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
5365

M
Mr.doob 已提交
5366
		program.uniforms = {};
5367
		program.attributes = {};
M
Mr.doob 已提交
5368

5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386
		var identifiers, u, a, i;

		// cache uniform locations

		identifiers = [

			'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition',
			'cameraInverseMatrix', 'boneGlobalMatrices', 'morphTargetInfluences'

		];

		for ( u in uniforms ) {

			identifiers.push( u );

		}

		cacheUniformLocations( program, identifiers );
5387

5388 5389 5390 5391 5392 5393 5394 5395 5396
		// cache attributes locations

		identifiers = [

			"position", "normal", "uv", "uv2", "tangent", "color",
			"skinVertexA", "skinVertexB", "skinIndex", "skinWeight"

		];

5397
		for ( i = 0; i < parameters.maxMorphTargets; i ++ ) {
5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410

			identifiers.push( "morphTarget" + i );

		}

		for ( a in attributes ) {

			identifiers.push( a );

		}

		cacheAttributeLocations( program, identifiers );

M
Mr.doob 已提交
5411 5412
		program.id = _programs.length;

5413 5414
		_programs.push( { program: program, code: code } );

M
Mr.doob 已提交
5415 5416
		_this.info.memory.programs = _programs.length;

M
Mr.doob 已提交
5417
		return program;
M
Mr.doob 已提交
5418

M
Mr.doob 已提交
5419
	};
M
Mr.doob 已提交
5420

5421
	function loadUniformsSkinning( uniforms, object ) {
5422

M
Mr.doob 已提交
5423
		_gl.uniformMatrix4fv( uniforms.cameraInverseMatrix, false, _viewMatrixArray );
A
alteredq 已提交
5424
		_gl.uniformMatrix4fv( uniforms.boneGlobalMatrices, false, object.boneMatrices );
5425

5426
	};
5427

5428

5429
	function loadUniformsMatrices( uniforms, object ) {
5430

A
alteredq 已提交
5431
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray );
A
alteredq 已提交
5432 5433 5434 5435 5436 5437

		if ( uniforms.normalMatrix ) {

			_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrixArray );

		}
A
alteredq 已提交
5438 5439

	};
5440

5441
	function loadUniformsGeneric( program, uniforms ) {
M
Mr.doob 已提交
5442

M
Mr.doob 已提交
5443
		var uniform, value, type, location, texture, i, il, j, jl, offset;
M
Mr.doob 已提交
5444

M
Mr.doob 已提交
5445
		for( j = 0, jl = uniforms.length; j < jl; j ++ ) {
M
Mr.doob 已提交
5446

M
Mr.doob 已提交
5447
			location = program.uniforms[ uniforms[ j ][ 1 ] ];
5448
			if ( !location ) continue;
M
Mr.doob 已提交
5449

M
Mr.doob 已提交
5450
			uniform = uniforms[ j ][ 0 ];
M
Mr.doob 已提交
5451

5452 5453
			type = uniform.type;
			value = uniform.value;
M
Mr.doob 已提交
5454

5455 5456
			// single integer

5457
			if( type === "i" ) {
M
Mr.doob 已提交
5458

M
Mr.doob 已提交
5459
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
5460

5461 5462
			// single float

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

M
Mr.doob 已提交
5465
				_gl.uniform1f( location, value );
5466

5467 5468
			// single THREE.Vector2

5469
			} else if( type === "v2" ) {
5470 5471 5472 5473 5474

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

			// single THREE.Vector3

5475
			} else if( type === "v3" ) {
5476 5477 5478 5479 5480

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

			// single THREE.Vector4

5481
			} else if( type === "v4" ) {
5482 5483 5484 5485 5486

				_gl.uniform4f( location, value.x, value.y, value.z, value.w );

			// single THREE.Color

5487
			} else if( type === "c" ) {
5488 5489 5490 5491 5492

				_gl.uniform3f( location, value.r, value.g, value.b );

			// flat array of floats (JS or typed array)

5493
			} else if( type === "fv1" ) {
A
alteredq 已提交
5494 5495

				_gl.uniform1fv( location, value );
M
Mr.doob 已提交
5496

5497 5498
			// flat array of floats with 3 x N size (JS or typed array)

5499
			} else if( type === "fv" ) {
5500 5501 5502

				_gl.uniform3fv( location, value );

5503
			// array of THREE.Vector3
5504

5505
			} else if( type === "v3v" ) {
5506

5507
				if ( ! uniform._array ) {
5508

5509
					uniform._array = new Float32Array( 3 * value.length );
5510

5511
				}
5512

5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 5523 5524 5525
				for ( i = 0, il = value.length; i < il; i ++ ) {

					offset = i * 3;

					uniform._array[ offset ] 	 = value[ i ].x;
					uniform._array[ offset + 1 ] = value[ i ].y;
					uniform._array[ offset + 2 ] = value[ i ].z;

				}

				_gl.uniform3fv( location, uniform._array );

			// single THREE.Matrix4
5526

5527
			} else if( type === "m4" ) {
5528 5529 5530 5531 5532 5533 5534 5535 5536 5537

				if ( ! uniform._array ) {

					uniform._array = new Float32Array( 16 );

				}

				value.flattenToArray( uniform._array );
				_gl.uniformMatrix4fv( location, false, uniform._array );

5538 5539
			// array of THREE.Matrix4

5540
			} else if( type === "m4v" ) {
5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552 5553 5554 5555

				if ( ! uniform._array ) {

					uniform._array = new Float32Array( 16 * value.length );

				}

				for ( i = 0, il = value.length; i < il; i ++ ) {

					value[ i ].flattenToArrayOffset( uniform._array, i * 16 );

				}

				_gl.uniformMatrix4fv( location, false, uniform._array );

5556

5557
			// single THREE.Texture (2d or cube)
M
Mr.doob 已提交
5558

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

M
Mr.doob 已提交
5561
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
5562

5563
				texture = uniform.texture;
M
Mr.doob 已提交
5564

5565
				if ( !texture ) continue;
M
Mr.doob 已提交
5566

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

5569
					setCubeTexture( texture, value );
M
Mr.doob 已提交
5570

A
alteredq 已提交
5571 5572 5573 5574
				} else if ( texture instanceof THREE.WebGLRenderTargetCube ) {

					setCubeTextureDynamic( texture, value );

5575
				} else {
M
Mr.doob 已提交
5576

5577
					setTexture( texture, value );
M
Mr.doob 已提交
5578

5579
				}
M
Mr.doob 已提交
5580

5581 5582
			// array of THREE.Texture (2d)

5583
			} else if( type === "tv" ) {
5584 5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608

				if ( ! uniform._array ) {

					uniform._array = [];

					for( i = 0, il = uniform.texture.length; i < il; i ++ ) {

						uniform._array[ i ] = value + i;

					}

				}

				_gl.uniform1iv( location, uniform._array );

				for( i = 0, il = uniform.texture.length; i < il; i ++ ) {

					texture = uniform.texture[ i ];

					if ( !texture ) continue;

					setTexture( texture, uniform._array[ i ] );

				}

5609
			}
M
Mr.doob 已提交
5610

5611
		}
M
Mr.doob 已提交
5612

5613
	};
M
Mr.doob 已提交
5614

5615
	function setBlending( blending ) {
A
alteredq 已提交
5616

5617
		if ( blending !== _oldBlending ) {
5618

A
alteredq 已提交
5619 5620 5621 5622 5623
			switch ( blending ) {

				case THREE.AdditiveBlending:

					_gl.blendEquation( _gl.FUNC_ADD );
5624
					_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE );
A
alteredq 已提交
5625 5626 5627 5628 5629

					break;

				case THREE.SubtractiveBlending:

5630 5631 5632 5633
					// TODO: Find blendFuncSeparate() combination

					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.ZERO, _gl.ONE_MINUS_SRC_COLOR );
A
alteredq 已提交
5634 5635 5636

					break;

5637 5638 5639
				case THREE.MultiplyBlending:

					// TODO: Find blendFuncSeparate() combination
A
alteredq 已提交
5640 5641

					_gl.blendEquation( _gl.FUNC_ADD );
5642
					_gl.blendFunc( _gl.ZERO, _gl.SRC_COLOR );
A
alteredq 已提交
5643 5644 5645 5646 5647

					break;

				default:

5648 5649
					_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 已提交
5650 5651

					break;
5652

A
alteredq 已提交
5653
			}
5654

A
alteredq 已提交
5655
			_oldBlending = blending;
5656

A
alteredq 已提交
5657 5658 5659
		}

	};
5660

5661
	function setTextureParameters( textureType, texture, image ) {
5662

5663
		if ( isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ) ) {
M
Mr.doob 已提交
5664

5665 5666
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
M
Mr.doob 已提交
5667

5668 5669
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
M
Mr.doob 已提交
5670

5671
			_gl.generateMipmap( textureType );
M
Mr.doob 已提交
5672

5673
		} else {
M
Mr.doob 已提交
5674

5675 5676
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
5677

5678 5679
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
M
Mr.doob 已提交
5680

5681
		}
M
Mr.doob 已提交
5682

5683
	};
5684

5685
	function setTexture( texture, slot ) {
5686

5687
		if ( texture.needsUpdate ) {
A
alteredq 已提交
5688

5689
			if ( ! texture.__webglInit ) {
M
Mr.doob 已提交
5690

5691
				texture.__webglInit = true;
5692
				texture.__webglTexture = _gl.createTexture();
A
alteredq 已提交
5693

M
Mr.doob 已提交
5694 5695
				_this.info.memory.textures ++;

5696
			}
M
Mr.doob 已提交
5697

5698
			_gl.activeTexture( _gl.TEXTURE0 + slot );
5699 5700
			_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );

5701
			if ( texture instanceof THREE.DataTexture ) {
5702 5703

				_gl.texImage2D( _gl.TEXTURE_2D, 0, paramThreeToGL( texture.format ), texture.image.width, texture.image.height, 0, paramThreeToGL( texture.format ), _gl.UNSIGNED_BYTE, texture.image.data );
M
Mr.doob 已提交
5704

A
alteredq 已提交
5705
			} else {
M
Mr.doob 已提交
5706

M
Mr.doob 已提交
5707
				_gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image );
M
Mr.doob 已提交
5708 5709 5710

			}

5711
			setTextureParameters( _gl.TEXTURE_2D, texture, texture.image );
M
Mr.doob 已提交
5712

A
alteredq 已提交
5713
			texture.needsUpdate = false;
5714

5715
		} else {
5716

5717 5718
			_gl.activeTexture( _gl.TEXTURE0 + slot );
			_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
5719 5720

		}
M
Mr.doob 已提交
5721

5722
	};
M
Mr.doob 已提交
5723

5724
	function setCubeTexture( texture, slot ) {
5725

5726
		if ( texture.image.length === 6 ) {
5727 5728 5729

			if ( texture.needsUpdate ) {

A
alteredq 已提交
5730
				if ( ! texture.image.__webglTextureCube ) {
5731 5732

					texture.image.__webglTextureCube = _gl.createTexture();
5733

A
alteredq 已提交
5734
				}
5735

A
alteredq 已提交
5736 5737
				_gl.activeTexture( _gl.TEXTURE0 + slot );
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
5738

A
alteredq 已提交
5739
				for ( var i = 0; i < 6; i ++ ) {
5740

A
alteredq 已提交
5741
					_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image[ i ] );
5742

A
alteredq 已提交
5743
				}
5744

A
alteredq 已提交
5745
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, texture.image[ 0 ] );
5746

A
alteredq 已提交
5747
				texture.needsUpdate = false;
5748

A
alteredq 已提交
5749
			} else {
5750

A
alteredq 已提交
5751 5752
				_gl.activeTexture( _gl.TEXTURE0 + slot );
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
5753

A
alteredq 已提交
5754
			}
5755

A
alteredq 已提交
5756
		}
5757

A
alteredq 已提交
5758
	};
5759

A
alteredq 已提交
5760
	function setCubeTextureDynamic( texture, slot ) {
5761

A
alteredq 已提交
5762 5763
		_gl.activeTexture( _gl.TEXTURE0 + slot );
		_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.__webglTexture );
5764 5765 5766

	};

5767
	function setupFrameBuffer( framebuffer, renderTarget, textureTarget ) {
5768

5769 5770
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
		_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureTarget, renderTarget.__webglTexture, 0 );
A
alteredq 已提交
5771

5772
	};
M
Mr.doob 已提交
5773

5774
	function setupRenderBuffer( renderbuffer, renderTarget  ) {
M
Mikael Emtinger 已提交
5775

5776
		_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );
5777

5778
		if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
M
Mr.doob 已提交
5779

5780 5781
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
A
alteredq 已提交
5782

5783 5784
		/* For some reason this is not working. Defaulting to RGBA4.
		} else if( ! renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
A
alteredq 已提交
5785

5786 5787 5788 5789
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.STENCIL_INDEX8, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
		*/
		} else if( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
A
alteredq 已提交
5790

5791 5792
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
A
alteredq 已提交
5793

5794
		} else {
A
alteredq 已提交
5795

5796
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );
A
alteredq 已提交
5797

5798
		}
A
alteredq 已提交
5799

5800
	};
A
alteredq 已提交
5801

5802
	function setRenderTarget( renderTarget ) {
A
alteredq 已提交
5803

5804
		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
A
alteredq 已提交
5805

5806
		if ( renderTarget && ! renderTarget.__webglFramebuffer ) {
A
alteredq 已提交
5807

5808 5809
			if( renderTarget.depthBuffer === undefined ) renderTarget.depthBuffer = true;
			if( renderTarget.stencilBuffer === undefined ) renderTarget.stencilBuffer = true;
A
alteredq 已提交
5810

5811
			renderTarget.__webglTexture = _gl.createTexture();
A
alteredq 已提交
5812

5813
			// Setup texture, create render and frame buffers
5814

5815
			if ( isCube ) {
M
Mr.doob 已提交
5816

5817 5818
				renderTarget.__webglFramebuffer = [];
				renderTarget.__webglRenderbuffer = [];
M
Mikael Emtinger 已提交
5819

5820 5821
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, renderTarget.__webglTexture );
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget, renderTarget );
A
alteredq 已提交
5822

5823
				for ( var i = 0; i < 6; i ++ ) {
A
alteredq 已提交
5824

5825 5826
					renderTarget.__webglFramebuffer[ i ] = _gl.createFramebuffer();
					renderTarget.__webglRenderbuffer[ i ] = _gl.createRenderbuffer();
A
alteredq 已提交
5827

5828
					_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, paramThreeToGL( renderTarget.format ), renderTarget.width, renderTarget.height, 0, paramThreeToGL( renderTarget.format ), paramThreeToGL( renderTarget.type ), null );
A
alteredq 已提交
5829

5830
					setupFrameBuffer( renderTarget.__webglFramebuffer[ i ], renderTarget, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
A
alteredq 已提交
5831

5832
					setupRenderBuffer( renderTarget.__webglRenderbuffer[ i ], renderTarget );
A
alteredq 已提交
5833

5834
				}
5835

5836
			} else {
5837

5838 5839
				renderTarget.__webglFramebuffer = _gl.createFramebuffer();
				renderTarget.__webglRenderbuffer = _gl.createRenderbuffer();
5840

5841 5842
				_gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
				setTextureParameters( _gl.TEXTURE_2D, renderTarget, renderTarget );
5843

5844
				_gl.texImage2D( _gl.TEXTURE_2D, 0, paramThreeToGL( renderTarget.format ), renderTarget.width, renderTarget.height, 0, paramThreeToGL( renderTarget.format ), paramThreeToGL( renderTarget.type ), null );
5845

5846
				setupFrameBuffer( renderTarget.__webglFramebuffer, renderTarget, _gl.TEXTURE_2D );
5847

5848
				_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderTarget.__webglRenderbuffer );
5849

5850
				setupRenderBuffer( renderTarget.__webglRenderbuffer, renderTarget );
5851

M
Mikael Emtinger 已提交
5852
			}
5853

5854
			// Release everything
M
Mr.doob 已提交
5855

A
alteredq 已提交
5856 5857 5858 5859 5860 5861 5862 5863 5864 5865
			if ( isCube ) {

				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );

			} else {

				_gl.bindTexture( _gl.TEXTURE_2D, null );

			}

5866 5867
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
M
Mr.doob 已提交
5868

5869 5870
		}

5871
		var framebuffer, width, height, vx, vy;
M
Mr.doob 已提交
5872

5873
		if ( renderTarget ) {
M
Mr.doob 已提交
5874

A
alteredq 已提交
5875 5876
			if ( isCube ) {

5877
				framebuffer = renderTarget.__webglFramebuffer[ renderTarget.activeCubeFace ];
A
alteredq 已提交
5878 5879 5880

			} else {

5881
				framebuffer = renderTarget.__webglFramebuffer;
A
alteredq 已提交
5882 5883 5884

			}

5885 5886
			width = renderTarget.width;
			height = renderTarget.height;
M
Mr.doob 已提交
5887

5888 5889 5890
			vx = 0;
			vy = 0;

5891
		} else {
M
Mr.doob 已提交
5892

5893
			framebuffer = null;
5894

5895 5896
			width = _viewportWidth;
			height = _viewportHeight;
5897

5898 5899
			vx = _viewportX;
			vy = _viewportY;
M
Mr.doob 已提交
5900

5901
		}
M
Mr.doob 已提交
5902

5903
		if ( framebuffer !== _currentFramebuffer ) {
M
Mr.doob 已提交
5904

5905
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
5906
			_gl.viewport( vx, vy, width, height );
M
Mr.doob 已提交
5907

5908
			_currentFramebuffer = framebuffer;
M
Mr.doob 已提交
5909

5910
		}
5911

5912
	};
M
Mr.doob 已提交
5913

5914
	function updateRenderTargetMipmap( renderTarget ) {
M
Mr.doob 已提交
5915

A
alteredq 已提交
5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928
		if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) {

			_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, renderTarget.__webglTexture );
			_gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
			_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );

		} else {

			_gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
			_gl.generateMipmap( _gl.TEXTURE_2D );
			_gl.bindTexture( _gl.TEXTURE_2D, null );

		}
M
Mr.doob 已提交
5929 5930

	};
5931

5932
	function cacheUniformLocations( program, identifiers ) {
M
Mr.doob 已提交
5933

M
Mr.doob 已提交
5934
		var i, l, id;
M
Mr.doob 已提交
5935

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

5938 5939
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
5940

M
Mr.doob 已提交
5941
		}
M
Mr.doob 已提交
5942

M
Mr.doob 已提交
5943
	};
M
Mr.doob 已提交
5944

5945
	function cacheAttributeLocations( program, identifiers ) {
5946

5947
		var i, l, id;
M
Mr.doob 已提交
5948

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

5951 5952
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
M
Mr.doob 已提交
5953

5954
		}
M
Mr.doob 已提交
5955

M
Mr.doob 已提交
5956
	};
M
Mr.doob 已提交
5957

5958
	function getShader( type, string ) {
N
Nicolas Garcia Belmonte 已提交
5959 5960 5961

		var shader;

5962
		if ( type === "fragment" ) {
N
Nicolas Garcia Belmonte 已提交
5963 5964 5965

			shader = _gl.createShader( _gl.FRAGMENT_SHADER );

5966
		} else if ( type === "vertex" ) {
N
Nicolas Garcia Belmonte 已提交
5967 5968 5969 5970 5971 5972 5973 5974 5975 5976

			shader = _gl.createShader( _gl.VERTEX_SHADER );

		}

		_gl.shaderSource( shader, string );
		_gl.compileShader( shader );

		if ( !_gl.getShaderParameter( shader, _gl.COMPILE_STATUS ) ) {

5977
			console.error( _gl.getShaderInfoLog( shader ) );
5978
			console.error( string );
N
Nicolas Garcia Belmonte 已提交
5979 5980 5981 5982 5983
			return null;

		}

		return shader;
M
Mr.doob 已提交
5984

5985
	};
N
Nicolas Garcia Belmonte 已提交
5986

5987
	// fallback filters for non-power-of-2 textures
5988

5989
	function filterFallback( f ) {
5990

5991 5992 5993 5994 5995 5996 5997 5998
		switch ( f ) {

			case THREE.NearestFilter:
			case THREE.NearestMipMapNearestFilter:
			case THREE.NearestMipMapLinearFilter: return _gl.NEAREST; break;

			case THREE.LinearFilter:
			case THREE.LinearMipMapNearestFilter:
M
Mr.doob 已提交
5999
			case THREE.LinearMipMapLinearFilter:
M
Mikael Emtinger 已提交
6000
			default:
6001

M
Mikael Emtinger 已提交
6002
				return _gl.LINEAR; break;
6003 6004

		}
6005

6006
	};
6007 6008

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

6010
		switch ( p ) {
M
Mr.doob 已提交
6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023

			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;

6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037
			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;

6038
		}
M
Mr.doob 已提交
6039

6040
		return 0;
M
Mr.doob 已提交
6041

6042 6043
	};

6044
	function isPowerOfTwo( value ) {
6045

6046
		return ( value & ( value - 1 ) ) === 0;
6047 6048 6049

	};

6050
	function materialNeedsSmoothNormals( material ) {
6051

6052
		return material && material.shading !== undefined && material.shading === THREE.SmoothShading;
6053 6054

	};
6055

6056
	function bufferGuessVertexColorType( material ) {
6057

6058
		if ( material.vertexColors ) {
6059

6060
			return material.vertexColors;
6061

6062
		}
6063

6064
		return false;
6065

6066 6067
	};

6068
	function bufferGuessNormalType( material ) {
6069

6070
		// only MeshBasicMaterial and MeshDepthMaterial don't need normals
6071

6072
		if ( ( material instanceof THREE.MeshBasicMaterial && !material.envMap ) || material instanceof THREE.MeshDepthMaterial ) {
6073

6074
			return false;
6075

6076
		}
6077

6078
		if ( materialNeedsSmoothNormals( material ) ) {
6079

6080
			return THREE.SmoothShading;
6081

6082
		} else {
6083

6084
			return THREE.FlatShading;
6085 6086

		}
6087

6088 6089
	};

6090
	function bufferGuessUVType( material ) {
6091

6092
		// material must use some texture to require uvs
6093

6094
		if ( material.map || material.lightMap || material instanceof THREE.ShaderMaterial ) {
6095

6096
			return true;
6097

6098
		}
6099

6100
		return false;
6101

6102
	};
6103

6104
	function allocateBones( object ) {
6105

6106 6107 6108 6109 6110 6111 6112
		// 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)
6113

6114
		var maxBones = 50;
6115

6116
		if ( object !== undefined && object instanceof THREE.SkinnedMesh ) {
6117

6118 6119 6120 6121 6122
			maxBones = object.bones.length;

		}

		return maxBones;
6123

6124
	};
6125

6126
	function allocateLights( lights ) {
6127

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

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

6133
			light = lights[ l ];
6134

6135 6136 6137
			if ( light instanceof THREE.SpotLight ) dirLights ++; // hack, not a proper spotlight
			if ( light instanceof THREE.DirectionalLight ) dirLights ++;
			if ( light instanceof THREE.PointLight ) pointLights ++;
6138

6139
		}
6140

6141
		if ( ( pointLights + dirLights ) <= _maxLights ) {
6142

6143 6144
			maxDirLights = dirLights;
			maxPointLights = pointLights;
6145

6146
		} else {
6147

6148 6149
			maxDirLights = Math.ceil( _maxLights * dirLights / ( pointLights + dirLights ) );
			maxPointLights = _maxLights - maxDirLights;
6150 6151 6152

		}

6153
		return { 'directional' : maxDirLights, 'point' : maxPointLights };
6154 6155

	};
M
Mr.doob 已提交
6156

6157 6158
	function allocateShadows( lights ) {

M
Mr.doob 已提交
6159
		var l, ll, light, maxShadows = 0;
6160 6161 6162 6163 6164 6165 6166 6167 6168 6169 6170 6171 6172 6173

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

			light = lights[ l ];

			if ( light instanceof THREE.SpotLight && light.castShadow ) maxShadows ++;

		}

		return maxShadows;

	};


A
alteredq 已提交
6174
	/* DEBUG
6175
	function getGLParams() {
M
Mr.doob 已提交
6176

6177
		var params  = {
M
Mr.doob 已提交
6178

6179 6180
			'MAX_VARYING_VECTORS': _gl.getParameter( _gl.MAX_VARYING_VECTORS ),
			'MAX_VERTEX_ATTRIBS': _gl.getParameter( _gl.MAX_VERTEX_ATTRIBS ),
M
Mr.doob 已提交
6181

6182 6183 6184
			'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 已提交
6185

6186 6187 6188
			'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 已提交
6189

6190 6191
		return params;
	};
M
Mr.doob 已提交
6192

6193
	function dumpObject( obj ) {
M
Mr.doob 已提交
6194

6195 6196
		var p, str = "";
		for ( p in obj ) {
M
Mr.doob 已提交
6197

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

6200
		}
M
Mr.doob 已提交
6201

6202 6203
		return str;
	}
A
alteredq 已提交
6204
	*/
6205
};