WebGLRenderer.js 136.6 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,
M
Mikael Emtinger 已提交
32
	_cullEnabled = true,
33

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

39
	// camera matrices caches
40 41

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

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

54
	_vector3 = new THREE.Vector4(),
55

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

A
alteredq 已提交
58 59
	_lights = {

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

	},

66
	// parameters
67

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

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

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

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

			programs: 0,
			geometries: 0,
			textures: 0

		},

		render: {

			calls: 0,
			vertices: 0,
			faces: 0

		}
95

96
	};
M
Mr.doob 已提交
97

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

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

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

108 109 110 111 112 113 114 115
	this.autoUpdateObjects = true;

	// physically based shading

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

116 117 118 119 120 121 122 123 124 125 126
	// 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;

127
	this.shadowMap = [];
128

129
	this.shadowMapEnabled = false;
130
	this.shadowMapAutoUpdate = true;
131
	this.shadowMapSoft = true;
132

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

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

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

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

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

145 146 147 148
	// Init GL

	try {

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

			throw 'Error creating WebGL context.';

		}

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

163 164 165 166 167 168 169 170
	} catch ( error ) {

		console.error( error );

	}

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

	_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 已提交
189

M
Mr.doob 已提交
190
	this.context = _gl;
191

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

M
Mikael Emtinger 已提交
194
	// prepare sprites
M
Mr.doob 已提交
195 196

	var _sprite = {};
M
Mikael Emtinger 已提交
197 198 199 200

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

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

	_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 已提交
214 215

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

M
Mikael Emtinger 已提交
217 218 219 220 221 222 223
	_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 已提交
224
	_gl.bufferData( _gl.ARRAY_BUFFER, _sprite.vertices, _gl.STATIC_DRAW );
M
Mikael Emtinger 已提交
225 226 227 228 229 230

	_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 已提交
231 232
	_gl.attachShader( _sprite.program, getShader( "fragment", THREE.ShaderLib.sprite.fragmentShader ) );
	_gl.attachShader( _sprite.program, getShader( "vertex",   THREE.ShaderLib.sprite.vertexShader   ) );
M
Mikael Emtinger 已提交
233 234 235 236
	_gl.linkProgram( _sprite.program );

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

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

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

244 245 246
	_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 已提交
247 248

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

252 253 254 255 256
	_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 已提交
257

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

M
Mr.doob 已提交
261
	var _spriteAttributesEnabled = false;
M
Mikael Emtinger 已提交
262

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

		_canvas.width = width;
		_canvas.height = height;
267

268 269 270
		this.setViewport( 0, 0, _canvas.width, _canvas.height );

	};
N
Nicolas Garcia Belmonte 已提交
271

272
	this.setViewport = function ( x, y, width, height ) {
273

274 275
		_viewportX = x;
		_viewportY = y;
276

277 278
		_viewportWidth = width;
		_viewportHeight = height;
279

280
		_gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight );
281

N
Nicolas Garcia Belmonte 已提交
282
	};
283

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

286
		_gl.scissor( x, y, width, height );
287

288
	};
289

290
	this.enableScissorTest = function ( enable ) {
291

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

	};
295

296
	this.setClearColorHex = function ( hex, alpha ) {
297

298 299 300 301
		_clearColor.setHex( hex );
		_clearAlpha = alpha;

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

303
	};
A
alteredq 已提交
304

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

307 308 309 310
		_clearColor.copy( color );
		_clearAlpha = alpha;

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

	};
313

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

		return _clearColor;

	};

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

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

	};

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

		var bits = 0;

330 331 332
		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 已提交
333 334

		_gl.clear( bits );
N
Nicolas Garcia Belmonte 已提交
335 336 337

	};

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

		return _gl;

	};

344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 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
	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 ) {

			for ( g in object.geometry.geometryGroups ) {

				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 已提交
387 388
		_this.info.memory.textures --;

389 390 391 392
	};

	//

M
Mr.doob 已提交
393
	function setupLights( program, lights ) {
394

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

399
		zlights = _lights,
M
Mr.doob 已提交
400

401
		dcolors = zlights.directional.colors,
402
		dpositions = zlights.directional.positions,
403

404
		pcolors = zlights.point.colors,
405
		ppositions = zlights.point.positions,
406
		pdistances = zlights.point.distances,
407

408 409
		dlength = 0,
		plength = 0,
410

411 412
		doffset = 0,
		poffset = 0;
M
Mr.doob 已提交
413

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

416
			light = lights[ l ];
417
			color = light.color;
418

419 420
			position = light.position;
			intensity = light.intensity;
421
			distance = light.distance;
422 423 424

			if ( light instanceof THREE.AmbientLight ) {

425 426 427 428 429 430 431 432 433 434 435 436 437
				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 已提交
438

439
			} else if ( light instanceof THREE.DirectionalLight ) {
440

441
				doffset = dlength * 3;
442

443 444 445 446 447 448 449 450 451 452 453 454 455
				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;

				}
456

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

461
				dlength += 1;
M
Mr.doob 已提交
462

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

				doffset = dlength * 3;

467 468 469 470 471 472 473 474 475 476 477 478 479
				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;

				}
480 481 482 483 484 485 486 487 488

				n = 1 / position.length();

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

				dlength += 1;

489 490
			} else if( light instanceof THREE.PointLight ) {

491
				poffset = plength * 3;
492

493 494 495 496 497 498 499 500 501 502 503 504 505
				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;

				}
506

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

511 512
				pdistances[ plength ] = distance;

513
				plength += 1;
M
Mr.doob 已提交
514

515 516 517
			}

		}
518

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

M
Mr.doob 已提交
522 523
		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 已提交
524

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

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

532
	};
M
Mr.doob 已提交
533

534 535 536
	// Buffer allocation

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

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

M
Mr.doob 已提交
541 542
		_this.info.geometries ++;

543
	};
M
Mr.doob 已提交
544

545
	function createLineBuffers( geometry ) {
M
Mr.doob 已提交
546

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

M
Mr.doob 已提交
550 551
		_this.info.memory.geometries ++;

552
	};
553

554
	function createRibbonBuffers( geometry ) {
A
alteredq 已提交
555

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

M
Mr.doob 已提交
559 560
		_this.info.memory.geometries ++;

A
alteredq 已提交
561 562
	};

563
	function createMeshBuffers( geometryGroup ) {
M
Mr.doob 已提交
564

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

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

582
			var m, ml;
583

M
Mr.doob 已提交
584
			geometryGroup.__webglMorphTargetsBuffers = [];
585

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

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

590 591 592
			}

		}
M
Mr.doob 已提交
593

M
Mr.doob 已提交
594 595
		_this.info.memory.geometries ++;

596
	};
597

598 599 600 601 602 603 604
	// Buffer deallocation

	function deleteParticleBuffers( geometry ) {

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

M
Mr.doob 已提交
605 606
		_this.info.memory.geometries --;

607 608 609 610 611 612 613
	};

	function deleteLineBuffers( geometry ) {

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

M
Mr.doob 已提交
614 615
		_this.info.memory.geometries --;

616 617 618 619 620 621 622
	};

	function deleteRibbonBuffers( geometry ) {

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

M
Mr.doob 已提交
623 624
		_this.info.memory.geometries --;

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

	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 ) {

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

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

			}

		}

M
Mr.doob 已提交
654 655
		_this.info.memory.geometries --;

656 657 658 659
	};

	//

660
	function initLineBuffers ( geometry ) {
M
Mr.doob 已提交
661

662 663 664
		var nvertices = geometry.vertices.length;

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

667
		geometry.__webglLineCount = nvertices;
M
Mr.doob 已提交
668

669
	};
M
Mr.doob 已提交
670

671
	function initRibbonBuffers ( geometry ) {
A
alteredq 已提交
672 673 674 675 676 677

		var nvertices = geometry.vertices.length;

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

678
		geometry.__webglVertexCount = nvertices;
A
alteredq 已提交
679 680

	};
681

682
	function initParticleBuffers ( geometry, object ) {
683 684 685 686

		var nvertices = geometry.vertices.length;

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

689
		geometry.__sortArray = [];
690

691
		geometry.__webglParticleCount = nvertices;
692

693 694
		// custom attributes

695
		var material = object.material;
696

697
		if ( material.attributes ) {
698

699
			if ( geometry.__webglCustomAttributesList === undefined ) {
700

701
				geometry.__webglCustomAttributesList = [];
702

703
			}
704

705
			for ( var a in material.attributes ) {
706

707 708
				// Do a shallow copy of the attribute object so different geometryGroup chunks use different
				// attribute buffers which are correctly indexed in the setMeshBuffers function
709

710 711 712
				// Not sure how to best translate this into non-indexed arrays
				// used for particles, as there are no geometry chunks here
				// Probably could be simplified
713

714
				originalAttribute = material.attributes[ a ];
715

716
				attribute = {};
717

718
				for ( property in originalAttribute ) {
719

720
					attribute[ property ] = originalAttribute[ property ];
721

722
				}
723

724
				if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
725

726
					attribute.__webglInitialized = true;
727

728
					size = 1;		// "f" and "i"
729

730 731 732 733
					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;
734

735 736 737 738
					attribute.size = size;
					attribute.array = new Float32Array( nvertices * size );
					attribute.buffer = _gl.createBuffer();
					attribute.buffer.belongsToAttribute = a;
739

740 741
					originalAttribute.needsUpdate = true;
					attribute.__original = originalAttribute;
742

743
				}
744

745
				geometry.__webglCustomAttributesList.push( attribute );
746

747
			}
748

749
		}
750

751
	};
752

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

M
Mikael Emtinger 已提交
769
		var f, fl, fi, face,
770
		m, ml, size,
771 772 773 774 775
		nvertices = 0, ntris = 0, nlines = 0,

		uvType,
		vertexColorType,
		normalType,
776
		material,
777
		attribute, property, originalAttribute,
778 779 780 781

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

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

785 786
			fi = chunk_faces[ f ];
			face = obj_faces[ fi ];
M
Mr.doob 已提交
787

788
			if ( face instanceof THREE.Face3 ) {
M
Mr.doob 已提交
789

790 791 792
				nvertices += 3;
				ntris += 1;
				nlines += 3;
M
Mr.doob 已提交
793

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

796 797
				nvertices += 4;
				ntris += 2;
798
				nlines += 4;
M
Mr.doob 已提交
799

800
			}
M
Mr.doob 已提交
801

802
		}
803

804
		material = getBufferMaterial( object, geometryGroup );
805

806 807 808
		uvType = bufferGuessUVType( material );
		normalType = bufferGuessNormalType( material );
		vertexColorType = bufferGuessVertexColorType( material );
A
alteredq 已提交
809

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

812
		geometryGroup.__vertexArray = new Float32Array( nvertices * 3 );
813

814
		if ( normalType ) {
M
Mr.doob 已提交
815

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

818
		}
819

820
		if ( geometry.hasTangents ) {
821

822
			geometryGroup.__tangentArray = new Float32Array( nvertices * 4 );
823

824
		}
825

826
		if ( vertexColorType ) {
827

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

830
		}
M
Mr.doob 已提交
831

832
		if ( uvType ) {
833

834
			if ( geometry.faceUvs.length > 0 || geometry.faceVertexUvs.length > 0 ) {
835

836 837 838 839 840
				geometryGroup.__uvArray = new Float32Array( nvertices * 2 );

			}

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

842 843 844 845 846 847 848 849 850 851 852 853 854 855 856
				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 );

		}

857
		geometryGroup.__faceArray = new Uint16Array( ntris * 3 );
858
		geometryGroup.__lineArray = new Uint16Array( nlines * 2 );
M
Mr.doob 已提交
859

860 861
		if ( geometryGroup.numMorphTargets ) {

M
Mr.doob 已提交
862
			geometryGroup.__morphTargetsArrays = [];
863

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

866 867
				geometryGroup.__morphTargetsArrays.push( new Float32Array( nvertices * 3 ) );

868 869 870
			}

		}
871

872
		geometryGroup.__needsSmoothNormals = ( normalType === THREE.SmoothShading );
873

874 875 876 877
		geometryGroup.__uvType = uvType;
		geometryGroup.__vertexColorType = vertexColorType;
		geometryGroup.__normalType = normalType;

878
		geometryGroup.__webglFaceCount = ntris * 3;
879
		geometryGroup.__webglLineCount = nlines * 2;
880

M
Mr.doob 已提交
881

882
		// custom attributes
M
Mr.doob 已提交
883

884
		if ( material.attributes ) {
885

886
			if ( geometryGroup.__webglCustomAttributesList === undefined ) {
887

888
				geometryGroup.__webglCustomAttributesList = [];
889

890
			}
891

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

894 895
				// Do a shallow copy of the attribute object so different geometryGroup chunks use different
				// attribute buffers which are correctly indexed in the setMeshBuffers function
896

897
				originalAttribute = material.attributes[ a ];
898

899
				attribute = {};
900

901
				for ( property in originalAttribute ) {
M
Mr.doob 已提交
902

903
					attribute[ property ] = originalAttribute[ property ];
904

905
				}
906

907
				if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
908

909
					attribute.__webglInitialized = true;
910

911
					size = 1;		// "f" and "i"
M
Mr.doob 已提交
912

913 914 915 916
					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;
917

918 919 920 921
					attribute.size = size;
					attribute.array = new Float32Array( nvertices * size );
					attribute.buffer = _gl.createBuffer();
					attribute.buffer.belongsToAttribute = a;
922

923 924
					originalAttribute.needsUpdate = true;
					attribute.__original = originalAttribute;
925 926 927

				}

928 929
				geometryGroup.__webglCustomAttributesList.push( attribute );

930
			}
M
Mr.doob 已提交
931

932
		}
933

934 935
		geometryGroup.__inittedArrays = true;

936
	};
M
Mr.doob 已提交
937

938

939
	function setMeshBuffers( geometryGroup, object, hint, dispose ) {
940

941 942 943 944 945 946 947
		if ( ! geometryGroup.__inittedArrays ) {

			// console.log( object );
			return;

		}

M
Mr.doob 已提交
948
		var f, fl, fi, face,
949 950 951 952 953 954 955 956 957 958
		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,
959
		m, ml, i, il,
960 961
		vn, uvi, uv2i,
		vk, vkl, vka,
962
		a,
M
Mr.doob 已提交
963

964
		vertexIndex = 0,
965

966 967
		offset = 0,
		offset_uv = 0,
968
		offset_uv2 = 0,
969 970 971 972
		offset_face = 0,
		offset_normal = 0,
		offset_tangent = 0,
		offset_line = 0,
973
		offset_color = 0,
A
alteredq 已提交
974
		offset_skin = 0,
975
		offset_morphTarget = 0,
976
		offset_custom = 0,
977
		offset_customSrc = 0,
M
Mr.doob 已提交
978

979 980
		value,

981 982 983 984 985 986
		vertexArray = geometryGroup.__vertexArray,
		uvArray = geometryGroup.__uvArray,
		uv2Array = geometryGroup.__uv2Array,
		normalArray = geometryGroup.__normalArray,
		tangentArray = geometryGroup.__tangentArray,
		colorArray = geometryGroup.__colorArray,
987

988 989 990 991
		skinVertexAArray = geometryGroup.__skinVertexAArray,
		skinVertexBArray = geometryGroup.__skinVertexBArray,
		skinIndexArray = geometryGroup.__skinIndexArray,
		skinWeightArray = geometryGroup.__skinWeightArray,
M
Mr.doob 已提交
992

993 994
		morphTargetsArrays = geometryGroup.__morphTargetsArrays,

995
		customAttributes = geometryGroup.__webglCustomAttributesList,
996
		customAttribute,
997

998 999
		faceArray = geometryGroup.__faceArray,
		lineArray = geometryGroup.__lineArray,
M
Mr.doob 已提交
1000

1001
		needsSmoothNormals = geometryGroup.__needsSmoothNormals,
1002

1003
		vertexColorType = geometryGroup.__vertexColorType,
A
alteredq 已提交
1004 1005
		uvType = geometryGroup.__uvType,
		normalType = geometryGroup.__normalType,
1006

1007
		geometry = object.geometry, // this is shared for all chunks
1008

1009
		dirtyVertices = geometry.__dirtyVertices,
1010 1011 1012
		dirtyElements = geometry.__dirtyElements,
		dirtyUvs = geometry.__dirtyUvs,
		dirtyNormals = geometry.__dirtyNormals,
1013
		dirtyTangents = geometry.__dirtyTangents,
1014
		dirtyColors = geometry.__dirtyColors,
1015
		dirtyMorphTargets = geometry.__dirtyMorphTargets,
M
Mr.doob 已提交
1016

1017
		vertices = geometry.vertices,
1018
		chunk_faces = geometryGroup.faces,
1019
		obj_faces = geometry.faces,
1020

1021 1022
		obj_uvs  = geometry.faceVertexUvs[ 0 ],
		obj_uvs2 = geometry.faceVertexUvs[ 1 ],
1023

A
alteredq 已提交
1024
		obj_colors = geometry.colors,
1025

A
alteredq 已提交
1026 1027 1028
		obj_skinVerticesA = geometry.skinVerticesA,
		obj_skinVerticesB = geometry.skinVerticesB,
		obj_skinIndices = geometry.skinIndices,
1029
		obj_skinWeights = geometry.skinWeights,
1030

1031
		morphTargets = geometry.morphTargets;
1032

1033
		if ( customAttributes ) {
M
Mr.doob 已提交
1034

1035
			for ( i = 0, il = customAttributes.length; i < il; i ++ ) {
M
Mr.doob 已提交
1036

1037 1038
				customAttributes[ i ].offset = 0;
				customAttributes[ i ].offsetSrc = 0;
M
Mr.doob 已提交
1039

1040 1041
			}

M
Mr.doob 已提交
1042
		}
1043 1044


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

1047 1048
			fi = chunk_faces[ f ];
			face = obj_faces[ fi ];
1049 1050

			if ( obj_uvs ) {
A
alteredq 已提交
1051 1052 1053 1054

				uv = obj_uvs[ fi ];

			}
1055 1056 1057

			if ( obj_uvs2 ) {

A
alteredq 已提交
1058 1059 1060
				uv2 = obj_uvs2[ fi ];

			}
M
Mr.doob 已提交
1061

1062
			vertexNormals = face.vertexNormals;
1063
			faceNormal = face.normal;
1064

1065 1066
			vertexColors = face.vertexColors;
			faceColor = face.color;
1067

1068
			vertexTangents = face.vertexTangents;
1069 1070 1071

			if ( face instanceof THREE.Face3 ) {

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

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

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

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

1086 1087 1088
					vertexArray[ offset + 6 ] = v3.x;
					vertexArray[ offset + 7 ] = v3.y;
					vertexArray[ offset + 8 ] = v3.z;
M
Mr.doob 已提交
1089

1090
					offset += 9;
M
Mr.doob 已提交
1091

1092
				}
1093

1094
				if ( customAttributes ) {
M
Mr.doob 已提交
1095

1096
					for ( i = 0, il = customAttributes.length; i < il; i ++ ) {
M
Mr.doob 已提交
1097

1098
						customAttribute = customAttributes[ i ];
M
Mr.doob 已提交
1099

1100
						if ( customAttribute.__original.needsUpdate ) {
M
Mr.doob 已提交
1101

1102
							offset_custom = customAttribute.offset;
1103
							offset_customSrc = customAttribute.offsetSrc;
M
Mr.doob 已提交
1104

1105 1106 1107
							if ( customAttribute.size === 1 ) {

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

1109
									customAttribute.array[ offset_custom ] 	   = customAttribute.value[ face.a ];
1110 1111
									customAttribute.array[ offset_custom + 1 ] = customAttribute.value[ face.b ];
									customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ face.c ];
1112 1113 1114

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

1115 1116 1117 1118 1119
									value = customAttribute.value[ offset_customSrc ];

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

1121 1122 1123 1124
									customAttribute.offsetSrc ++;

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

1125
									customAttribute.array[ offset_custom ] 	   = customAttribute.value[ offset_customSrc ];
1126 1127
									customAttribute.array[ offset_custom + 1 ] = customAttribute.value[ offset_customSrc + 1 ];
									customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ offset_customSrc + 2 ];
1128

1129
									customAttribute.offsetSrc += 3;
1130

1131
								}
M
Mr.doob 已提交
1132

1133
								customAttribute.offset += 3;
M
Mr.doob 已提交
1134

1135
							} else {
M
Mr.doob 已提交
1136

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

1139 1140 1141
									v1 = customAttribute.value[ face.a ];
									v2 = customAttribute.value[ face.b ];
									v3 = customAttribute.value[ face.c ];
1142 1143 1144

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

1145 1146 1147 1148 1149
									value = customAttribute.value[ offset_customSrc ];

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

1151 1152 1153 1154
									customAttribute.offsetSrc ++;

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

1155
									v1 = customAttribute.value[ offset_customSrc ];
1156 1157
									v2 = customAttribute.value[ offset_customSrc + 1 ];
									v3 = customAttribute.value[ offset_customSrc + 2 ];
1158

1159
									customAttribute.offsetSrc += 3;
1160

1161
								}
M
Mr.doob 已提交
1162

1163 1164

								if ( customAttribute.size === 2 ) {
M
Mr.doob 已提交
1165

1166
									customAttribute.array[ offset_custom ] 	   = v1.x;
M
Mr.doob 已提交
1167
									customAttribute.array[ offset_custom + 1 ] = v1.y;
1168

M
Mr.doob 已提交
1169 1170
									customAttribute.array[ offset_custom + 2 ] = v2.x;
									customAttribute.array[ offset_custom + 3 ] = v2.y;
1171

M
Mr.doob 已提交
1172
									customAttribute.array[ offset_custom + 4 ] = v3.x;
1173
									customAttribute.array[ offset_custom + 5 ] = v3.y;
M
Mr.doob 已提交
1174

1175
									customAttribute.offset += 6;
M
Mr.doob 已提交
1176

1177 1178 1179
								} else if ( customAttribute.size === 3 ) {

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

1181
										customAttribute.array[ offset_custom ] 	   = v1.r;
1182 1183
										customAttribute.array[ offset_custom + 1 ] = v1.g;
										customAttribute.array[ offset_custom + 2 ] = v1.b;
1184

1185 1186 1187
										customAttribute.array[ offset_custom + 3 ] = v2.r;
										customAttribute.array[ offset_custom + 4 ] = v2.g;
										customAttribute.array[ offset_custom + 5 ] = v2.b;
1188

1189 1190 1191
										customAttribute.array[ offset_custom + 6 ] = v3.r;
										customAttribute.array[ offset_custom + 7 ] = v3.g;
										customAttribute.array[ offset_custom + 8 ] = v3.b;
1192

1193
									} else {
1194

1195
										customAttribute.array[ offset_custom ] 	   = v1.x;
1196 1197
										customAttribute.array[ offset_custom + 1 ] = v1.y;
										customAttribute.array[ offset_custom + 2 ] = v1.z;
1198

1199 1200 1201
										customAttribute.array[ offset_custom + 3 ] = v2.x;
										customAttribute.array[ offset_custom + 4 ] = v2.y;
										customAttribute.array[ offset_custom + 5 ] = v2.z;
1202

1203 1204 1205
										customAttribute.array[ offset_custom + 6 ] = v3.x;
										customAttribute.array[ offset_custom + 7 ] = v3.y;
										customAttribute.array[ offset_custom + 8 ] = v3.z;
1206

1207
									}
M
Mr.doob 已提交
1208

1209
									customAttribute.offset += 9;
M
Mr.doob 已提交
1210

1211
								} else {
M
Mr.doob 已提交
1212

1213
									customAttribute.array[ offset_custom  ] 	= v1.x;
M
Mr.doob 已提交
1214 1215 1216
									customAttribute.array[ offset_custom + 1  ] = v1.y;
									customAttribute.array[ offset_custom + 2  ] = v1.z;
									customAttribute.array[ offset_custom + 3  ] = v1.w;
1217

M
Mr.doob 已提交
1218 1219 1220 1221
									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;
1222

M
Mr.doob 已提交
1223
									customAttribute.array[ offset_custom + 8  ] = v3.x;
1224 1225 1226
									customAttribute.array[ offset_custom + 9  ] = v3.y;
									customAttribute.array[ offset_custom + 10 ] = v3.z;
									customAttribute.array[ offset_custom + 11 ] = v3.w;
M
Mr.doob 已提交
1227

1228
									customAttribute.offset += 12;
M
Mr.doob 已提交
1229

1230
								}
M
Mr.doob 已提交
1231

1232
							}
M
Mr.doob 已提交
1233

1234
						}
M
Mr.doob 已提交
1235

1236
					}
M
Mr.doob 已提交
1237

1238 1239 1240
				}


1241
				if ( dirtyMorphTargets ) {
1242 1243 1244

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

1245 1246 1247
						v1 = morphTargets[ vk ].vertices[ face.a ].position;
						v2 = morphTargets[ vk ].vertices[ face.b ].position;
						v3 = morphTargets[ vk ].vertices[ face.c ].position;
1248

1249
						vka = morphTargetsArrays[ vk ];
1250

1251
						vka[ offset_morphTarget ] 	  = v1.x;
1252 1253
						vka[ offset_morphTarget + 1 ] = v1.y;
						vka[ offset_morphTarget + 2 ] = v1.z;
1254

1255 1256 1257
						vka[ offset_morphTarget + 3 ] = v2.x;
						vka[ offset_morphTarget + 4 ] = v2.y;
						vka[ offset_morphTarget + 5 ] = v2.z;
1258

1259 1260 1261
						vka[ offset_morphTarget + 6 ] = v3.x;
						vka[ offset_morphTarget + 7 ] = v3.y;
						vka[ offset_morphTarget + 8 ] = v3.z;
1262

1263 1264
					}

1265
					offset_morphTarget += 9;
1266

1267 1268
				}

A
alteredq 已提交
1269 1270 1271
				if ( obj_skinWeights.length ) {

					// weights
1272

A
alteredq 已提交
1273 1274 1275
					sw1 = obj_skinWeights[ face.a ];
					sw2 = obj_skinWeights[ face.b ];
					sw3 = obj_skinWeights[ face.c ];
1276

A
alteredq 已提交
1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292
					skinWeightArray[ offset_skin ]     = sw1.x;
					skinWeightArray[ offset_skin + 1 ] = sw1.y;
					skinWeightArray[ offset_skin + 2 ] = sw1.z;
					skinWeightArray[ offset_skin + 3 ] = sw1.w;

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

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

					// indices
1293

A
alteredq 已提交
1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313
					si1 = obj_skinIndices[ face.a ];
					si2 = obj_skinIndices[ face.b ];
					si3 = obj_skinIndices[ face.c ];

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

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

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

					// vertices A
1314

A
alteredq 已提交
1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334
					sa1 = obj_skinVerticesA[ face.a ];
					sa2 = obj_skinVerticesA[ face.b ];
					sa3 = obj_skinVerticesA[ face.c ];

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

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

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

					// vertices B
1335

A
alteredq 已提交
1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355
					sb1 = obj_skinVerticesB[ face.a ];
					sb2 = obj_skinVerticesB[ face.b ];
					sb3 = obj_skinVerticesB[ face.c ];

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

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

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

					offset_skin += 12;
1356

A
alteredq 已提交
1357
				}
1358

1359 1360
				if ( dirtyColors && vertexColorType ) {

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

1363 1364 1365 1366 1367
						c1 = vertexColors[ 0 ];
						c2 = vertexColors[ 1 ];
						c3 = vertexColors[ 2 ];

					} else {
1368

1369 1370 1371 1372 1373
						c1 = faceColor;
						c2 = faceColor;
						c3 = faceColor;

					}
1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385

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

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

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

1387 1388 1389 1390
					offset_color += 9;

				}

1391
				if ( dirtyTangents && geometry.hasTangents ) {
1392

1393 1394 1395
					t1 = vertexTangents[ 0 ];
					t2 = vertexTangents[ 1 ];
					t3 = vertexTangents[ 2 ];
1396

1397 1398 1399 1400
					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 已提交
1401

1402 1403 1404 1405
					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 已提交
1406

1407 1408 1409 1410
					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 已提交
1411

1412
					offset_tangent += 12;
M
Mr.doob 已提交
1413

1414 1415
				}

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

1418
					if ( vertexNormals.length === 3 && needsSmoothNormals ) {
1419 1420

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

1422
							vn = vertexNormals[ i ];
M
Mr.doob 已提交
1423

1424 1425 1426
							normalArray[ offset_normal ]     = vn.x;
							normalArray[ offset_normal + 1 ] = vn.y;
							normalArray[ offset_normal + 2 ] = vn.z;
M
Mr.doob 已提交
1427

1428
							offset_normal += 3;
M
Mr.doob 已提交
1429

1430
						}
M
Mr.doob 已提交
1431

1432
					} else {
1433

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

1436 1437 1438
							normalArray[ offset_normal ]     = faceNormal.x;
							normalArray[ offset_normal + 1 ] = faceNormal.y;
							normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
1439

1440
							offset_normal += 3;
M
Mr.doob 已提交
1441

1442
						}
M
Mr.doob 已提交
1443 1444

					}
M
Mr.doob 已提交
1445

1446 1447
				}

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

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

1452
						uvi = uv[ i ];
M
Mr.doob 已提交
1453

1454 1455
						uvArray[ offset_uv ]     = uvi.u;
						uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
1456

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

M
Mr.doob 已提交
1459
					}
1460 1461 1462

				}

A
alteredq 已提交
1463
				if ( dirtyUvs && uv2 !== undefined && uvType ) {
1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477

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

						uv2i = uv2[ i ];

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

						offset_uv2 += 2;

					}

				}

1478
				if ( dirtyElements ) {
M
Mr.doob 已提交
1479

1480
					faceArray[ offset_face ] 	 = vertexIndex;
1481 1482
					faceArray[ offset_face + 1 ] = vertexIndex + 1;
					faceArray[ offset_face + 2 ] = vertexIndex + 2;
M
Mr.doob 已提交
1483

1484
					offset_face += 3;
M
Mr.doob 已提交
1485

1486 1487
					lineArray[ offset_line ]     = vertexIndex;
					lineArray[ offset_line + 1 ] = vertexIndex + 1;
M
Mr.doob 已提交
1488

1489 1490
					lineArray[ offset_line + 2 ] = vertexIndex;
					lineArray[ offset_line + 3 ] = vertexIndex + 2;
M
Mr.doob 已提交
1491

1492 1493
					lineArray[ offset_line + 4 ] = vertexIndex + 1;
					lineArray[ offset_line + 5 ] = vertexIndex + 2;
M
Mr.doob 已提交
1494

1495
					offset_line += 6;
1496

1497
					vertexIndex += 3;
M
Mr.doob 已提交
1498

1499
				}
M
Mr.doob 已提交
1500

1501 1502 1503

			} else if ( face instanceof THREE.Face4 ) {

1504
				if ( dirtyVertices ) {
M
Mr.doob 已提交
1505

1506 1507 1508 1509
					v1 = vertices[ face.a ].position;
					v2 = vertices[ face.b ].position;
					v3 = vertices[ face.c ].position;
					v4 = vertices[ face.d ].position;
M
Mr.doob 已提交
1510

1511 1512 1513
					vertexArray[ offset ]     = v1.x;
					vertexArray[ offset + 1 ] = v1.y;
					vertexArray[ offset + 2 ] = v1.z;
M
Mr.doob 已提交
1514

1515 1516 1517
					vertexArray[ offset + 3 ] = v2.x;
					vertexArray[ offset + 4 ] = v2.y;
					vertexArray[ offset + 5 ] = v2.z;
1518

1519 1520 1521
					vertexArray[ offset + 6 ] = v3.x;
					vertexArray[ offset + 7 ] = v3.y;
					vertexArray[ offset + 8 ] = v3.z;
1522

1523
					vertexArray[ offset + 9 ]  = v4.x;
1524 1525
					vertexArray[ offset + 10 ] = v4.y;
					vertexArray[ offset + 11 ] = v4.z;
M
Mr.doob 已提交
1526

1527
					offset += 12;
M
Mr.doob 已提交
1528

1529
				}
1530

1531
				if ( customAttributes ) {
M
Mr.doob 已提交
1532

1533
					for ( i = 0, il = customAttributes.length; i < il; i ++ ) {
M
Mr.doob 已提交
1534

1535
						customAttribute = customAttributes[ i ];
1536

1537
						if ( customAttribute.__original.needsUpdate ) {
1538 1539

							offset_custom = customAttribute.offset;
1540
							offset_customSrc = customAttribute.offsetSrc;
M
Mr.doob 已提交
1541

1542 1543 1544
							if ( customAttribute.size === 1 ) {

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

1546
									customAttribute.array[ offset_custom ] 	   = customAttribute.value[ face.a ];
1547 1548
									customAttribute.array[ offset_custom + 1 ] = customAttribute.value[ face.b ];
									customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ face.c ];
A
alteredq 已提交
1549
									customAttribute.array[ offset_custom + 3 ] = customAttribute.value[ face.d ];
1550 1551 1552

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

1553
									value = customAttribute.value[ offset_customSrc ];
1554

1555 1556 1557 1558 1559 1560
									customAttribute.array[ offset_custom ] 	   = value;
									customAttribute.array[ offset_custom + 1 ] = value;
									customAttribute.array[ offset_custom + 2 ] = value;
									customAttribute.array[ offset_custom + 3 ] = value;

									customAttribute.offsetSrc ++;
1561 1562 1563

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

1564
									customAttribute.array[ offset_custom ] 	   = customAttribute.value[ offset_customSrc ];
1565 1566
									customAttribute.array[ offset_custom + 1 ] = customAttribute.value[ offset_customSrc + 1 ];
									customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ offset_customSrc + 2 ];
A
alteredq 已提交
1567
									customAttribute.array[ offset_custom + 3 ] = customAttribute.value[ offset_customSrc + 3 ];
1568

1569
									customAttribute.offsetSrc += 4;
1570

1571
								}
M
Mr.doob 已提交
1572

1573
								customAttribute.offset += 4;
M
Mr.doob 已提交
1574

1575
							} else {
M
Mr.doob 已提交
1576

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

1579 1580 1581 1582
									v1 = customAttribute.value[ face.a ];
									v2 = customAttribute.value[ face.b ];
									v3 = customAttribute.value[ face.c ];
									v4 = customAttribute.value[ face.d ];
1583 1584 1585

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

1586
									value = customAttribute.value[ offset_customSrc ];
1587

1588 1589 1590 1591 1592 1593
									v1 = value;
									v2 = value;
									v3 = value;
									v4 = value;

									customAttribute.offsetSrc ++;
1594 1595 1596

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

1597
									v1 = customAttribute.value[ offset_customSrc ];
1598 1599 1600
									v2 = customAttribute.value[ offset_customSrc + 1 ];
									v3 = customAttribute.value[ offset_customSrc + 2 ];
									v4 = customAttribute.value[ offset_customSrc + 3 ];
1601

1602
									customAttribute.offsetSrc += 4;
1603

1604 1605
								}

M
Mr.doob 已提交
1606

1607
								if ( customAttribute.size === 2 ) {
M
Mr.doob 已提交
1608

1609
									customAttribute.array[ offset_custom ] 	   = v1.x;
M
Mr.doob 已提交
1610
									customAttribute.array[ offset_custom + 1 ] = v1.y;
1611

M
Mr.doob 已提交
1612 1613
									customAttribute.array[ offset_custom + 2 ] = v2.x;
									customAttribute.array[ offset_custom + 3 ] = v2.y;
1614

M
Mr.doob 已提交
1615
									customAttribute.array[ offset_custom + 4 ] = v3.x;
1616
									customAttribute.array[ offset_custom + 5 ] = v3.y;
1617

M
Mr.doob 已提交
1618
									customAttribute.array[ offset_custom + 6 ] = v4.x;
1619
									customAttribute.array[ offset_custom + 7 ] = v4.y;
M
Mr.doob 已提交
1620

1621
									customAttribute.offset += 8;
M
Mr.doob 已提交
1622

1623 1624 1625
								} else if ( customAttribute.size === 3 ) {

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

1627
										customAttribute.array[ offset_custom  ] 	= v1.r;
1628 1629
										customAttribute.array[ offset_custom + 1  ] = v1.g;
										customAttribute.array[ offset_custom + 2  ] = v1.b;
1630

1631 1632 1633
										customAttribute.array[ offset_custom + 3  ] = v2.r;
										customAttribute.array[ offset_custom + 4  ] = v2.g;
										customAttribute.array[ offset_custom + 5  ] = v2.b;
1634

1635 1636 1637
										customAttribute.array[ offset_custom + 6  ] = v3.r;
										customAttribute.array[ offset_custom + 7  ] = v3.g;
										customAttribute.array[ offset_custom + 8  ] = v3.b;
1638

1639 1640 1641 1642 1643
										customAttribute.array[ offset_custom + 9  ] = v4.r;
										customAttribute.array[ offset_custom + 10 ] = v4.g;
										customAttribute.array[ offset_custom + 11 ] = v4.b;

									} else {
1644

1645
										customAttribute.array[ offset_custom  ] 	= v1.x;
1646 1647
										customAttribute.array[ offset_custom + 1  ] = v1.y;
										customAttribute.array[ offset_custom + 2  ] = v1.z;
1648

1649 1650 1651
										customAttribute.array[ offset_custom + 3  ] = v2.x;
										customAttribute.array[ offset_custom + 4  ] = v2.y;
										customAttribute.array[ offset_custom + 5  ] = v2.z;
1652

1653 1654 1655
										customAttribute.array[ offset_custom + 6  ] = v3.x;
										customAttribute.array[ offset_custom + 7  ] = v3.y;
										customAttribute.array[ offset_custom + 8  ] = v3.z;
1656

1657 1658 1659
										customAttribute.array[ offset_custom + 9  ] = v4.x;
										customAttribute.array[ offset_custom + 10 ] = v4.y;
										customAttribute.array[ offset_custom + 11 ] = v4.z;
1660

1661
									}
M
Mr.doob 已提交
1662

1663
									customAttribute.offset += 12;
M
Mr.doob 已提交
1664

1665
								} else {
M
Mr.doob 已提交
1666

1667
									customAttribute.array[ offset_custom  ] 	= v1.x;
M
Mr.doob 已提交
1668 1669 1670
									customAttribute.array[ offset_custom + 1  ] = v1.y;
									customAttribute.array[ offset_custom + 2  ] = v1.z;
									customAttribute.array[ offset_custom + 3  ] = v1.w;
1671

M
Mr.doob 已提交
1672 1673 1674 1675
									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;
1676

M
Mr.doob 已提交
1677
									customAttribute.array[ offset_custom + 8  ] = v3.x;
1678 1679 1680
									customAttribute.array[ offset_custom + 9  ] = v3.y;
									customAttribute.array[ offset_custom + 10 ] = v3.z;
									customAttribute.array[ offset_custom + 11 ] = v3.w;
1681

M
Mr.doob 已提交
1682
									customAttribute.array[ offset_custom + 12 ] = v4.x;
1683 1684 1685
									customAttribute.array[ offset_custom + 13 ] = v4.y;
									customAttribute.array[ offset_custom + 14 ] = v4.z;
									customAttribute.array[ offset_custom + 15 ] = v4.w;
M
Mr.doob 已提交
1686

1687
									customAttribute.offset += 16;
M
Mr.doob 已提交
1688

1689
								}
M
Mr.doob 已提交
1690

1691
							}
M
Mr.doob 已提交
1692

1693
						}
M
Mr.doob 已提交
1694

1695
					}
M
Mr.doob 已提交
1696

1697 1698 1699
				}


1700
				if ( dirtyMorphTargets ) {
1701

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

1704 1705 1706 1707
						v1 = morphTargets[ vk ].vertices[ face.a ].position;
						v2 = morphTargets[ vk ].vertices[ face.b ].position;
						v3 = morphTargets[ vk ].vertices[ face.c ].position;
						v4 = morphTargets[ vk ].vertices[ face.d ].position;
1708

1709
						vka = morphTargetsArrays[ vk ];
1710

1711
						vka[ offset_morphTarget ] 	  = v1.x;
1712 1713
						vka[ offset_morphTarget + 1 ] = v1.y;
						vka[ offset_morphTarget + 2 ] = v1.z;
1714

1715 1716 1717
						vka[ offset_morphTarget + 3 ] = v2.x;
						vka[ offset_morphTarget + 4 ] = v2.y;
						vka[ offset_morphTarget + 5 ] = v2.z;
1718

1719 1720 1721
						vka[ offset_morphTarget + 6 ] = v3.x;
						vka[ offset_morphTarget + 7 ] = v3.y;
						vka[ offset_morphTarget + 8 ] = v3.z;
1722

1723
						vka[ offset_morphTarget + 9 ]  = v4.x;
1724 1725
						vka[ offset_morphTarget + 10 ] = v4.y;
						vka[ offset_morphTarget + 11 ] = v4.z;
1726

1727 1728
					}

1729
					offset_morphTarget += 12;
1730

1731 1732
				}

A
alteredq 已提交
1733 1734 1735
				if ( obj_skinWeights.length ) {

					// weights
1736

A
alteredq 已提交
1737 1738 1739 1740
					sw1 = obj_skinWeights[ face.a ];
					sw2 = obj_skinWeights[ face.b ];
					sw3 = obj_skinWeights[ face.c ];
					sw4 = obj_skinWeights[ face.d ];
1741

A
alteredq 已提交
1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762
					skinWeightArray[ offset_skin ]     = sw1.x;
					skinWeightArray[ offset_skin + 1 ] = sw1.y;
					skinWeightArray[ offset_skin + 2 ] = sw1.z;
					skinWeightArray[ offset_skin + 3 ] = sw1.w;

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

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

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

					// indices
1763

A
alteredq 已提交
1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789
					si1 = obj_skinIndices[ face.a ];
					si2 = obj_skinIndices[ face.b ];
					si3 = obj_skinIndices[ face.c ];
					si4 = obj_skinIndices[ face.d ];

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

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

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

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

					// vertices A
1790

A
alteredq 已提交
1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816
					sa1 = obj_skinVerticesA[ face.a ];
					sa2 = obj_skinVerticesA[ face.b ];
					sa3 = obj_skinVerticesA[ face.c ];
					sa4 = obj_skinVerticesA[ face.d ];

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

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

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

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

					// vertices B
1817

A
alteredq 已提交
1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837
					sb1 = obj_skinVerticesB[ face.a ];
					sb2 = obj_skinVerticesB[ face.b ];
					sb3 = obj_skinVerticesB[ face.c ];
					sb4 = obj_skinVerticesB[ face.d ];

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

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

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

1838 1839
					skinVertexBArray[ offset_skin + 12 ] = sb4.x;
					skinVertexBArray[ offset_skin + 13 ] = sb4.y;
A
alteredq 已提交
1840 1841 1842
					skinVertexBArray[ offset_skin + 14 ] = sb4.z;
					skinVertexBArray[ offset_skin + 15 ] = 1;

1843 1844
					offset_skin += 16;

A
alteredq 已提交
1845
				}
1846

1847 1848
				if ( dirtyColors && vertexColorType ) {

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

1851 1852 1853 1854 1855 1856
						c1 = vertexColors[ 0 ];
						c2 = vertexColors[ 1 ];
						c3 = vertexColors[ 2 ];
						c4 = vertexColors[ 3 ];

					} else {
1857

1858 1859 1860 1861 1862 1863
						c1 = faceColor;
						c2 = faceColor;
						c3 = faceColor;
						c4 = faceColor;

					}
1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875

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

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

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

1877 1878 1879
					colorArray[ offset_color + 9 ]  = c4.r;
					colorArray[ offset_color + 10 ] = c4.g;
					colorArray[ offset_color + 11 ] = c4.b;
1880

1881 1882
					offset_color += 12;

1883 1884
				}

1885
				if ( dirtyTangents && geometry.hasTangents ) {
1886

1887 1888 1889 1890
					t1 = vertexTangents[ 0 ];
					t2 = vertexTangents[ 1 ];
					t3 = vertexTangents[ 2 ];
					t4 = vertexTangents[ 3 ];
1891

1892 1893 1894 1895
					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 已提交
1896

1897 1898 1899 1900
					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 已提交
1901

1902 1903
					tangentArray[ offset_tangent + 8 ]  = t3.x;
					tangentArray[ offset_tangent + 9 ]  = t3.y;
1904 1905
					tangentArray[ offset_tangent + 10 ] = t3.z;
					tangentArray[ offset_tangent + 11 ] = t3.w;
M
Mr.doob 已提交
1906

1907 1908 1909 1910
					tangentArray[ offset_tangent + 12 ] = t4.x;
					tangentArray[ offset_tangent + 13 ] = t4.y;
					tangentArray[ offset_tangent + 14 ] = t4.z;
					tangentArray[ offset_tangent + 15 ] = t4.w;
M
Mr.doob 已提交
1911

1912
					offset_tangent += 16;
M
Mr.doob 已提交
1913

1914
				}
M
Mr.doob 已提交
1915

M
Mr.doob 已提交
1916
				if ( dirtyNormals && normalType ) {
M
Mr.doob 已提交
1917

1918
					if ( vertexNormals.length === 4 && needsSmoothNormals ) {
1919

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

1922
							vn = vertexNormals[ i ];
M
Mr.doob 已提交
1923

1924 1925 1926
							normalArray[ offset_normal ]     = vn.x;
							normalArray[ offset_normal + 1 ] = vn.y;
							normalArray[ offset_normal + 2 ] = vn.z;
M
Mr.doob 已提交
1927

1928
							offset_normal += 3;
M
Mr.doob 已提交
1929

1930
						}
M
Mr.doob 已提交
1931

1932
					} else {
1933

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

1936 1937 1938
							normalArray[ offset_normal ]     = faceNormal.x;
							normalArray[ offset_normal + 1 ] = faceNormal.y;
							normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
1939

1940
							offset_normal += 3;
M
Mr.doob 已提交
1941

1942
						}
M
Mr.doob 已提交
1943 1944

					}
M
Mr.doob 已提交
1945

1946 1947
				}

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

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

1952
						uvi = uv[ i ];
M
Mr.doob 已提交
1953

1954 1955
						uvArray[ offset_uv ]     = uvi.u;
						uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
1956

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

M
Mr.doob 已提交
1959
					}
1960 1961

				}
1962

A
alteredq 已提交
1963
				if ( dirtyUvs && uv2 !== undefined && uvType ) {
1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976

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

						uv2i = uv2[ i ];

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

						offset_uv2 += 2;

					}

				}
M
Mr.doob 已提交
1977

1978
				if ( dirtyElements ) {
M
Mr.doob 已提交
1979

1980
					faceArray[ offset_face ]     = vertexIndex;
1981 1982
					faceArray[ offset_face + 1 ] = vertexIndex + 1;
					faceArray[ offset_face + 2 ] = vertexIndex + 3;
M
Mr.doob 已提交
1983

1984 1985 1986
					faceArray[ offset_face + 3 ] = vertexIndex + 1;
					faceArray[ offset_face + 4 ] = vertexIndex + 2;
					faceArray[ offset_face + 5 ] = vertexIndex + 3;
M
Mr.doob 已提交
1987

1988
					offset_face += 6;
M
Mr.doob 已提交
1989

1990 1991
					lineArray[ offset_line ]     = vertexIndex;
					lineArray[ offset_line + 1 ] = vertexIndex + 1;
M
Mr.doob 已提交
1992

1993
					lineArray[ offset_line + 2 ] = vertexIndex;
1994
					lineArray[ offset_line + 3 ] = vertexIndex + 3;
M
Mr.doob 已提交
1995

1996 1997
					lineArray[ offset_line + 4 ] = vertexIndex + 1;
					lineArray[ offset_line + 5 ] = vertexIndex + 2;
M
Mr.doob 已提交
1998

1999 2000
					lineArray[ offset_line + 6 ] = vertexIndex + 2;
					lineArray[ offset_line + 7 ] = vertexIndex + 3;
M
Mr.doob 已提交
2001

2002
					offset_line += 8;
M
Mr.doob 已提交
2003

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

2006
				}
M
Mr.doob 已提交
2007

2008
			}
M
Mr.doob 已提交
2009

2010 2011
		}

2012
		if ( dirtyVertices ) {
M
Mr.doob 已提交
2013

2014
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
2015
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
M
Mr.doob 已提交
2016

2017
		}
M
Mr.doob 已提交
2018

2019
		if ( customAttributes ) {
M
Mr.doob 已提交
2020

2021
			for ( i = 0, il = customAttributes.length; i < il; i ++ ) {
M
Mr.doob 已提交
2022

2023
				customAttribute = customAttributes[ i ];
2024

2025
				if ( customAttribute.__original.needsUpdate ) {
2026 2027 2028 2029 2030 2031 2032 2033 2034 2035

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

				}

			}

		}

2036
		if ( dirtyMorphTargets ) {
2037 2038 2039 2040

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

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

2043
			}
2044

2045 2046
		}

2047
		if ( dirtyColors && offset_color > 0 ) {
2048

2049
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
2050 2051 2052
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}
2053

2054
		if ( dirtyNormals ) {
M
Mr.doob 已提交
2055

2056
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
2057
			_gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
M
Mr.doob 已提交
2058

2059 2060
		}

2061
		if ( dirtyTangents && geometry.hasTangents ) {
2062

2063
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
2064
			_gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint );
M
Mr.doob 已提交
2065

2066
		}
2067

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

2070
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
2071
			_gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
M
Mr.doob 已提交
2072

2073
		}
M
Mr.doob 已提交
2074

2075 2076
		if ( dirtyUvs && offset_uv2 > 0 ) {

2077
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
2078 2079 2080 2081
			_gl.bufferData( _gl.ARRAY_BUFFER, uv2Array, hint );

		}

2082
		if ( dirtyElements ) {
M
Mr.doob 已提交
2083

2084
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
2085
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint );
2086

2087
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
2088
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
M
Mr.doob 已提交
2089

2090
		}
2091

2092
		if ( offset_skin > 0 ) {
2093

2094
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
A
alteredq 已提交
2095 2096
			_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexAArray, hint );

2097
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
A
alteredq 已提交
2098 2099
			_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexBArray, hint );

2100
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
A
alteredq 已提交
2101 2102
			_gl.bufferData( _gl.ARRAY_BUFFER, skinIndexArray, hint );

2103
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
A
alteredq 已提交
2104
			_gl.bufferData( _gl.ARRAY_BUFFER, skinWeightArray, hint );
2105

A
alteredq 已提交
2106
		}
2107

2108
		if ( dispose ) {
2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124

			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;

		}
2125

2126
	};
2127

2128
	function setLineBuffers ( geometry, hint ) {
M
Mr.doob 已提交
2129

2130
		var v, c, vertex, offset,
2131 2132 2133 2134
		vertices = geometry.vertices,
		colors = geometry.colors,
		vl = vertices.length,
		cl = colors.length,
M
Mr.doob 已提交
2135

2136 2137
		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,
2138

2139 2140
		dirtyVertices = geometry.__dirtyVertices,
		dirtyColors = geometry.__dirtyColors;
M
Mr.doob 已提交
2141

2142
		if ( dirtyVertices ) {
M
Mr.doob 已提交
2143

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

2146
				vertex = vertices[ v ].position;
M
Mr.doob 已提交
2147

2148
				offset = v * 3;
M
Mr.doob 已提交
2149

2150 2151 2152
				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;
M
Mr.doob 已提交
2153

2154 2155
			}

2156
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
A
alteredq 已提交
2157 2158
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );

2159
		}
M
Mr.doob 已提交
2160

2161 2162
		if ( dirtyColors ) {

2163
			for ( c = 0; c < cl; c ++ ) {
2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174

				color = colors[ c ];

				offset = c * 3;

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

			}

2175
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
2176 2177 2178 2179
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}

2180
	};
M
Mr.doob 已提交
2181

2182
	function setRibbonBuffers ( geometry, hint ) {
A
alteredq 已提交
2183 2184

		var v, c, vertex, offset,
2185 2186 2187 2188
		vertices = geometry.vertices,
		colors = geometry.colors,
		vl = vertices.length,
		cl = colors.length,
A
alteredq 已提交
2189

2190 2191
		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,
2192

2193 2194
		dirtyVertices = geometry.__dirtyVertices,
		dirtyColors = geometry.__dirtyColors;
A
alteredq 已提交
2195 2196 2197

		if ( dirtyVertices ) {

2198
			for ( v = 0; v < vl; v ++ ) {
A
alteredq 已提交
2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209

				vertex = vertices[ v ].position;

				offset = v * 3;

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

			}

2210
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
A
alteredq 已提交
2211 2212 2213 2214 2215 2216
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );

		}

		if ( dirtyColors ) {

2217
			for ( c = 0; c < cl; c ++ ) {
A
alteredq 已提交
2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228

				color = colors[ c ];

				offset = c * 3;

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

			}

2229
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
A
alteredq 已提交
2230 2231 2232 2233 2234
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}

	};
2235

2236
	function setParticleBuffers ( geometry, hint, object ) {
2237

A
alteredq 已提交
2238
		var v, c, vertex, offset,
2239 2240
		vertices = geometry.vertices,
		vl = vertices.length,
2241

2242 2243
		colors = geometry.colors,
		cl = colors.length,
2244

2245 2246
		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,
2247

2248
		sortArray = geometry.__sortArray,
2249

2250 2251
		dirtyVertices = geometry.__dirtyVertices,
		dirtyElements = geometry.__dirtyElements,
2252 2253
		dirtyColors = geometry.__dirtyColors,

2254 2255
		customAttributes = geometry.__webglCustomAttributesList,
		i, il,
2256 2257 2258 2259 2260 2261
		a, ca, cal, v1,
		offset_custom,
		customAttribute;

		if ( customAttributes ) {

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

2264
				customAttributes[ i ].offset = 0;
2265 2266 2267 2268

			}

		}
2269

2270
		if ( object.sortParticles ) {
2271

2272
			_projScreenMatrix.multiplySelf( object.matrixWorld );
2273

2274 2275 2276
			for ( v = 0; v < vl; v++ ) {

				vertex = vertices[ v ].position;
2277

2278 2279
				_vector3.copy( vertex );
				_projScreenMatrix.multiplyVector3( _vector3 );
2280

2281
				sortArray[ v ] = [ _vector3.z, v ];
2282

2283
			}
2284

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

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

2289
				vertex = vertices[ sortArray[v][1] ].position;
2290

2291
				offset = v * 3;
2292

2293 2294 2295
				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;
2296

2297
			}
2298

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

A
alteredq 已提交
2301
				offset = c * 3;
2302

A
alteredq 已提交
2303 2304 2305 2306 2307
				color = colors[ sortArray[c][1] ];

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

2309
			}
2310

2311 2312
			if ( customAttributes ) {

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

2315
					customAttribute = customAttributes[ i ];
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 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380

					cal = customAttribute.value.length;

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

						index = sortArray[ca][1];

						offset_custom = customAttribute.offset;

						if ( customAttribute.size === 1 ) {

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

								customAttribute.array[ offset_custom ] = customAttribute.value[ index ];

							}

						} else {

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

								v1 = customAttribute.value[ index ];

							}

							if ( customAttribute.size === 2 ) {

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

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

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

									customAttribute.array[ offset_custom ] 	   = v1.r;
									customAttribute.array[ offset_custom + 1 ] = v1.g;
									customAttribute.array[ offset_custom + 2 ] = v1.b;

								} else {

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

								}

							} else {

								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.offset += customAttribute.size;

					}

				}

			}

2381

2382
		} else {
2383

2384 2385
			if ( dirtyVertices ) {

2386
				for ( v = 0; v < vl; v ++ ) {
2387 2388 2389 2390 2391 2392 2393 2394 2395 2396

					vertex = vertices[ v ].position;

					offset = v * 3;

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

				}
2397 2398

			}
2399

A
alteredq 已提交
2400
			if ( dirtyColors ) {
2401

2402
				for ( c = 0; c < cl; c ++ ) {
A
alteredq 已提交
2403 2404 2405 2406 2407 2408 2409 2410 2411

					color = colors[ c ];

					offset = c * 3;

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

2412
				}
2413

A
alteredq 已提交
2414
			}
2415

2416 2417
			if ( customAttributes ) {

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

2420
					customAttribute = customAttributes[ i ];
2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488

					if ( customAttribute.__original.needsUpdate ) {

						cal = customAttribute.value.length;

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

							offset_custom = customAttribute.offset;

							if ( customAttribute.size === 1 ) {

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

									customAttribute.array[ offset_custom ] = customAttribute.value[ ca ];

								}

							} else {

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

									v1 = customAttribute.value[ ca ];

								}

								if ( customAttribute.size === 2 ) {

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

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

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

										customAttribute.array[ offset_custom ] 	   = v1.r;
										customAttribute.array[ offset_custom + 1 ] = v1.g;
										customAttribute.array[ offset_custom + 2 ] = v1.b;


									} else {

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

									}

								} else {

									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.offset += customAttribute.size;

						}

					}

				}

			}

2489
		}
2490

A
alteredq 已提交
2491
		if ( dirtyVertices || object.sortParticles ) {
2492

2493
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
A
alteredq 已提交
2494
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
2495

A
alteredq 已提交
2496
		}
2497

A
alteredq 已提交
2498
		if ( dirtyColors || object.sortParticles ) {
2499

2500
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
A
alteredq 已提交
2501
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
2502

A
alteredq 已提交
2503
		}
2504

2505 2506
		if ( customAttributes ) {

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

2509
				customAttribute = customAttributes[ i ];
2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522

				if ( customAttribute.__original.needsUpdate || object.sortParticles ) {

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

				}

			}

		}


2523
	};
M
Mr.doob 已提交
2524

2525
	function setMaterialShaders( material, shaders ) {
2526

2527
		material.uniforms = THREE.UniformsUtils.clone( shaders.uniforms );
2528 2529
		material.vertexShader = shaders.vertexShader;
		material.fragmentShader = shaders.fragmentShader;
2530

M
Mr.doob 已提交
2531
	};
2532

2533
	function refreshUniformsCommon( uniforms, material ) {
M
Mr.doob 已提交
2534

A
alteredq 已提交
2535
		uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
2536

2537 2538 2539 2540 2541 2542 2543 2544 2545 2546
		if ( _this.gammaInput ) {

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

		} else {

			uniforms.diffuse.value = material.color;

		}

A
alteredq 已提交
2547
		uniforms.map.texture = material.map;
2548

2549
		if ( material.map ) {
M
Mr.doob 已提交
2550

2551 2552 2553
			uniforms.offsetRepeat.value.set( material.map.offset.x, material.map.offset.y, material.map.repeat.x, material.map.repeat.y );

		}
2554

2555
		uniforms.lightMap.texture = material.lightMap;
2556

2557
		uniforms.envMap.texture = material.envMap;
2558
		uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : -1;
2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570

		if ( _this.gammaInput ) {

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

		} else {

			uniforms.reflectivity.value = material.reflectivity;

		}

2571
		uniforms.refractionRatio.value = material.refractionRatio;
A
alteredq 已提交
2572
		uniforms.combine.value = material.combine;
2573
		uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
2574

2575
	};
2576

2577
	function refreshUniformsLine( uniforms, material ) {
2578

M
Mr.doob 已提交
2579
		uniforms.diffuse.value = material.color;
A
alteredq 已提交
2580
		uniforms.opacity.value = material.opacity;
2581 2582

	};
M
Mr.doob 已提交
2583

2584
	function refreshUniformsParticle( uniforms, material ) {
2585

M
Mr.doob 已提交
2586
		uniforms.psColor.value = material.color;
A
alteredq 已提交
2587 2588
		uniforms.opacity.value = material.opacity;
		uniforms.size.value = material.size;
M
Mr.doob 已提交
2589
		uniforms.scale.value = _canvas.height / 2.0; // TODO: Cache this.
2590

A
alteredq 已提交
2591
		uniforms.map.texture = material.map;
2592

A
alteredq 已提交
2593
	};
2594

2595
	function refreshUniformsFog( uniforms, fog ) {
2596

M
Mr.doob 已提交
2597
		uniforms.fogColor.value = fog.color;
2598

A
alteredq 已提交
2599
		if ( fog instanceof THREE.Fog ) {
2600

A
alteredq 已提交
2601 2602
			uniforms.fogNear.value = fog.near;
			uniforms.fogFar.value = fog.far;
2603

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

A
alteredq 已提交
2606
			uniforms.fogDensity.value = fog.density;
2607 2608

		}
2609

2610 2611
	};

2612
	function refreshUniformsPhong( uniforms, material ) {
M
Mr.doob 已提交
2613

A
alteredq 已提交
2614
		uniforms.shininess.value = material.shininess;
M
Mr.doob 已提交
2615

2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627
		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;

		}

2628
	};
M
Mr.doob 已提交
2629

2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642
	function refreshUniformsLambert( uniforms, material ) {

		if ( _this.gammaInput ) {

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

		} else {

			uniforms.ambient.value = material.ambient;

		}

	};
M
Mr.doob 已提交
2643

2644
	function refreshUniformsLights( uniforms, lights ) {
M
Mr.doob 已提交
2645

A
alteredq 已提交
2646 2647
		uniforms.enableLighting.value = lights.directional.length + lights.point.length;
		uniforms.ambientLightColor.value = lights.ambient;
2648

A
alteredq 已提交
2649 2650
		uniforms.directionalLightColor.value = lights.directional.colors;
		uniforms.directionalLightDirection.value = lights.directional.positions;
2651

A
alteredq 已提交
2652 2653
		uniforms.pointLightColor.value = lights.point.colors;
		uniforms.pointLightPosition.value = lights.point.positions;
2654
		uniforms.pointLightDistance.value = lights.point.distances;
M
Mr.doob 已提交
2655

A
alteredq 已提交
2656
	};
M
Mr.doob 已提交
2657

2658 2659 2660 2661
	function refreshUniformsShadow( uniforms, material ) {

		if ( uniforms.shadowMatrix ) {

2662 2663 2664 2665 2666 2667 2668
			for ( var i = 0; i < _shadowMatrix.length; i ++ ) {

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


			}
2669 2670 2671 2672 2673 2674 2675 2676

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

		}

	};

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

2679
		var u, a, identifiers, i, parameters, maxLightCount, maxBones, maxShadows, shaderID;
2680

A
alteredq 已提交
2681
		if ( material instanceof THREE.MeshDepthMaterial ) {
2682

2683
			shaderID = 'depth';
2684

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

2687
			shaderID = 'normal';
2688

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

2691
			shaderID = 'basic';
2692

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

2695
			shaderID = 'lambert';
M
Mr.doob 已提交
2696

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

2699
			shaderID = 'phong';
M
Mr.doob 已提交
2700

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

2703
			shaderID = 'basic';
2704

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

2707 2708 2709 2710 2711 2712 2713
			shaderID = 'particle_basic';

		}

		if ( shaderID ) {

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

A
alteredq 已提交
2715
		}
2716

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

2720
		maxLightCount = allocateLights( lights );
2721

2722 2723
		maxShadows = allocateShadows( lights );

2724
		maxBones = allocateBones( object );
M
Mr.doob 已提交
2725

2726
		parameters = {
2727

M
Mr.doob 已提交
2728
			map: !!material.map, envMap: !!material.envMap, lightMap: !!material.lightMap,
2729
			vertexColors: material.vertexColors,
M
Mr.doob 已提交
2730 2731
			fog: fog, useFog: material.fog,
			sizeAttenuation: material.sizeAttenuation,
2732 2733
			skinning: material.skinning,
			morphTargets: material.morphTargets,
2734
			maxMorphTargets: this.maxMorphTargets,
2735
			maxDirLights: maxLightCount.directional, maxPointLights: maxLightCount.point,
2736
			maxBones: maxBones,
2737
			shadowMapEnabled: this.shadowMapEnabled && object.receiveShadow,
2738 2739 2740
			shadowMapSoft: this.shadowMapSoft,
			shadowMapWidth: this.shadowMapWidth,
			shadowMapHeight: this.shadowMapHeight,
2741
			maxShadows: maxShadows,
2742 2743 2744
			alphaTest: material.alphaTest,
			metal: material.metal,
			perPixel: material.perPixel
2745

2746
		};
M
Mikael Emtinger 已提交
2747

2748
		material.program = buildProgram( shaderID, material.fragmentShader, material.vertexShader, material.uniforms, material.attributes, parameters );
2749

2750
		var attributes = material.program.attributes;
2751

2752
		if ( attributes.position >= 0 ) _gl.enableVertexAttribArray( attributes.position );
2753 2754 2755
		if ( attributes.color >= 0 ) _gl.enableVertexAttribArray( attributes.color );
		if ( attributes.normal >= 0 ) _gl.enableVertexAttribArray( attributes.normal );
		if ( attributes.tangent >= 0 ) _gl.enableVertexAttribArray( attributes.tangent );
2756

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

2761 2762 2763 2764
			_gl.enableVertexAttribArray( attributes.skinVertexA );
			_gl.enableVertexAttribArray( attributes.skinVertexB );
			_gl.enableVertexAttribArray( attributes.skinIndex );
			_gl.enableVertexAttribArray( attributes.skinWeight );
2765

2766
		}
2767

2768
		if ( material.attributes ) {
M
Mr.doob 已提交
2769

2770
			for ( a in material.attributes ) {
M
Mr.doob 已提交
2771

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

2774
			}
M
Mr.doob 已提交
2775

2776
		}
2777

2778
		if ( material.morphTargets ) {
2779

2780
			material.numSupportedMorphTargets = 0;
2781

2782
			var id, base = "morphTarget";
2783

2784
			for ( i = 0; i < this.maxMorphTargets; i ++ ) {
2785

2786
				id = base + i;
2787

2788
				if ( attributes[ id ] >= 0 ) {
2789

2790 2791
					_gl.enableVertexAttribArray( attributes[ id ] );
					material.numSupportedMorphTargets ++;
2792

2793
				}
2794

2795
			}
2796

2797
		}
M
Mr.doob 已提交
2798

M
Mr.doob 已提交
2799 2800 2801 2802 2803 2804 2805 2806
		material.uniformsList = [];

		for ( u in material.uniforms ) {

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

		}

2807
	};
2808

2809
	function setProgram( camera, lights, fog, material, object ) {
2810

2811
		if ( ! material.program ) {
2812 2813 2814 2815

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

		}
M
Mr.doob 已提交
2816

2817 2818 2819 2820 2821 2822
		if ( material.morphTargets ) {

			if ( ! object.__webglMorphTargetInfluences ) {

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

2823
				for ( var i = 0, il = _this.maxMorphTargets; i < il; i ++ ) {
2824 2825 2826 2827 2828 2829 2830 2831 2832

					object.__webglMorphTargetInfluences[ i ] = 0;

				}

			}

		}

M
Mr.doob 已提交
2833 2834
		var refreshMaterial = false;

2835
		var program = material.program,
A
alteredq 已提交
2836 2837
			p_uniforms = program.uniforms,
			m_uniforms = material.uniforms;
2838

2839
		if ( program !== _currentProgram ) {
M
Mr.doob 已提交
2840

M
Mr.doob 已提交
2841
			_gl.useProgram( program );
2842
			_currentProgram = program;
2843

M
Mr.doob 已提交
2844 2845
			refreshMaterial = true;

M
Mr.doob 已提交
2846
		}
2847

2848
		if ( material.id !== _currentMaterialId ) {
2849

M
Mr.doob 已提交
2850 2851
			_currentMaterialId = material.id;
			refreshMaterial = true;
2852

M
Mr.doob 已提交
2853
		}
2854

M
Mr.doob 已提交
2855
		if ( refreshMaterial ) {
2856

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

M
Mr.doob 已提交
2859
			// refresh uniforms common to several materials
2860

M
Mr.doob 已提交
2861
			if ( fog && material.fog ) {
M
Mr.doob 已提交
2862

M
Mr.doob 已提交
2863
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
2864

M
Mr.doob 已提交
2865
			}
M
Mr.doob 已提交
2866

M
Mr.doob 已提交
2867 2868 2869
			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material.lights ) {
M
Mr.doob 已提交
2870

M
Mr.doob 已提交
2871 2872
				setupLights( program, lights );
				refreshUniformsLights( m_uniforms, _lights );
M
Mr.doob 已提交
2873

M
Mr.doob 已提交
2874
			}
2875

M
Mr.doob 已提交
2876 2877 2878
			if ( material instanceof THREE.MeshBasicMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
2879

M
Mr.doob 已提交
2880
				refreshUniformsCommon( m_uniforms, material );
2881

M
Mr.doob 已提交
2882
			}
2883

M
Mr.doob 已提交
2884
			// refresh single material specific uniforms
2885

M
Mr.doob 已提交
2886
			if ( material instanceof THREE.LineBasicMaterial ) {
M
Mr.doob 已提交
2887

M
Mr.doob 已提交
2888
				refreshUniformsLine( m_uniforms, material );
M
Mr.doob 已提交
2889

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

M
Mr.doob 已提交
2892
				refreshUniformsParticle( m_uniforms, material );
2893

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

M
Mr.doob 已提交
2896
				refreshUniformsPhong( m_uniforms, material );
2897

2898 2899 2900 2901
			} else if ( material instanceof THREE.MeshLambertMaterial ) {

				refreshUniformsLambert( m_uniforms, material );

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

M
Mr.doob 已提交
2904 2905 2906
				m_uniforms.mNear.value = camera.near;
				m_uniforms.mFar.value = camera.far;
				m_uniforms.opacity.value = material.opacity;
2907

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

M
Mr.doob 已提交
2910
				m_uniforms.opacity.value = material.opacity;
2911

M
Mr.doob 已提交
2912
			}
2913

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

M
Mr.doob 已提交
2916
				refreshUniformsShadow( m_uniforms, material );
2917

M
Mr.doob 已提交
2918
			}
2919

M
Mr.doob 已提交
2920
			// load common uniforms
M
Mr.doob 已提交
2921

M
Mr.doob 已提交
2922
			loadUniformsGeneric( program, material.uniformsList );
M
Mr.doob 已提交
2923

M
Mr.doob 已提交
2924 2925
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)
2926

M
Mr.doob 已提交
2927 2928 2929
			if ( material instanceof THREE.ShaderMaterial ||
				 material instanceof THREE.MeshPhongMaterial ||
				 material.envMap ) {
2930

M
Mr.doob 已提交
2931
				if( p_uniforms.cameraPosition !== null ) {
2932

M
Mr.doob 已提交
2933
					_gl.uniform3f( p_uniforms.cameraPosition, camera.position.x, camera.position.y, camera.position.z );
M
Mr.doob 已提交
2934

M
Mr.doob 已提交
2935
				}
M
Mr.doob 已提交
2936

2937
			}
2938

M
Mr.doob 已提交
2939 2940 2941 2942
			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material instanceof THREE.ShaderMaterial ||
				 material.skinning ) {
2943

M
Mr.doob 已提交
2944
				if( p_uniforms.viewMatrix !== null ) {
2945

M
Mr.doob 已提交
2946
					_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, _viewMatrixArray );
M
Mr.doob 已提交
2947

M
Mr.doob 已提交
2948 2949 2950 2951 2952 2953 2954
				}

			}

			if ( material.skinning ) {

				loadUniformsSkinning( p_uniforms, object );
M
Mr.doob 已提交
2955 2956

			}
2957

A
alteredq 已提交
2958
		}
2959

M
Mr.doob 已提交
2960 2961 2962 2963 2964 2965 2966 2967 2968 2969
		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 );
2970

M
Mr.doob 已提交
2971
			}
2972

A
alteredq 已提交
2973
		}
2974

A
alteredq 已提交
2975
		return program;
2976

A
alteredq 已提交
2977
	};
2978

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

2981
		if ( material.opacity === 0 ) return;
2982

2983
		var program, attributes, linewidth, primitives, a, attribute, i, il;
A
alteredq 已提交
2984

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

2987
		attributes = program.attributes;
M
Mr.doob 已提交
2988

M
Mr.doob 已提交
2989
		var updateBuffers = false,
2990 2991
			wireframeBit = material.wireframe ? 1 : 0,
			geometryGroupHash = ( geometryGroup.id * 0xffffff ) + ( program.id * 2 ) + wireframeBit;
M
Mr.doob 已提交
2992

2993
		if ( geometryGroupHash !== _currentGeometryGroupHash ) {
M
Mr.doob 已提交
2994 2995 2996 2997 2998 2999

			_currentGeometryGroupHash = geometryGroupHash;
			updateBuffers = true;

		}

3000
		// vertices
M
Mr.doob 已提交
3001

3002
		if ( !material.morphTargets && attributes.position >= 0 ) {
3003

M
Mr.doob 已提交
3004 3005 3006 3007 3008 3009
			if ( updateBuffers ) {

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

			}
3010

3011
		} else {
3012

3013 3014 3015 3016 3017
			if ( object.morphTargetBase ) {

				setupMorphTargets( material, geometryGroup, object );

			}
3018

3019 3020
		}

3021

M
Mr.doob 已提交
3022
		if ( updateBuffers ) {
3023

M
Mr.doob 已提交
3024
			// custom attributes
3025

M
Mr.doob 已提交
3026
			// Use the per-geometryGroup custom attribute arrays which are setup in initMeshBuffers
M
Mr.doob 已提交
3027

3028
			if ( geometryGroup.__webglCustomAttributesList ) {
M
Mr.doob 已提交
3029

3030
				for ( i = 0, il = geometryGroup.__webglCustomAttributesList.length; i < il; i ++ ) {
M
Mr.doob 已提交
3031

3032
					attribute = geometryGroup.__webglCustomAttributesList[ i ];
M
Mr.doob 已提交
3033

3034
					if( attributes[ attribute.buffer.belongsToAttribute ] >= 0 ) {
M
Mr.doob 已提交
3035 3036

						_gl.bindBuffer( _gl.ARRAY_BUFFER, attribute.buffer );
3037
						_gl.vertexAttribPointer( attributes[ attribute.buffer.belongsToAttribute ], attribute.size, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
3038 3039

					}
M
Mr.doob 已提交
3040

3041
				}
M
Mr.doob 已提交
3042

3043
			}
M
Mr.doob 已提交
3044

3045

M
Mr.doob 已提交
3046
			// colors
3047

M
Mr.doob 已提交
3048
			if ( attributes.color >= 0 ) {
A
alteredq 已提交
3049

M
Mr.doob 已提交
3050 3051
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
				_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
3052

M
Mr.doob 已提交
3053
			}
A
alteredq 已提交
3054

M
Mr.doob 已提交
3055
			// normals
A
alteredq 已提交
3056

M
Mr.doob 已提交
3057
			if ( attributes.normal >= 0 ) {
M
Mr.doob 已提交
3058

M
Mr.doob 已提交
3059 3060
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
				_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
3061

M
Mr.doob 已提交
3062
			}
3063

M
Mr.doob 已提交
3064
			// tangents
3065

M
Mr.doob 已提交
3066
			if ( attributes.tangent >= 0 ) {
3067

M
Mr.doob 已提交
3068 3069
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
				_gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
3070

M
Mr.doob 已提交
3071
			}
3072

M
Mr.doob 已提交
3073
			// uvs
3074

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

M
Mr.doob 已提交
3077
				if ( geometryGroup.__webglUVBuffer ) {
M
Mr.doob 已提交
3078

M
Mr.doob 已提交
3079 3080
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
					_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
3081

M
Mr.doob 已提交
3082
					_gl.enableVertexAttribArray( attributes.uv );
3083

M
Mr.doob 已提交
3084
				} else {
3085

M
Mr.doob 已提交
3086
					_gl.disableVertexAttribArray( attributes.uv );
3087

M
Mr.doob 已提交
3088
				}
M
Mr.doob 已提交
3089

3090
			}
3091

M
Mr.doob 已提交
3092
			if ( attributes.uv2 >= 0 ) {
3093

M
Mr.doob 已提交
3094
				if ( geometryGroup.__webglUV2Buffer ) {
3095

M
Mr.doob 已提交
3096 3097
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
					_gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );
3098

M
Mr.doob 已提交
3099
					_gl.enableVertexAttribArray( attributes.uv2 );
3100

M
Mr.doob 已提交
3101
				} else {
3102

M
Mr.doob 已提交
3103
					_gl.disableVertexAttribArray( attributes.uv2 );
3104

M
Mr.doob 已提交
3105
				}
3106 3107 3108

			}

M
Mr.doob 已提交
3109 3110 3111
			if ( material.skinning &&
				 attributes.skinVertexA >= 0 && attributes.skinVertexB >= 0 &&
				 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
3112

M
Mr.doob 已提交
3113 3114
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
				_gl.vertexAttribPointer( attributes.skinVertexA, 4, _gl.FLOAT, false, 0, 0 );
3115

M
Mr.doob 已提交
3116 3117
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
				_gl.vertexAttribPointer( attributes.skinVertexB, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
3118

M
Mr.doob 已提交
3119 3120
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
				_gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
3121

M
Mr.doob 已提交
3122 3123
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
				_gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
3124

M
Mr.doob 已提交
3125
			}
3126

A
alteredq 已提交
3127
		}
3128

3129
		// render mesh
M
Mr.doob 已提交
3130

3131
		if ( object instanceof THREE.Mesh ) {
3132

3133
			// wireframe
3134

3135
			if ( material.wireframe ) {
M
Mr.doob 已提交
3136

3137
				_gl.lineWidth( material.wireframeLinewidth );
M
Mr.doob 已提交
3138 3139

				if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
3140
				_gl.drawElements( _gl.LINES, geometryGroup.__webglLineCount, _gl.UNSIGNED_SHORT, 0 );
3141

3142
			// triangles
3143

3144
			} else {
3145

M
Mr.doob 已提交
3146
				if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
3147 3148
				_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );

3149
			}
3150

M
Mr.doob 已提交
3151 3152 3153
			_this.info.render.calls ++;
			_this.info.render.vertices += geometryGroup.__webglFaceCount;
			_this.info.render.faces += geometryGroup.__webglFaceCount / 3;
3154

3155
		// render lines
3156

3157
		} else if ( object instanceof THREE.Line ) {
3158

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

3161
			_gl.lineWidth( material.linewidth );
3162
			_gl.drawArrays( primitives, 0, geometryGroup.__webglLineCount );
3163

M
Mr.doob 已提交
3164
			_this.info.render.calls ++;
3165

3166
		// render particles
3167

3168
		} else if ( object instanceof THREE.ParticleSystem ) {
3169

3170
			_gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webglParticleCount );
3171

M
Mr.doob 已提交
3172
			_this.info.render.calls ++;
3173

A
alteredq 已提交
3174
		// render ribbon
3175

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

3178
			_gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webglVertexCount );
3179

M
Mr.doob 已提交
3180
			_this.info.render.calls ++;
3181

3182 3183 3184 3185
		}

	};

M
Mikael Emtinger 已提交
3186

M
Mikael Emtinger 已提交
3187
	function setupMorphTargets( material, geometryGroup, object ) {
3188

M
Mikael Emtinger 已提交
3189
		// set base
3190

M
Mikael Emtinger 已提交
3191
		var attributes = material.program.attributes;
3192

3193
		if ( object.morphTargetBase !== - 1 ) {
3194 3195

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

3198
		} else if ( attributes.position >= 0 ) {
3199 3200

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

M
Mikael Emtinger 已提交
3203
		}
3204

3205
		if ( object.morphTargetForcedOrder.length ) {
M
Mikael Emtinger 已提交
3206 3207

			// set forced order
3208

M
Mikael Emtinger 已提交
3209 3210 3211
			var m = 0;
			var order = object.morphTargetForcedOrder;
			var influences = object.morphTargetInfluences;
3212 3213 3214 3215

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

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

3218
				object.__webglMorphTargetInfluences[ m ] = influences[ order[ m ] ];
3219 3220 3221

				m ++;
			}
3222

M
Mikael Emtinger 已提交
3223
		} else {
3224

M
Mikael Emtinger 已提交
3225
			// find most influencing
3226

M
Mikael Emtinger 已提交
3227
			var used = [];
3228
			var candidateInfluence = - 1;
M
Mikael Emtinger 已提交
3229 3230 3231 3232
			var candidate = 0;
			var influences = object.morphTargetInfluences;
			var i, il = influences.length;
			var m = 0;
3233

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

M
Mikael Emtinger 已提交
3236
				used[ object.morphTargetBase ] = true;
3237

M
Mikael Emtinger 已提交
3238
			}
3239 3240 3241

			while ( m < material.numSupportedMorphTargets ) {

3242
				for ( i = 0; i < il; i ++ ) {
3243 3244 3245

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

M
Mikael Emtinger 已提交
3246 3247
						candidate = i;
						candidateInfluence = influences[ candidate ];
3248

M
Mikael Emtinger 已提交
3249
					}
3250

M
Mikael Emtinger 已提交
3251
				}
3252 3253

				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ candidate ] );
M
Mikael Emtinger 已提交
3254
				_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
3255 3256 3257

				object.__webglMorphTargetInfluences[ m ] = candidateInfluence;

M
Mikael Emtinger 已提交
3258 3259
				used[ candidate ] = 1;
				candidateInfluence = -1;
3260
				m ++;
3261

M
Mikael Emtinger 已提交
3262
			}
3263

M
Mikael Emtinger 已提交
3264 3265 3266
		}

		// load updated influences uniform
3267

3268
		if( material.program.uniforms.morphTargetInfluences !== null ) {
M
Mr.doob 已提交
3269

3270
			_gl.uniform1fv( material.program.uniforms.morphTargetInfluences, object.__webglMorphTargetInfluences );
M
Mr.doob 已提交
3271

3272 3273
		}

M
Mikael Emtinger 已提交
3274 3275 3276
	}


3277
	function renderBufferImmediate( object, program, shading ) {
3278

3279 3280
		if ( ! object.__webglVertexBuffer ) object.__webglVertexBuffer = _gl.createBuffer();
		if ( ! object.__webglNormalBuffer ) object.__webglNormalBuffer = _gl.createBuffer();
3281

A
alteredq 已提交
3282
		if ( object.hasPos ) {
3283

3284 3285 3286 3287
			_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 );
3288

A
alteredq 已提交
3289
		}
3290

A
alteredq 已提交
3291
		if ( object.hasNormal ) {
3292

3293
			_gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglNormalBuffer );
3294

3295
			if ( shading === THREE.FlatShading ) {
3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321

				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 已提交
3322
					normalArray[ i ] 	 = nx;
3323 3324 3325
					normalArray[ i + 1 ] = ny;
					normalArray[ i + 2 ] = nz;

M
Mr.doob 已提交
3326
					normalArray[ i + 3 ] = nx;
3327 3328 3329
					normalArray[ i + 4 ] = ny;
					normalArray[ i + 5 ] = nz;

M
Mr.doob 已提交
3330
					normalArray[ i + 6 ] = nx;
3331 3332 3333 3334 3335 3336 3337
					normalArray[ i + 7 ] = ny;
					normalArray[ i + 8 ] = nz;

				}

			}

3338 3339 3340
			_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 );
3341

A
alteredq 已提交
3342
		}
3343

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

A
alteredq 已提交
3346
		object.count = 0;
3347

A
alteredq 已提交
3348
	};
3349

3350
	function setObjectFaces( object ) {
3351

3352
		if ( _oldDoubleSided !== object.doubleSided ) {
3353

3354
			if( object.doubleSided ) {
3355

3356
				_gl.disable( _gl.CULL_FACE );
3357

3358
			} else {
3359

A
alteredq 已提交
3360
				_gl.enable( _gl.CULL_FACE );
3361

A
alteredq 已提交
3362
			}
3363

3364
			_oldDoubleSided = object.doubleSided;
3365

3366
		}
3367

3368
		if ( _oldFlipSided !== object.flipSided ) {
3369

3370 3371 3372 3373
			if( object.flipSided ) {

				_gl.frontFace( _gl.CW );

3374
			} else {
3375 3376 3377 3378

				_gl.frontFace( _gl.CCW );

			}
3379

3380
			_oldFlipSided = object.flipSided;
3381 3382

		}
3383

3384
	};
3385

M
Mr.doob 已提交
3386
	function setDepthTest( depthTest ) {
3387

3388
		if ( _oldDepthTest !== depthTest ) {
A
alteredq 已提交
3389

M
Mr.doob 已提交
3390
			if( depthTest ) {
3391

A
alteredq 已提交
3392
				_gl.enable( _gl.DEPTH_TEST );
3393

A
alteredq 已提交
3394
			} else {
3395

A
alteredq 已提交
3396
				_gl.disable( _gl.DEPTH_TEST );
3397

A
alteredq 已提交
3398
			}
3399

M
Mr.doob 已提交
3400 3401 3402 3403 3404 3405 3406 3407
			_oldDepthTest = depthTest;

		}

	};

	function setDepthWrite( depthWrite ) {

3408
		if ( _oldDepthWrite !== depthWrite ) {
M
Mr.doob 已提交
3409 3410 3411

			_gl.depthMask( depthWrite );
			_oldDepthWrite = depthWrite;
A
alteredq 已提交
3412 3413

		}
3414

A
alteredq 已提交
3415
	};
M
Mr.doob 已提交
3416 3417 3418

	function setPolygonOffset ( polygonoffset, factor, units ) {

3419
		if ( _oldPolygonOffset !== polygonoffset ) {
M
Mr.doob 已提交
3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434

			if ( polygonoffset ) {

				_gl.enable( _gl.POLYGON_OFFSET_FILL );

			} else {

				_gl.disable( _gl.POLYGON_OFFSET_FILL );

			}

			_oldPolygonOffset = polygonoffset;

		}

3435
		if ( polygonoffset && ( _oldPolygonOffsetFactor !== factor || _oldPolygonOffsetUnits !== units ) ) {
M
Mr.doob 已提交
3436 3437 3438 3439 3440 3441 3442 3443 3444

			_gl.polygonOffset( factor, units );

			_oldPolygonOffsetFactor = factor;
			_oldPolygonOffsetUnits = units;

		}

	};
3445

M
Mr.doob 已提交
3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481
	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;

	};

3482
	function addToFixedArray( where, what ) {
3483

3484 3485
		where.list[ where.count ] = what;
		where.count += 1;
3486

3487
	};
3488

3489
	function unrollImmediateBufferMaterial( globject ) {
3490

3491 3492
		var object = globject.object,
			material = object.material;
3493

3494
		if ( material.transparent ) {
3495

3496 3497
			globject.transparent = material;
			globject.opaque = null;
3498

3499 3500 3501 3502
		} else {

			globject.opaque = material;
			globject.transparent = null;
3503

3504
		}
3505

3506
	};
3507

3508
	function unrollBufferMaterial( globject ) {
3509

3510
		var object = globject.object,
3511
			buffer = globject.buffer,
3512 3513 3514 3515 3516 3517 3518
			material, materialIndex, meshMaterial;

		meshMaterial = object.material;

		if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {

			materialIndex = buffer.materialIndex;
3519

3520
			if ( materialIndex >= 0 ) {
3521

3522
				material = object.geometry.materials[ materialIndex ];
3523

3524
				if ( material.transparent ) {
3525

3526 3527
					globject.transparent = material;
					globject.opaque = null;
3528

3529
				} else {
3530

3531 3532
					globject.opaque = material;
					globject.transparent = null;
3533 3534 3535

				}

3536 3537 3538
			}

		} else {
3539

3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554
			material = meshMaterial;

			if ( material ) {

				if ( material.transparent ) {

					globject.transparent = material;
					globject.opaque = null;

				} else {

					globject.opaque = material;
					globject.transparent = null;

				}
3555

3556 3557 3558
			}

		}
3559

3560
	};
3561

3562
	function painterSort( a, b ) {
3563

3564
		return b.z - a.z;
3565 3566

	};
3567

3568 3569 3570
	function renderShadowMap( scene, camera ) {

		var i, il, light,
3571 3572
			j = 0,
			shadowMap, shadowMatrix,
3573 3574 3575
			oil,
			material,
			o, ol, webglObject, object,
3576
			lights = scene.lights,
3577 3578 3579 3580
			fog = null;

		if ( ! _cameraLight ) {

M
Mr.doob 已提交
3581
			_cameraLight = new THREE.PerspectiveCamera( _this.shadowCameraFov, _this.shadowMapWidth / _this.shadowMapHeight, _this.shadowCameraNear, _this.shadowCameraFar );
3582 3583 3584 3585 3586 3587 3588 3589 3590

		}

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

			light = lights[ i ];

			if ( light instanceof THREE.SpotLight && light.castShadow ) {

M
Mr.doob 已提交
3591 3592
				_currentMaterialId = -1;

3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608
				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 ];

3609
				_cameraLight.position.copy( light.position );
M
Mr.doob 已提交
3610
				_cameraLight.lookAt( light.target.position );
3611

3612
				_cameraLight.update( undefined, true );
3613

3614
				scene.update( undefined, false, _cameraLight );
3615

3616 3617
				// compute shadow matrix

3618 3619 3620 3621
				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 );
3622

3623 3624
				shadowMatrix.multiplySelf( _cameraLight.projectionMatrix );
				shadowMatrix.multiplySelf( _cameraLight.matrixWorldInverse );
3625 3626 3627 3628 3629 3630 3631 3632 3633

				// render shadow map

				_cameraLight.matrixWorldInverse.flattenToArray( _viewMatrixArray );
				_cameraLight.projectionMatrix.flattenToArray( _projectionMatrixArray );

				_projScreenMatrix.multiply( _cameraLight.projectionMatrix, _cameraLight.matrixWorldInverse );
				computeFrustum( _projScreenMatrix );

3634
				setRenderTarget( shadowMap );
3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658

				// 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 已提交
3659
						if ( ! ( object instanceof THREE.Mesh ) || ! ( object.frustumCulled ) || isInFrustum( object ) ) {
3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696

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

3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709
						if ( object.customDepthMaterial ) {

							material =  object.customDepthMaterial;

						} else if ( object.geometry.morphTargets.length ) {

							material =  _depthMaterialMorph;

						} else {

							material = _depthMaterial;

						}
3710 3711 3712 3713 3714 3715 3716 3717

						renderBuffer( _cameraLight, lights, fog, material, buffer, object );

					}

				}


3718
				for ( o = 0; o < oil; o ++ ) {
3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730

					webglObject = scene.__webglObjectsImmediate[ o ];
					object = webglObject.object;

					if ( object.visible && object.castShadow ) {

						if( object.matrixAutoUpdate ) {

							object.matrixWorld.flattenToArray( object._objectMatrixArray );

						}

M
Mr.doob 已提交
3731 3732
						_currentGeometryGroupHash = -1;

3733 3734 3735 3736 3737
						setupMatrices( object, _cameraLight, false );

						setObjectFaces( object );

						program = setProgram( _cameraLight, lights, fog, _depthMaterial, object );
M
Mr.doob 已提交
3738 3739 3740 3741 3742 3743 3744 3745 3746 3747

						if ( object.immediateRenderCallback ) {

							object.immediateRenderCallback( program, _gl, _frustum );

						} else {

							object.render( function( object ) { renderBufferImmediate( object, program, _depthMaterial.shading ); } );

						}
3748 3749 3750 3751 3752 3753 3754

					}

				}

				//_gl.cullFace( _gl.BACK );

3755 3756
				j ++;

3757 3758 3759 3760 3761 3762
			}

		}

	};

M
Mr.doob 已提交
3763
	this.clearTarget = function ( renderTarget, color, depth, stencil ) {
3764 3765

		setRenderTarget( renderTarget );
M
Mr.doob 已提交
3766
		this.clear( color, depth, stencil );
3767 3768 3769

	};

3770 3771 3772 3773 3774 3775
	this.updateShadowMap = function ( scene, camera ) {

		renderShadowMap( scene, camera );

	};

3776
	this.render = function( scene, camera, renderTarget, forceClear ) {
3777

3778
		var i, program, material,
3779
			o, ol, oil, webglObject, object, buffer,
3780
			lights = scene.lights,
N
Nicholas Kinsey 已提交
3781
			fog = scene.fog;
3782

M
Mr.doob 已提交
3783 3784
		_currentMaterialId = -1;

3785 3786 3787
		if ( this.autoUpdateObjects ) this.initWebGLObjects( scene );

		if ( this.shadowMapEnabled && this.shadowMapAutoUpdate ) renderShadowMap( scene, camera );
3788

M
Mr.doob 已提交
3789 3790 3791
		_this.info.render.calls = 0;
		_this.info.render.vertices = 0;
		_this.info.render.faces = 0;
3792

3793
		// hack: find parent of camera.
3794

3795
		if ( camera.matrixAutoUpdate ) {
3796

3797 3798 3799 3800 3801
			var parent = camera;

			while ( parent.parent ) {

				parent = parent.parent;
3802

3803 3804 3805
			}

			parent.update( undefined, true );
M
Mr.doob 已提交
3806

3807 3808 3809
		}

		scene.update( undefined, false, camera );
3810

M
Mr.doob 已提交
3811
		camera.matrixWorldInverse.flattenToArray( _viewMatrixArray );
3812
		camera.projectionMatrix.flattenToArray( _projectionMatrixArray );
M
Mr.doob 已提交
3813

M
Mr.doob 已提交
3814
		_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
M
Mr.doob 已提交
3815
		computeFrustum( _projScreenMatrix );
3816

M
Mr.doob 已提交
3817
		setRenderTarget( renderTarget );
M
Mr.doob 已提交
3818

M
Mr.doob 已提交
3819
		if ( this.autoClear || forceClear ) {
M
Mr.doob 已提交
3820

M
Mr.doob 已提交
3821
			this.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil );
M
Mr.doob 已提交
3822

3823 3824
		}

3825
		// set matrices
3826

3827
		ol = scene.__webglObjects.length;
3828

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

3831 3832
			webglObject = scene.__webglObjects[ o ];
			object = webglObject.object;
M
Mr.doob 已提交
3833

3834
			if ( object.visible ) {
3835

A
alteredq 已提交
3836
				if ( ! ( object instanceof THREE.Mesh ) || ! ( object.frustumCulled ) || isInFrustum( object ) ) {
3837

3838
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
3839

3840
					setupMatrices( object, camera, true );
3841

3842
					unrollBufferMaterial( webglObject );
3843

3844
					webglObject.render = true;
3845

3846
					if ( this.sortObjects ) {
3847

3848
						if ( object.renderDepth ) {
M
Mr.doob 已提交
3849

3850
							webglObject.z = object.renderDepth;
M
Mr.doob 已提交
3851

3852
						} else {
M
Mr.doob 已提交
3853

3854 3855
							_vector3.copy( object.position );
							_projScreenMatrix.multiplyVector3( _vector3 );
M
Mr.doob 已提交
3856

3857
							webglObject.z = _vector3.z;
M
Mr.doob 已提交
3858

3859
						}
3860

3861
					}
3862

3863
				} else {
3864

3865
					webglObject.render = false;
3866

3867
				}
3868

3869
			} else {
3870

3871
				webglObject.render = false;
3872

3873
			}
3874

3875
		}
3876

3877
		if ( this.sortObjects ) {
3878

3879
			scene.__webglObjects.sort( painterSort );
3880

3881
		}
3882

3883
		oil = scene.__webglObjectsImmediate.length;
3884

3885
		for ( o = 0; o < oil; o ++ ) {
3886

3887 3888
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
3889

3890
			if ( object.visible ) {
3891 3892 3893

				if( object.matrixAutoUpdate ) {

3894
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
3895

A
alteredq 已提交
3896
				}
3897

3898
				setupMatrices( object, camera, true );
3899

3900
				unrollImmediateBufferMaterial( webglObject );
3901

3902
			}
3903

3904
		}
A
alteredq 已提交
3905

M
Mr.doob 已提交
3906
		if ( scene.overrideMaterial ) {
3907

M
Mr.doob 已提交
3908 3909
			setDepthTest( scene.overrideMaterial.depthTest );
			setBlending( scene.overrideMaterial.blending );
3910

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

M
Mr.doob 已提交
3913 3914 3915
				webglObject = scene.__webglObjects[ o ];

				if ( webglObject.render ) {
3916

M
Mr.doob 已提交
3917 3918
					object = webglObject.object;
					buffer = webglObject.buffer;
3919

M
Mr.doob 已提交
3920 3921 3922 3923 3924 3925 3926 3927
					setObjectFaces( object );

					renderBuffer( camera, lights, fog, scene.overrideMaterial, buffer, object );

				}

			}

3928
			for ( o = 0; o < oil; o ++ ) {
M
Mr.doob 已提交
3929 3930

				webglObject = scene.__webglObjectsImmediate[ o ];
3931
				object = webglObject.object;
3932

M
Mr.doob 已提交
3933 3934
				if ( object.visible ) {

M
Mr.doob 已提交
3935 3936
					_currentGeometryGroupHash = -1;

M
Mr.doob 已提交
3937 3938 3939
					setObjectFaces( object );

					program = setProgram( camera, lights, fog, scene.overrideMaterial, object );
M
Mr.doob 已提交
3940 3941 3942 3943 3944 3945 3946 3947 3948 3949

					if ( object.immediateRenderCallback ) {

						object.immediateRenderCallback( program, _gl, _frustum );

					} else {

						object.render( function( object ) { renderBufferImmediate( object, program, scene.overrideMaterial.shading ); } );

					}
M
Mr.doob 已提交
3950 3951 3952 3953 3954 3955 3956 3957

				}

			}

		} else {

			// opaque pass
3958
			// (front-to-back order)
M
Mr.doob 已提交
3959 3960 3961

			setBlending( THREE.NormalBlending );

3962
			for ( o = ol - 1; o >= 0; o -- ) {
M
Mr.doob 已提交
3963 3964 3965 3966 3967 3968 3969

				webglObject = scene.__webglObjects[ o ];

				if ( webglObject.render ) {

					object = webglObject.object;
					buffer = webglObject.buffer;
3970
					material = webglObject.opaque;
3971

3972
					if ( ! material ) continue;
3973

3974
					setObjectFaces( object );
3975

3976 3977 3978 3979
					setDepthTest( material.depthTest );
					setDepthWrite( material.depthWrite );
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
					renderBuffer( camera, lights, fog, material, buffer, object );
3980

3981
				}
3982 3983 3984

			}

M
Mr.doob 已提交
3985
			// opaque pass (immediate simulator)
3986

3987
			for ( o = 0; o < oil; o ++ ) {
3988

M
Mr.doob 已提交
3989 3990
				webglObject = scene.__webglObjectsImmediate[ o ];
				object = webglObject.object;
3991

M
Mr.doob 已提交
3992
				if ( object.visible ) {
3993

M
Mr.doob 已提交
3994 3995
					_currentGeometryGroupHash = -1;

3996
					material = webglObject.opaque;
3997

3998
					if ( ! material ) continue;
3999

4000
					setObjectFaces( object );
4001

4002 4003 4004
					setDepthTest( material.depthTest );
					setDepthWrite( material.depthWrite );
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
M
Mr.doob 已提交
4005

4006
					program = setProgram( camera, lights, fog, material, object );
M
Mr.doob 已提交
4007

4008
					if ( object.immediateRenderCallback ) {
M
Mr.doob 已提交
4009

4010
						object.immediateRenderCallback( program, _gl, _frustum );
M
Mr.doob 已提交
4011

4012
					} else {
M
Mr.doob 已提交
4013

4014
						object.render( function( object ) { renderBufferImmediate( object, program, material.shading ); } );
4015

M
Mr.doob 已提交
4016
					}
4017

4018
				}
4019

A
alteredq 已提交
4020
			}
4021

M
Mr.doob 已提交
4022
			// transparent pass
4023
			// (back-to-front order)
A
alteredq 已提交
4024

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

M
Mr.doob 已提交
4027
				webglObject = scene.__webglObjects[ o ];
4028

M
Mr.doob 已提交
4029
				if ( webglObject.render ) {
4030

M
Mr.doob 已提交
4031 4032
					object = webglObject.object;
					buffer = webglObject.buffer;
4033
					material = webglObject.transparent;
4034

4035
					if ( ! material ) continue;
4036

4037
					setObjectFaces( object );
4038

4039 4040 4041 4042
					setBlending( material.blending );
					setDepthTest( material.depthTest );
					setDepthWrite( material.depthWrite );
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
4043

4044
					renderBuffer( camera, lights, fog, material, buffer, object );
4045

4046
				}
4047

4048
			}
M
Mr.doob 已提交
4049

M
Mr.doob 已提交
4050
			// transparent pass (immediate simulator)
M
Mr.doob 已提交
4051

4052
			for ( o = 0; o < oil; o ++ ) {
4053

M
Mr.doob 已提交
4054 4055
				webglObject = scene.__webglObjectsImmediate[ o ];
				object = webglObject.object;
4056

M
Mr.doob 已提交
4057
				if ( object.visible ) {
4058

M
Mr.doob 已提交
4059 4060
					_currentGeometryGroupHash = -1;

4061
					material = webglObject.transparent;
4062

4063
					if ( ! material ) continue;
4064

4065
					setObjectFaces( object );
4066

4067 4068 4069 4070
					setBlending( material.blending );
					setDepthTest( material.depthTest );
					setDepthWrite( material.depthWrite );
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
M
Mr.doob 已提交
4071

4072
					program = setProgram( camera, lights, fog, material, object );
M
Mr.doob 已提交
4073

4074
					if ( object.immediateRenderCallback ) {
M
Mr.doob 已提交
4075

4076
						object.immediateRenderCallback( program, _gl, _frustum );
M
Mr.doob 已提交
4077

4078
					} else {
M
Mr.doob 已提交
4079

4080
						object.render( function( object ) { renderBufferImmediate( object, program, material.shading ); } );
4081

M
Mr.doob 已提交
4082
					}
4083

4084
				}
4085

4086
			}
4087

4088
		}
4089

M
Mikael Emtinger 已提交
4090
		// render 2d
4091

M
Mr.doob 已提交
4092
		if ( scene.__webglSprites.length ) {
4093

4094
			renderSprites( scene, camera );
4095

M
Mikael Emtinger 已提交
4096 4097
		}

M
Mikael Emtinger 已提交
4098 4099 4100 4101 4102 4103 4104 4105
		// Generate mipmap if we're using any kind of mipmap filtering

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

			updateRenderTargetMipmap( renderTarget );

		}

4106
		//_gl.finish();
4107

M
Mikael Emtinger 已提交
4108 4109
	};

4110 4111
	/*
	 * Render sprites
M
Mr.doob 已提交
4112
	 *
4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127
	 */

	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
4128

4129 4130
		_gl.useProgram( _sprite.program );
		_currentProgram = _sprite.program;
4131
		_oldBlending = -1;
M
Mr.doob 已提交
4132 4133
		_oldDepthTest = -1;
		_currentGeometryGroupHash = -1;
4134

M
Mr.doob 已提交
4135
		if ( !_spriteAttributesEnabled ) {
4136

M
Mr.doob 已提交
4137 4138
			_gl.enableVertexAttribArray( _sprite.attributes.position );
			_gl.enableVertexAttribArray( _sprite.attributes.uv );
4139

M
Mr.doob 已提交
4140 4141 4142
			_spriteAttributesEnabled = true;

		}
4143

4144
		_gl.disable( _gl.CULL_FACE );
4145
		_gl.enable( _gl.BLEND );
4146
		_gl.depthMask( true );
4147 4148 4149 4150 4151 4152

		_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 );
4153

4154 4155 4156 4157
		_gl.uniformMatrix4fv( uniforms.projectionMatrix, false, _projectionMatrixArray );

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

4159
		// update positions and sort
4160

M
Mr.doob 已提交
4161
		for( o = 0, ol = scene.__webglSprites.length; o < ol; o ++ ) {
4162

4163
			object = scene.__webglSprites[ o ];
4164

4165
			if ( !object.visible || object.opacity === 0 ) continue;
M
Mr.doob 已提交
4166

4167
			if( !object.useScreenCoordinates ) {
4168

4169 4170
				object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
				object.z = -object._modelViewMatrix.n34;
4171

4172
			} else {
4173

4174
				object.z = -object.position.z;
4175

4176
			}
4177

4178 4179 4180
		}

		scene.__webglSprites.sort( painterSort );
4181

M
Mr.doob 已提交
4182
		// render all sprites
4183

M
Mr.doob 已提交
4184
		for ( o = 0, ol = scene.__webglSprites.length; o < ol; o ++ ) {
4185 4186 4187

			object = scene.__webglSprites[ o ];

4188
			if ( !object.visible || object.opacity === 0 ) continue;
4189

M
Mr.doob 已提交
4190
			if ( object.map && object.map.image && object.map.image.width ) {
4191

M
Mr.doob 已提交
4192
				if ( object.useScreenCoordinates ) {
4193

M
Mr.doob 已提交
4194 4195 4196 4197
					_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 )));
4198

M
Mr.doob 已提交
4199
				} else {
4200

M
Mr.doob 已提交
4201 4202 4203
					_gl.uniform1i( uniforms.useScreenCoordinates, 0 );
					_gl.uniform1i( uniforms.affectedByDistance, object.affectedByDistance ? 1 : 0 );
					_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray );
4204

M
Mr.doob 已提交
4205
				}
4206

M
Mr.doob 已提交
4207
				size = object.map.image.width / ( object.scaleByViewport ? _viewportHeight : 1 );
4208

M
Mr.doob 已提交
4209 4210
				scale[ 0 ] = size * invAspect * object.scale.x;
				scale[ 1 ] = size * object.scale.y;
4211

M
Mr.doob 已提交
4212 4213 4214
				_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 );
4215

M
Mr.doob 已提交
4216 4217
				_gl.uniform1f( uniforms.opacity, object.opacity );
				_gl.uniform3f( uniforms.color, object.color.r, object.color.g, object.color.b );
4218

M
Mr.doob 已提交
4219 4220
				_gl.uniform1f( uniforms.rotation, object.rotation );
				_gl.uniform2fv( uniforms.scale, scale );
4221

M
Mr.doob 已提交
4222
				if ( object.mergeWith3D && !mergeWith3D ) {
4223

M
Mr.doob 已提交
4224 4225
					_gl.enable( _gl.DEPTH_TEST );
					mergeWith3D = true;
4226

M
Mr.doob 已提交
4227
				} else if ( !object.mergeWith3D && mergeWith3D ) {
4228

M
Mr.doob 已提交
4229 4230
					_gl.disable( _gl.DEPTH_TEST );
					mergeWith3D = false;
4231

4232
				}
4233

M
Mr.doob 已提交
4234 4235
				setBlending( object.blending );
				setTexture( object.map, 0 );
4236

M
Mr.doob 已提交
4237
				_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
4238

4239
			}
4240

4241 4242 4243 4244 4245 4246 4247
		}


		// restore gl

		_gl.enable( _gl.CULL_FACE );
		_gl.enable( _gl.DEPTH_TEST );
M
Mr.doob 已提交
4248
		_gl.depthMask( _oldDepthWrite );
4249 4250 4251

	}

4252
	function setupMatrices( object, camera, computeNormalMatrix ) {
4253

4254
		object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
4255 4256 4257 4258 4259 4260

		if ( computeNormalMatrix ) {

			THREE.Matrix4.makeInvert3x3( object._modelViewMatrix ).transposeIntoArray( object._normalMatrixArray );

		}
4261

M
Mr.doob 已提交
4262
	}
4263

A
alteredq 已提交
4264
	this.initWebGLObjects = function ( scene ) {
4265

4266
		if ( !scene.__webglObjects ) {
4267

4268 4269
			scene.__webglObjects = [];
			scene.__webglObjectsImmediate = [];
M
Mikael Emtinger 已提交
4270
			scene.__webglSprites = [];
4271

4272 4273
		}

M
Mr.doob 已提交
4274
		while ( scene.__objectsAdded.length ) {
4275

M
Mr.doob 已提交
4276 4277
			addObject( scene.__objectsAdded[ 0 ], scene );
			scene.__objectsAdded.splice( 0, 1 );
4278 4279 4280

		}

M
Mr.doob 已提交
4281
		while ( scene.__objectsRemoved.length ) {
4282

M
Mr.doob 已提交
4283 4284
			removeObject( scene.__objectsRemoved[ 0 ], scene );
			scene.__objectsRemoved.splice( 0, 1 );
4285 4286

		}
4287

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

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

4292
			updateObject( scene.__webglObjects[ o ].object );
A
alteredq 已提交
4293 4294

		}
4295

4296
	};
4297

M
Mr.doob 已提交
4298
	function addObject( object, scene ) {
4299

M
Mr.doob 已提交
4300
		var g, geometry, geometryGroup;
4301

M
Mr.doob 已提交
4302
		if ( ! object.__webglInit ) {
4303

M
Mr.doob 已提交
4304
			object.__webglInit = true;
M
Mr.doob 已提交
4305

M
Mr.doob 已提交
4306
			object._modelViewMatrix = new THREE.Matrix4();
A
alteredq 已提交
4307

M
Mr.doob 已提交
4308 4309 4310
			object._normalMatrixArray = new Float32Array( 9 );
			object._modelViewMatrixArray = new Float32Array( 16 );
			object._objectMatrixArray = new Float32Array( 16 );
4311

M
Mr.doob 已提交
4312
			object.matrixWorld.flattenToArray( object._objectMatrixArray );
4313

M
Mr.doob 已提交
4314
			if ( object instanceof THREE.Mesh ) {
4315

M
Mr.doob 已提交
4316
				geometry = object.geometry;
4317

4318
				if ( geometry.geometryGroups === undefined ) {
A
alteredq 已提交
4319

M
Mr.doob 已提交
4320
					sortFacesByMaterial( geometry );
A
alteredq 已提交
4321

M
Mr.doob 已提交
4322
				}
M
Mr.doob 已提交
4323

M
Mr.doob 已提交
4324
				// create separate VBOs per geometry chunk
M
Mr.doob 已提交
4325

M
Mr.doob 已提交
4326
				for ( g in geometry.geometryGroups ) {
M
Mr.doob 已提交
4327

M
Mr.doob 已提交
4328
					geometryGroup = geometry.geometryGroups[ g ];
A
alteredq 已提交
4329

M
Mr.doob 已提交
4330
					// initialise VBO on the first access
M
Mr.doob 已提交
4331

M
Mr.doob 已提交
4332
					if ( ! geometryGroup.__webglVertexBuffer ) {
4333

M
Mr.doob 已提交
4334 4335
						createMeshBuffers( geometryGroup );
						initMeshBuffers( geometryGroup, object );
M
Mr.doob 已提交
4336

M
Mr.doob 已提交
4337 4338 4339 4340 4341 4342 4343
						geometry.__dirtyVertices = true;
						geometry.__dirtyMorphTargets = true;
						geometry.__dirtyElements = true;
						geometry.__dirtyUvs = true;
						geometry.__dirtyNormals = true;
						geometry.__dirtyTangents = true;
						geometry.__dirtyColors = true;
A
alteredq 已提交
4344

M
Mr.doob 已提交
4345
					}
4346

M
Mr.doob 已提交
4347
				}
A
alteredq 已提交
4348

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

M
Mr.doob 已提交
4351
				geometry = object.geometry;
A
alteredq 已提交
4352

M
Mr.doob 已提交
4353
				if( ! geometry.__webglVertexBuffer ) {
A
alteredq 已提交
4354

M
Mr.doob 已提交
4355 4356
					createRibbonBuffers( geometry );
					initRibbonBuffers( geometry );
M
Mr.doob 已提交
4357

M
Mr.doob 已提交
4358 4359
					geometry.__dirtyVertices = true;
					geometry.__dirtyColors = true;
4360

M
Mr.doob 已提交
4361
				}
M
Mr.doob 已提交
4362

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

M
Mr.doob 已提交
4365
				geometry = object.geometry;
M
Mr.doob 已提交
4366

M
Mr.doob 已提交
4367
				if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
4368

M
Mr.doob 已提交
4369 4370
					createLineBuffers( geometry );
					initLineBuffers( geometry );
A
alteredq 已提交
4371

M
Mr.doob 已提交
4372 4373
					geometry.__dirtyVertices = true;
					geometry.__dirtyColors = true;
A
alteredq 已提交
4374

M
Mr.doob 已提交
4375
				}
A
alteredq 已提交
4376

M
Mr.doob 已提交
4377
			} else if ( object instanceof THREE.ParticleSystem ) {
A
alteredq 已提交
4378

M
Mr.doob 已提交
4379
				geometry = object.geometry;
4380

M
Mr.doob 已提交
4381
				if ( ! geometry.__webglVertexBuffer ) {
4382

M
Mr.doob 已提交
4383 4384
					createParticleBuffers( geometry );
					initParticleBuffers( geometry, object );
M
Mr.doob 已提交
4385

M
Mr.doob 已提交
4386 4387
					geometry.__dirtyVertices = true;
					geometry.__dirtyColors = true;
M
Mr.doob 已提交
4388

M
Mr.doob 已提交
4389
				}
M
Mr.doob 已提交
4390

M
Mr.doob 已提交
4391
			}
M
Mr.doob 已提交
4392

M
Mr.doob 已提交
4393
		}
M
Mr.doob 已提交
4394

M
Mr.doob 已提交
4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413
		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;
4414
				addBuffer( scene.__webglObjects, geometry, object );
M
Mr.doob 已提交
4415

M
Mr.doob 已提交
4416
			} else if ( THREE.MarchingCubes !== undefined && object instanceof THREE.MarchingCubes || object.immediateRenderCallback ) {
A
alteredq 已提交
4417

4418
				addBufferImmediate( scene.__webglObjectsImmediate, object );
A
alteredq 已提交
4419

4420
			} else if ( object instanceof THREE.Sprite ) {
4421

4422
				scene.__webglSprites.push( object );
4423

4424
			}
4425

M
Mr.doob 已提交
4426
			object.__webglActive = true;
4427 4428

		}
A
alteredq 已提交
4429 4430 4431

	};

4432
	function areCustomAttributesDirty( material ) {
4433

4434
		for ( var a in material.attributes ) {
4435

4436
			if ( material.attributes[ a ].needsUpdate ) return true;
4437 4438 4439 4440 4441 4442 4443

		}

		return false;

	};

4444
	function clearCustomAttributes( material ) {
4445

4446
		for ( var a in material.attributes ) {
4447

4448
			material.attributes[ a ].needsUpdate = false;
4449 4450 4451 4452 4453

		}

	};

4454
	function updateObject( object ) {
A
alteredq 已提交
4455

4456 4457
		var geometry = object.geometry,
			geometryGroup, customAttributesDirty, material;
A
alteredq 已提交
4458 4459 4460 4461 4462

		if ( object instanceof THREE.Mesh ) {

			// check all geometry groups

4463
			for( var i = 0, il = geometry.geometryGroupsList.length; i < il; i ++ ) {
A
alteredq 已提交
4464

4465
				geometryGroup = geometry.geometryGroupsList[ i ];
A
alteredq 已提交
4466

4467 4468 4469
				material = getBufferMaterial( object, geometryGroup );

				customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
4470

4471
				if ( geometry.__dirtyVertices || geometry.__dirtyMorphTargets || geometry.__dirtyElements ||
4472
					 geometry.__dirtyUvs || geometry.__dirtyNormals ||
4473
					 geometry.__dirtyColors || geometry.__dirtyTangents || customAttributesDirty ) {
A
alteredq 已提交
4474

4475
					setMeshBuffers( geometryGroup, object, _gl.DYNAMIC_DRAW, !geometry.dynamic );
A
alteredq 已提交
4476 4477 4478 4479 4480

				}

			}

4481
			geometry.__dirtyVertices = false;
4482
			geometry.__dirtyMorphTargets = false;
A
alteredq 已提交
4483 4484 4485
			geometry.__dirtyElements = false;
			geometry.__dirtyUvs = false;
			geometry.__dirtyNormals = false;
4486
			geometry.__dirtyColors = false;
4487
			geometry.__dirtyTangents = false;
M
Mr.doob 已提交
4488

4489
			material.attributes && clearCustomAttributes( material );
4490

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

4493
			if ( geometry.__dirtyVertices || geometry.__dirtyColors ) {
M
Mr.doob 已提交
4494

A
alteredq 已提交
4495
				setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
4496

A
alteredq 已提交
4497 4498 4499 4500 4501 4502 4503
			}

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

		} else if ( object instanceof THREE.Line ) {

4504
			if ( geometry.__dirtyVertices ||  geometry.__dirtyColors ) {
A
alteredq 已提交
4505 4506

				setLineBuffers( geometry, _gl.DYNAMIC_DRAW );
4507

4508
			}
4509

A
alteredq 已提交
4510 4511 4512 4513 4514
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;

		} else if ( object instanceof THREE.ParticleSystem ) {

4515
			material = getBufferMaterial( object, geometryGroup );
A
alteredq 已提交
4516

4517
			customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
4518

4519
			if ( geometry.__dirtyVertices || geometry.__dirtyColors || object.sortParticles || customAttributesDirty ) {
M
Mr.doob 已提交
4520

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

4523
			}
M
Mr.doob 已提交
4524

4525 4526
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
M
Mr.doob 已提交
4527

4528
			material.attributes && clearCustomAttributes( material );
4529

M
Mr.doob 已提交
4530
		}
4531

4532
	};
4533

4534
	function removeInstances( objlist, object ) {
M
Mr.doob 已提交
4535

4536
		for ( var o = objlist.length - 1; o >= 0; o -- ) {
M
Mr.doob 已提交
4537

4538
			if ( objlist[ o ].object === object ) {
4539

4540
				objlist.splice( o, 1 );
4541

4542
			}
4543

4544
		}
M
Mr.doob 已提交
4545

4546
	};
4547

4548 4549
	function removeInstancesDirect( objlist, object ) {

4550
		for ( var o = objlist.length - 1; o >= 0; o -- ) {
4551

4552
			if ( objlist[ o ] === object ) {
4553 4554 4555 4556 4557 4558 4559 4560 4561

				objlist.splice( o, 1 );

			}

		}

	};

4562
	function removeObject( object, scene ) {
4563

M
Mr.doob 已提交
4564
		if ( object instanceof THREE.Mesh  ||
4565 4566
			 object instanceof THREE.ParticleSystem ||
			 object instanceof THREE.Ribbon ||
4567
			 object instanceof THREE.Line ) {
4568

4569
			removeInstances( scene.__webglObjects, object );
4570

4571
		} else if ( object instanceof THREE.Sprite ) {
M
Mr.doob 已提交
4572

4573
			removeInstancesDirect( scene.__webglSprites, object );
M
Mr.doob 已提交
4574

M
Mr.doob 已提交
4575
		} else if ( object instanceof THREE.MarchingCubes || object.immediateRenderCallback ) {
4576

4577 4578 4579
			removeInstances( scene.__webglObjectsImmediate, object );

		}
M
Mr.doob 已提交
4580

M
Mr.doob 已提交
4581 4582
		object.__webglActive = false;

M
Mr.doob 已提交
4583 4584
	};

4585
	function sortFacesByMaterial( geometry ) {
4586

4587 4588 4589
		var f, fl, face, materialIndex, vertices,
			materialHash, groupHash,
			hash_map = {};
4590

4591
		var numMorphTargets = geometry.morphTargets.length;
4592 4593 4594

		geometry.geometryGroups = {};

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

			face = geometry.faces[ f ];
4598
			materialIndex = face.materialIndex;
4599

4600
			materialHash = ( materialIndex !== undefined ) ? materialIndex : -1;
4601

4602
			if ( hash_map[ materialHash ] === undefined ) {
4603

4604
				hash_map[ materialHash ] = { 'hash': materialHash, 'counter': 0 };
4605 4606 4607

			}

4608
			groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
4609

4610
			if ( geometry.geometryGroups[ groupHash ] === undefined ) {
4611

4612
				geometry.geometryGroups[ groupHash ] = { 'faces': [], 'materialIndex': materialIndex, 'vertices': 0, 'numMorphTargets': numMorphTargets };
4613 4614 4615 4616 4617

			}

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

4618
			if ( geometry.geometryGroups[ groupHash ].vertices + vertices > 65535 ) {
4619

4620 4621
				hash_map[ materialHash ].counter += 1;
				groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
4622

4623
				if ( geometry.geometryGroups[ groupHash ] === undefined ) {
4624

4625
					geometry.geometryGroups[ groupHash ] = { 'faces': [], 'materialIndex': materialIndex, 'vertices': 0, 'numMorphTargets': numMorphTargets };
4626 4627 4628 4629 4630

				}

			}

4631 4632
			geometry.geometryGroups[ groupHash ].faces.push( f );
			geometry.geometryGroups[ groupHash ].vertices += vertices;
4633 4634 4635

		}

4636 4637 4638 4639
		geometry.geometryGroupsList = [];

		for ( var g in geometry.geometryGroups ) {

M
Mr.doob 已提交
4640 4641
			geometry.geometryGroups[ g ].id = _geometryGroupCounter ++;

4642 4643 4644 4645
			geometry.geometryGroupsList.push( geometry.geometryGroups[ g ] );

		}

4646 4647
	};

4648
	function addBuffer( objlist, buffer, object ) {
4649

4650 4651 4652 4653 4654 4655 4656 4657
		objlist.push(
			{
				buffer: buffer,
				object: object,
				opaque: null,
				transparent: null
			}
		);
M
Mr.doob 已提交
4658

4659
	};
4660

4661
	function addBufferImmediate( objlist, object ) {
4662

4663 4664 4665 4666 4667 4668 4669
		objlist.push(
			{
				object: object,
				opaque: null,
				transparent: null
			}
		);
4670

4671
	};
4672

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

4675
		if ( cullFace ) {
M
Mr.doob 已提交
4676

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

4679
				_gl.frontFace( _gl.CCW );
M
Mr.doob 已提交
4680

4681
			} else {
M
Mr.doob 已提交
4682

4683
				_gl.frontFace( _gl.CW );
M
Mr.doob 已提交
4684

4685
			}
M
Mr.doob 已提交
4686

4687
			if( cullFace === "back" ) {
M
Mr.doob 已提交
4688

4689
				_gl.cullFace( _gl.BACK );
M
Mr.doob 已提交
4690

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

4693
				_gl.cullFace( _gl.FRONT );
M
Mr.doob 已提交
4694

4695
			} else {
M
Mr.doob 已提交
4696

4697
				_gl.cullFace( _gl.FRONT_AND_BACK );
M
Mr.doob 已提交
4698

4699
			}
M
Mr.doob 已提交
4700

4701
			_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
4702

4703
		} else {
M
Mr.doob 已提交
4704

4705
			_gl.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
4706

4707 4708 4709
		}

	};
N
Nicolas Garcia Belmonte 已提交
4710

4711
	this.supportsVertexTextures = function () {
4712

A
alteredq 已提交
4713
		return _supportsVertexTextures;
4714

4715
	};
4716

4717
	function maxVertexTextures() {
4718

4719 4720 4721
		return _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );

	};
4722

4723
	function buildProgram( shaderID, fragmentShader, vertexShader, uniforms, attributes, parameters ) {
4724

4725
		var p, pl, program, code;
4726
		var chunks = [];
4727 4728 4729

		// Generate code

4730 4731 4732 4733 4734 4735 4736 4737 4738 4739
		if ( shaderID ) {

			chunks.push( shaderID );

		} else {

			chunks.push( fragmentShader );
			chunks.push( vertexShader );

		}
4740 4741 4742

		for ( p in parameters ) {

4743 4744
			chunks.push( p );
			chunks.push( parameters[ p ] );
4745 4746 4747

		}

4748 4749
		code = chunks.join();

4750 4751 4752 4753
		// Check if code has been already compiled

		for ( p = 0, pl = _programs.length; p < pl; p ++ ) {

4754
			if ( _programs[ p ].code === code ) {
4755 4756

				// console.log( "Code already compiled." /*: \n\n" + code*/ );
4757

4758 4759 4760 4761 4762
				return _programs[ p ].program;

			}

		}
4763

4764
		//console.log( "building new program " );
4765 4766 4767

		//

4768
		program = _gl.createProgram();
M
Mr.doob 已提交
4769

4770
		var prefix_vertex = [
M
Mr.doob 已提交
4771

A
alteredq 已提交
4772
			_supportsVertexTextures ? "#define VERTEX_TEXTURES" : "",
4773

4774 4775 4776 4777
			_this.gammaInput ? "#define GAMMA_INPUT" : "",
			_this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
			_this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",

4778 4779 4780
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

4781 4782
			"#define MAX_SHADOWS " + parameters.maxShadows,

4783 4784
			"#define MAX_BONES " + parameters.maxBones,

4785
			parameters.map ? "#define USE_MAP" : "",
4786 4787 4788
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
4789
			parameters.skinning ? "#define USE_SKINNING" : "",
4790
			parameters.morphTargets ? "#define USE_MORPHTARGETS" : "",
4791

4792
			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
4793
			parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
4794

4795 4796
			parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",

M
Mr.doob 已提交
4797 4798 4799
			"uniform mat4 objectMatrix;",
			"uniform mat4 modelViewMatrix;",
			"uniform mat4 projectionMatrix;",
4800 4801
			"uniform mat4 viewMatrix;",
			"uniform mat3 normalMatrix;",
M
Mr.doob 已提交
4802
			"uniform vec3 cameraPosition;",
A
alteredq 已提交
4803 4804 4805

			"uniform mat4 cameraInverseMatrix;",

M
Mr.doob 已提交
4806 4807 4808
			"attribute vec3 position;",
			"attribute vec3 normal;",
			"attribute vec2 uv;",
4809
			"attribute vec2 uv2;",
4810

4811
			"#ifdef USE_COLOR",
4812

4813
				"attribute vec3 color;",
4814

4815 4816
			"#endif",

4817
			"#ifdef USE_MORPHTARGETS",
4818

4819 4820 4821 4822 4823 4824 4825 4826
				"attribute vec3 morphTarget0;",
				"attribute vec3 morphTarget1;",
				"attribute vec3 morphTarget2;",
				"attribute vec3 morphTarget3;",
				"attribute vec3 morphTarget4;",
				"attribute vec3 morphTarget5;",
				"attribute vec3 morphTarget6;",
				"attribute vec3 morphTarget7;",
4827

4828 4829 4830
			"#endif",

			"#ifdef USE_SKINNING",
4831

4832 4833 4834 4835
				"attribute vec4 skinVertexA;",
				"attribute vec4 skinVertexB;",
				"attribute vec4 skinIndex;",
				"attribute vec4 skinWeight;",
4836

4837
			"#endif",
4838

M
Mr.doob 已提交
4839
			""
A
alteredq 已提交
4840

M
Mr.doob 已提交
4841
		].join("\n");
4842

M
Mr.doob 已提交
4843 4844 4845 4846 4847 4848 4849 4850 4851
		var prefix_fragment = [

			"#ifdef GL_ES",
			"precision highp float;",
			"#endif",

			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

4852 4853
			"#define MAX_SHADOWS " + parameters.maxShadows,

4854 4855
			parameters.alphaTest ? "#define ALPHATEST " + parameters.alphaTest: "",

4856 4857 4858 4859
			_this.gammaInput ? "#define GAMMA_INPUT" : "",
			_this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
			_this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",

M
Mr.doob 已提交
4860 4861
			( parameters.useFog && parameters.fog ) ? "#define USE_FOG" : "",
			( parameters.useFog && parameters.fog instanceof THREE.FogExp2 ) ? "#define FOG_EXP2" : "",
M
Mr.doob 已提交
4862 4863 4864 4865 4866

			parameters.map ? "#define USE_MAP" : "",
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
4867

4868 4869 4870
			parameters.metal ? "#define METAL" : "",
			parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",

4871
			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
4872 4873 4874
			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 已提交
4875 4876 4877 4878 4879 4880 4881

			"uniform mat4 viewMatrix;",
			"uniform vec3 cameraPosition;",
			""

		].join("\n");

4882 4883
		_gl.attachShader( program, getShader( "fragment", prefix_fragment + fragmentShader ) );
		_gl.attachShader( program, getShader( "vertex", prefix_vertex + vertexShader ) );
M
Mr.doob 已提交
4884

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

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

4889
			console.error( "Could not initialise shader\n" + "VALIDATE_STATUS: " + _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) + ", gl error [" + _gl.getError() + "]" );
M
Mr.doob 已提交
4890

N
Nicolas Garcia Belmonte 已提交
4891
		}
4892

4893 4894
		//console.log( prefix_fragment + fragmentShader );
		//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
4895

M
Mr.doob 已提交
4896
		program.uniforms = {};
4897
		program.attributes = {};
M
Mr.doob 已提交
4898

4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916
		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 );
4917

4918 4919 4920 4921 4922 4923 4924 4925 4926
		// cache attributes locations

		identifiers = [

			"position", "normal", "uv", "uv2", "tangent", "color",
			"skinVertexA", "skinVertexB", "skinIndex", "skinWeight"

		];

4927
		for ( i = 0; i < parameters.maxMorphTargets; i ++ ) {
4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940

			identifiers.push( "morphTarget" + i );

		}

		for ( a in attributes ) {

			identifiers.push( a );

		}

		cacheAttributeLocations( program, identifiers );

M
Mr.doob 已提交
4941 4942
		program.id = _programs.length;

4943 4944
		_programs.push( { program: program, code: code } );

M
Mr.doob 已提交
4945 4946
		_this.info.memory.programs = _programs.length;

M
Mr.doob 已提交
4947
		return program;
M
Mr.doob 已提交
4948

M
Mr.doob 已提交
4949
	};
M
Mr.doob 已提交
4950

4951
	function loadUniformsSkinning( uniforms, object ) {
4952

M
Mr.doob 已提交
4953
		_gl.uniformMatrix4fv( uniforms.cameraInverseMatrix, false, _viewMatrixArray );
A
alteredq 已提交
4954
		_gl.uniformMatrix4fv( uniforms.boneGlobalMatrices, false, object.boneMatrices );
4955

4956
	};
4957

4958

4959
	function loadUniformsMatrices( uniforms, object ) {
4960

A
alteredq 已提交
4961
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray );
A
alteredq 已提交
4962 4963 4964 4965 4966 4967

		if ( uniforms.normalMatrix ) {

			_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrixArray );

		}
A
alteredq 已提交
4968 4969

	};
4970

4971
	function loadUniformsGeneric( program, uniforms ) {
M
Mr.doob 已提交
4972

M
Mr.doob 已提交
4973
		var uniform, value, type, location, texture, i, il, j, jl, offset;
M
Mr.doob 已提交
4974

M
Mr.doob 已提交
4975
		for( j = 0, jl = uniforms.length; j < jl; j ++ ) {
M
Mr.doob 已提交
4976

M
Mr.doob 已提交
4977
			location = program.uniforms[ uniforms[ j ][ 1 ] ];
4978
			if ( !location ) continue;
M
Mr.doob 已提交
4979

M
Mr.doob 已提交
4980
			uniform = uniforms[ j ][ 0 ];
M
Mr.doob 已提交
4981

4982 4983
			type = uniform.type;
			value = uniform.value;
M
Mr.doob 已提交
4984

4985 4986
			// single integer

4987
			if( type === "i" ) {
M
Mr.doob 已提交
4988

M
Mr.doob 已提交
4989
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
4990

4991 4992
			// single float

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

M
Mr.doob 已提交
4995
				_gl.uniform1f( location, value );
4996

4997 4998
			// single THREE.Vector2

4999
			} else if( type === "v2" ) {
5000 5001 5002 5003 5004

				_gl.uniform2f( location, value.x, value.y );

			// single THREE.Vector3

5005
			} else if( type === "v3" ) {
5006 5007 5008 5009 5010

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

			// single THREE.Vector4

5011
			} else if( type === "v4" ) {
5012 5013 5014 5015 5016

				_gl.uniform4f( location, value.x, value.y, value.z, value.w );

			// single THREE.Color

5017
			} else if( type === "c" ) {
5018 5019 5020 5021 5022

				_gl.uniform3f( location, value.r, value.g, value.b );

			// flat array of floats (JS or typed array)

5023
			} else if( type === "fv1" ) {
A
alteredq 已提交
5024 5025

				_gl.uniform1fv( location, value );
M
Mr.doob 已提交
5026

5027 5028
			// flat array of floats with 3 x N size (JS or typed array)

5029
			} else if( type === "fv" ) {
5030 5031 5032

				_gl.uniform3fv( location, value );

5033
			// array of THREE.Vector3
5034

5035
			} else if( type === "v3v" ) {
5036

5037
				if ( ! uniform._array ) {
5038

5039
					uniform._array = new Float32Array( 3 * value.length );
5040

5041
				}
5042

5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055
				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
5056

5057
			} else if( type === "m4" ) {
5058 5059 5060 5061 5062 5063 5064 5065 5066 5067

				if ( ! uniform._array ) {

					uniform._array = new Float32Array( 16 );

				}

				value.flattenToArray( uniform._array );
				_gl.uniformMatrix4fv( location, false, uniform._array );

5068 5069
			// array of THREE.Matrix4

5070
			} else if( type === "m4v" ) {
5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085

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

5086

5087
			// single THREE.Texture (2d or cube)
M
Mr.doob 已提交
5088

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

M
Mr.doob 已提交
5091
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
5092

5093
				texture = uniform.texture;
M
Mr.doob 已提交
5094

5095
				if ( !texture ) continue;
M
Mr.doob 已提交
5096

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

5099
					setCubeTexture( texture, value );
M
Mr.doob 已提交
5100

A
alteredq 已提交
5101 5102 5103 5104
				} else if ( texture instanceof THREE.WebGLRenderTargetCube ) {

					setCubeTextureDynamic( texture, value );

5105
				} else {
M
Mr.doob 已提交
5106

5107
					setTexture( texture, value );
M
Mr.doob 已提交
5108

5109
				}
M
Mr.doob 已提交
5110

5111 5112
			// array of THREE.Texture (2d)

5113
			} else if( type === "tv" ) {
5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138

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

				}

5139
			}
M
Mr.doob 已提交
5140

5141
		}
M
Mr.doob 已提交
5142

5143
	};
M
Mr.doob 已提交
5144

5145
	function setBlending( blending ) {
A
alteredq 已提交
5146

5147
		if ( blending !== _oldBlending ) {
5148

A
alteredq 已提交
5149 5150 5151 5152 5153
			switch ( blending ) {

				case THREE.AdditiveBlending:

					_gl.blendEquation( _gl.FUNC_ADD );
5154
					_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE );
A
alteredq 已提交
5155 5156 5157 5158 5159

					break;

				case THREE.SubtractiveBlending:

5160 5161 5162 5163
					// TODO: Find blendFuncSeparate() combination

					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.ZERO, _gl.ONE_MINUS_SRC_COLOR );
A
alteredq 已提交
5164 5165 5166

					break;

5167 5168 5169
				case THREE.MultiplyBlending:

					// TODO: Find blendFuncSeparate() combination
A
alteredq 已提交
5170 5171

					_gl.blendEquation( _gl.FUNC_ADD );
5172
					_gl.blendFunc( _gl.ZERO, _gl.SRC_COLOR );
A
alteredq 已提交
5173 5174 5175 5176 5177

					break;

				default:

5178 5179
					_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 已提交
5180 5181

					break;
5182

A
alteredq 已提交
5183
			}
5184

A
alteredq 已提交
5185
			_oldBlending = blending;
5186

A
alteredq 已提交
5187 5188 5189
		}

	};
5190

5191
	function setTextureParameters( textureType, texture, image ) {
5192

5193
		if ( isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ) ) {
M
Mr.doob 已提交
5194

5195 5196
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
M
Mr.doob 已提交
5197

5198 5199
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
M
Mr.doob 已提交
5200

5201
			_gl.generateMipmap( textureType );
M
Mr.doob 已提交
5202

5203
		} else {
M
Mr.doob 已提交
5204

5205 5206
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
5207

5208 5209
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
M
Mr.doob 已提交
5210

5211
		}
M
Mr.doob 已提交
5212

5213
	};
5214

5215
	function setTexture( texture, slot ) {
5216

5217
		if ( texture.needsUpdate ) {
A
alteredq 已提交
5218

5219
			if ( ! texture.__webglInit ) {
M
Mr.doob 已提交
5220

5221
				texture.__webglInit = true;
5222
				texture.__webglTexture = _gl.createTexture();
A
alteredq 已提交
5223

M
Mr.doob 已提交
5224 5225
				_this.info.memory.textures ++;

5226
			}
M
Mr.doob 已提交
5227

5228
			_gl.activeTexture( _gl.TEXTURE0 + slot );
5229 5230
			_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );

5231
			if ( texture instanceof THREE.DataTexture ) {
5232 5233

				_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 已提交
5234

A
alteredq 已提交
5235
			} else {
M
Mr.doob 已提交
5236

M
Mr.doob 已提交
5237
				_gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image );
M
Mr.doob 已提交
5238 5239 5240

			}

5241
			setTextureParameters( _gl.TEXTURE_2D, texture, texture.image );
M
Mr.doob 已提交
5242

A
alteredq 已提交
5243
			texture.needsUpdate = false;
5244

5245
		} else {
5246

5247 5248
			_gl.activeTexture( _gl.TEXTURE0 + slot );
			_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
5249 5250

		}
M
Mr.doob 已提交
5251

5252
	};
M
Mr.doob 已提交
5253

5254
	function setCubeTexture( texture, slot ) {
5255

5256
		if ( texture.image.length === 6 ) {
5257 5258 5259

			if ( texture.needsUpdate ) {

A
alteredq 已提交
5260
				if ( ! texture.image.__webglTextureCube ) {
5261 5262

					texture.image.__webglTextureCube = _gl.createTexture();
5263

A
alteredq 已提交
5264
				}
5265

A
alteredq 已提交
5266 5267
				_gl.activeTexture( _gl.TEXTURE0 + slot );
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
5268

A
alteredq 已提交
5269
				for ( var i = 0; i < 6; i ++ ) {
5270

A
alteredq 已提交
5271
					_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image[ i ] );
5272

A
alteredq 已提交
5273
				}
5274

A
alteredq 已提交
5275
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, texture.image[ 0 ] );
5276

A
alteredq 已提交
5277
				texture.needsUpdate = false;
5278

A
alteredq 已提交
5279
			} else {
5280

A
alteredq 已提交
5281 5282
				_gl.activeTexture( _gl.TEXTURE0 + slot );
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
5283

A
alteredq 已提交
5284
			}
5285

A
alteredq 已提交
5286
		}
5287

A
alteredq 已提交
5288
	};
5289

A
alteredq 已提交
5290
	function setCubeTextureDynamic( texture, slot ) {
5291

A
alteredq 已提交
5292 5293
		_gl.activeTexture( _gl.TEXTURE0 + slot );
		_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.__webglTexture );
5294 5295 5296

	};

5297
	function setupFrameBuffer( framebuffer, renderTarget, textureTarget ) {
5298

5299 5300
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
		_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureTarget, renderTarget.__webglTexture, 0 );
A
alteredq 已提交
5301

5302
	};
M
Mr.doob 已提交
5303

5304
	function setupRenderBuffer( renderbuffer, renderTarget  ) {
M
Mikael Emtinger 已提交
5305

5306
		_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );
5307

5308
		if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
M
Mr.doob 已提交
5309

5310 5311
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
A
alteredq 已提交
5312

5313 5314
		/* For some reason this is not working. Defaulting to RGBA4.
		} else if( ! renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
A
alteredq 已提交
5315

5316 5317 5318 5319
			_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 已提交
5320

5321 5322
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
A
alteredq 已提交
5323

5324
		} else {
A
alteredq 已提交
5325

5326
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );
A
alteredq 已提交
5327

5328
		}
A
alteredq 已提交
5329

5330
	};
A
alteredq 已提交
5331

5332
	function setRenderTarget( renderTarget ) {
A
alteredq 已提交
5333

5334
		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
A
alteredq 已提交
5335

5336
		if ( renderTarget && ! renderTarget.__webglFramebuffer ) {
A
alteredq 已提交
5337

5338 5339
			if( renderTarget.depthBuffer === undefined ) renderTarget.depthBuffer = true;
			if( renderTarget.stencilBuffer === undefined ) renderTarget.stencilBuffer = true;
A
alteredq 已提交
5340

5341
			renderTarget.__webglTexture = _gl.createTexture();
A
alteredq 已提交
5342

5343
			// Setup texture, create render and frame buffers
5344

5345
			if ( isCube ) {
M
Mr.doob 已提交
5346

5347 5348
				renderTarget.__webglFramebuffer = [];
				renderTarget.__webglRenderbuffer = [];
M
Mikael Emtinger 已提交
5349

5350 5351
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, renderTarget.__webglTexture );
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget, renderTarget );
A
alteredq 已提交
5352

5353
				for ( var i = 0; i < 6; i ++ ) {
A
alteredq 已提交
5354

5355 5356
					renderTarget.__webglFramebuffer[ i ] = _gl.createFramebuffer();
					renderTarget.__webglRenderbuffer[ i ] = _gl.createRenderbuffer();
A
alteredq 已提交
5357

5358
					_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 已提交
5359

5360
					setupFrameBuffer( renderTarget.__webglFramebuffer[ i ], renderTarget, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
A
alteredq 已提交
5361

5362
					setupRenderBuffer( renderTarget.__webglRenderbuffer[ i ], renderTarget );
A
alteredq 已提交
5363

5364
				}
5365

5366
			} else {
5367

5368 5369
				renderTarget.__webglFramebuffer = _gl.createFramebuffer();
				renderTarget.__webglRenderbuffer = _gl.createRenderbuffer();
5370

5371 5372
				_gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
				setTextureParameters( _gl.TEXTURE_2D, renderTarget, renderTarget );
5373

5374
				_gl.texImage2D( _gl.TEXTURE_2D, 0, paramThreeToGL( renderTarget.format ), renderTarget.width, renderTarget.height, 0, paramThreeToGL( renderTarget.format ), paramThreeToGL( renderTarget.type ), null );
5375

5376
				setupFrameBuffer( renderTarget.__webglFramebuffer, renderTarget, _gl.TEXTURE_2D );
5377

5378
				_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderTarget.__webglRenderbuffer );
5379

5380
				setupRenderBuffer( renderTarget.__webglRenderbuffer, renderTarget );
5381

M
Mikael Emtinger 已提交
5382
			}
5383

5384
			// Release everything
M
Mr.doob 已提交
5385

A
alteredq 已提交
5386 5387 5388 5389 5390 5391 5392 5393 5394 5395
			if ( isCube ) {

				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );

			} else {

				_gl.bindTexture( _gl.TEXTURE_2D, null );

			}

5396 5397
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
M
Mr.doob 已提交
5398

5399 5400
		}

5401
		var framebuffer, width, height, vx, vy;
M
Mr.doob 已提交
5402

5403
		if ( renderTarget ) {
M
Mr.doob 已提交
5404

A
alteredq 已提交
5405 5406
			if ( isCube ) {

5407
				framebuffer = renderTarget.__webglFramebuffer[ renderTarget.activeCubeFace ];
A
alteredq 已提交
5408 5409 5410

			} else {

5411
				framebuffer = renderTarget.__webglFramebuffer;
A
alteredq 已提交
5412 5413 5414

			}

5415 5416
			width = renderTarget.width;
			height = renderTarget.height;
M
Mr.doob 已提交
5417

5418 5419 5420
			vx = 0;
			vy = 0;

5421
		} else {
M
Mr.doob 已提交
5422

5423
			framebuffer = null;
5424

5425 5426
			width = _viewportWidth;
			height = _viewportHeight;
5427

5428 5429
			vx = _viewportX;
			vy = _viewportY;
M
Mr.doob 已提交
5430

5431
		}
M
Mr.doob 已提交
5432

5433
		if ( framebuffer !== _currentFramebuffer ) {
M
Mr.doob 已提交
5434

5435
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
5436
			_gl.viewport( vx, vy, width, height );
M
Mr.doob 已提交
5437

5438
			_currentFramebuffer = framebuffer;
M
Mr.doob 已提交
5439

5440
		}
5441

5442
	};
M
Mr.doob 已提交
5443

5444
	function updateRenderTargetMipmap( renderTarget ) {
M
Mr.doob 已提交
5445

A
alteredq 已提交
5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458
		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 已提交
5459 5460

	};
5461

5462
	function cacheUniformLocations( program, identifiers ) {
M
Mr.doob 已提交
5463

M
Mr.doob 已提交
5464
		var i, l, id;
M
Mr.doob 已提交
5465

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

5468 5469
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
5470

M
Mr.doob 已提交
5471
		}
M
Mr.doob 已提交
5472

M
Mr.doob 已提交
5473
	};
M
Mr.doob 已提交
5474

5475
	function cacheAttributeLocations( program, identifiers ) {
5476

5477
		var i, l, id;
M
Mr.doob 已提交
5478

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

5481 5482
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
M
Mr.doob 已提交
5483

5484
		}
M
Mr.doob 已提交
5485

M
Mr.doob 已提交
5486
	};
M
Mr.doob 已提交
5487

5488
	function getShader( type, string ) {
N
Nicolas Garcia Belmonte 已提交
5489 5490 5491

		var shader;

5492
		if ( type === "fragment" ) {
N
Nicolas Garcia Belmonte 已提交
5493 5494 5495

			shader = _gl.createShader( _gl.FRAGMENT_SHADER );

5496
		} else if ( type === "vertex" ) {
N
Nicolas Garcia Belmonte 已提交
5497 5498 5499 5500 5501 5502 5503 5504 5505 5506

			shader = _gl.createShader( _gl.VERTEX_SHADER );

		}

		_gl.shaderSource( shader, string );
		_gl.compileShader( shader );

		if ( !_gl.getShaderParameter( shader, _gl.COMPILE_STATUS ) ) {

5507
			console.error( _gl.getShaderInfoLog( shader ) );
5508
			console.error( string );
N
Nicolas Garcia Belmonte 已提交
5509 5510 5511 5512 5513
			return null;

		}

		return shader;
M
Mr.doob 已提交
5514

5515
	};
N
Nicolas Garcia Belmonte 已提交
5516

5517
	// fallback filters for non-power-of-2 textures
5518

5519
	function filterFallback( f ) {
5520

5521 5522 5523 5524 5525 5526 5527 5528
		switch ( f ) {

			case THREE.NearestFilter:
			case THREE.NearestMipMapNearestFilter:
			case THREE.NearestMipMapLinearFilter: return _gl.NEAREST; break;

			case THREE.LinearFilter:
			case THREE.LinearMipMapNearestFilter:
M
Mr.doob 已提交
5529
			case THREE.LinearMipMapLinearFilter:
M
Mikael Emtinger 已提交
5530
			default:
5531

M
Mikael Emtinger 已提交
5532
				return _gl.LINEAR; break;
5533 5534

		}
5535

5536
	};
5537 5538

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

5540
		switch ( p ) {
M
Mr.doob 已提交
5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552 5553

			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;

5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564 5565 5566 5567
			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;

5568
		}
M
Mr.doob 已提交
5569

5570
		return 0;
M
Mr.doob 已提交
5571

5572 5573
	};

5574
	function isPowerOfTwo( value ) {
5575

5576
		return ( value & ( value - 1 ) ) === 0;
5577 5578 5579

	};

5580
	function materialNeedsSmoothNormals( material ) {
5581

5582
		return material && material.shading !== undefined && material.shading === THREE.SmoothShading;
5583 5584

	};
5585

5586
	function bufferGuessVertexColorType( material ) {
5587

5588
		if ( material.vertexColors ) {
5589

5590
			return material.vertexColors;
5591

5592
		}
5593

5594
		return false;
5595

5596 5597
	};

5598
	function bufferGuessNormalType( material ) {
5599

5600
		// only MeshBasicMaterial and MeshDepthMaterial don't need normals
5601

5602
		if ( ( material instanceof THREE.MeshBasicMaterial && !material.envMap ) || material instanceof THREE.MeshDepthMaterial ) {
5603

5604
			return false;
5605

5606
		}
5607

5608
		if ( materialNeedsSmoothNormals( material ) ) {
5609

5610
			return THREE.SmoothShading;
5611

5612
		} else {
5613

5614
			return THREE.FlatShading;
5615 5616

		}
5617

5618 5619
	};

5620
	function bufferGuessUVType( material ) {
5621

5622
		// material must use some texture to require uvs
5623

5624
		if ( material.map || material.lightMap || material instanceof THREE.ShaderMaterial ) {
5625

5626
			return true;
5627

5628
		}
5629

5630
		return false;
5631

5632
	};
5633

5634
	function allocateBones( object ) {
5635

5636 5637 5638 5639 5640 5641 5642
		// 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)
5643

5644
		var maxBones = 50;
5645

5646
		if ( object !== undefined && object instanceof THREE.SkinnedMesh ) {
5647

5648 5649 5650 5651 5652
			maxBones = object.bones.length;

		}

		return maxBones;
5653

5654
	};
5655

5656
	function allocateLights( lights ) {
5657

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

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

5663
			light = lights[ l ];
5664

5665 5666 5667
			if ( light instanceof THREE.SpotLight ) dirLights ++; // hack, not a proper spotlight
			if ( light instanceof THREE.DirectionalLight ) dirLights ++;
			if ( light instanceof THREE.PointLight ) pointLights ++;
5668

5669
		}
5670

5671
		if ( ( pointLights + dirLights ) <= _maxLights ) {
5672

5673 5674
			maxDirLights = dirLights;
			maxPointLights = pointLights;
5675

5676
		} else {
5677

5678 5679
			maxDirLights = Math.ceil( _maxLights * dirLights / ( pointLights + dirLights ) );
			maxPointLights = _maxLights - maxDirLights;
5680 5681 5682

		}

5683
		return { 'directional' : maxDirLights, 'point' : maxPointLights };
5684 5685

	};
M
Mr.doob 已提交
5686

5687 5688
	function allocateShadows( lights ) {

M
Mr.doob 已提交
5689
		var l, ll, light, maxShadows = 0;
5690 5691 5692 5693 5694 5695 5696 5697 5698 5699 5700 5701 5702 5703

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

			light = lights[ l ];

			if ( light instanceof THREE.SpotLight && light.castShadow ) maxShadows ++;

		}

		return maxShadows;

	};


A
alteredq 已提交
5704
	/* DEBUG
5705
	function getGLParams() {
M
Mr.doob 已提交
5706

5707
		var params  = {
M
Mr.doob 已提交
5708

5709 5710
			'MAX_VARYING_VECTORS': _gl.getParameter( _gl.MAX_VARYING_VECTORS ),
			'MAX_VERTEX_ATTRIBS': _gl.getParameter( _gl.MAX_VERTEX_ATTRIBS ),
M
Mr.doob 已提交
5711

5712 5713 5714
			'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 已提交
5715

5716 5717 5718
			'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 已提交
5719

5720 5721
		return params;
	};
M
Mr.doob 已提交
5722

5723
	function dumpObject( obj ) {
M
Mr.doob 已提交
5724

5725 5726
		var p, str = "";
		for ( p in obj ) {
M
Mr.doob 已提交
5727

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

5730
		}
M
Mr.doob 已提交
5731

5732 5733
		return str;
	}
A
alteredq 已提交
5734
	*/
5735
};