WebGLRenderer.js 149.3 KB
Newer Older
N
Nicolas Garcia Belmonte 已提交
1 2 3
/**
 * @author supereggbert / http://www.paulbrunt.co.uk/
 * @author mrdoob / http://mrdoob.com/
4
 * @author alteredq / http://alteredqualia.com/
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
	this.autoUpdateObjects = true;
109
	this.autoUpdateScene = true;
110 111 112 113 114 115 116

	// physically based shading

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

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

128
	this.shadowMap = [];
129

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

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

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

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

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

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

146 147 148 149
	// Init GL

	try {

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

			throw 'Error creating WebGL context.';

		}

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

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

		console.error( error );

	}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		_canvas.width = width;
		_canvas.height = height;
268

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

	};
N
Nicolas Garcia Belmonte 已提交
272

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

275 276
		_viewportX = x;
		_viewportY = y;
277

278 279
		_viewportWidth = width;
		_viewportHeight = height;
280

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

N
Nicolas Garcia Belmonte 已提交
283
	};
284

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

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

289
	};
290

291
	this.enableScissorTest = function ( enable ) {
292

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

	};
296

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

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

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

304
	};
A
alteredq 已提交
305

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

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

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

	};
314

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

		return _clearColor;

	};

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

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

	};

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

		var bits = 0;

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

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

	};

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

		return _gl;

	};

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

390 391 392 393
	};

	//

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

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

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

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

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

409 410
		dlength = 0,
		plength = 0,
411

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

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

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

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

			if ( light instanceof THREE.AmbientLight ) {

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

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

442
				doffset = dlength * 3;
443

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

				}
457

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

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

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

				doffset = dlength * 3;

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

				}
481 482 483 484 485 486 487 488 489

				n = 1 / position.length();

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

				dlength += 1;

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

492
				poffset = plength * 3;
493

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

				}
507

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

512 513
				pdistances[ plength ] = distance;

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

516 517 518
			}

		}
519

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

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

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

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

533
	};
M
Mr.doob 已提交
534

535 536 537
	// Buffer allocation

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

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

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

544
	};
M
Mr.doob 已提交
545

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

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

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

553
	};
554

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

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

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

A
alteredq 已提交
562 563
	};

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

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

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

583
			var m, ml;
584

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

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

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

591 592 593
			}

		}
M
Mr.doob 已提交
594

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

597
	};
598

599 600 601 602 603 604 605
	// Buffer deallocation

	function deleteParticleBuffers( geometry ) {

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

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

608 609 610 611 612 613 614
	};

	function deleteLineBuffers( geometry ) {

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

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

617 618 619 620 621 622 623
	};

	function deleteRibbonBuffers( geometry ) {

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

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

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

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

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

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

			}

		}

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

657 658 659 660
	};

	//

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

663 664
		var nvertices = geometry.vertices.length;

665
		var material = object.material;
666

667
		if ( material.attributes ) {
668

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

671
				geometry.__webglCustomAttributesList = [];
672

673
			}
674

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

677 678
				// Do a shallow copy of the attribute object so different geometryGroup chunks use different
				// attribute buffers which are correctly indexed in the setMeshBuffers function
679

680 681 682
				// 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
683

684
				originalAttribute = material.attributes[ a ];
685

686
				attribute = {};
687

688
				for ( property in originalAttribute ) {
689

690
					attribute[ property ] = originalAttribute[ property ];
691

692
				}
693

694
				if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
695

696
					attribute.__webglInitialized = true;
697

698
					size = 1;		// "f" and "i"
699

700 701 702 703
					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;
704

705 706 707 708
					attribute.size = size;
					attribute.array = new Float32Array( nvertices * size );
					attribute.buffer = _gl.createBuffer();
					attribute.buffer.belongsToAttribute = a;
709

710 711
					originalAttribute.needsUpdate = true;
					attribute.__original = originalAttribute;
712

713
				}
714

715
				geometry.__webglCustomAttributesList.push( attribute );
716

717
			}
718

719
		}
720

721
	};
722

A
alteredq 已提交
723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765
	//

	function initLineBuffers ( geometry, object ) {

		var nvertices = geometry.vertices.length;

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

		geometry.__webglLineCount = nvertices;

		initCustomAttributes ( geometry, object );

	};

	function initParticleBuffers ( geometry, object ) {

		var nvertices = geometry.vertices.length;

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

		geometry.__sortArray = [];

		geometry.__webglParticleCount = nvertices;

		initCustomAttributes ( geometry, object );

	};

	function initRibbonBuffers ( geometry ) {

		var nvertices = geometry.vertices.length;

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

		geometry.__webglVertexCount = nvertices;

	};

	//

766 767 768 769 770 771 772 773 774
	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 ];
775 776 777

		}

778 779
	};

M
Mr.doob 已提交
780
	function initMeshBuffers ( geometryGroup, object ) {
M
Mr.doob 已提交
781

782 783 784
		var geometry = object.geometry,
			faces3 = geometryGroup.faces3,
			faces4 = geometryGroup.faces4,
M
Mr.doob 已提交
785

786 787 788
			nvertices = faces3.length * 3 + faces4.length * 4,
			ntris     = faces3.length * 1 + faces4.length * 2,
			nlines    = faces3.length * 3 + faces4.length * 4,
789

790
			material = getBufferMaterial( object, geometryGroup ),
791

792 793 794
			uvType = bufferGuessUVType( material ),
			normalType = bufferGuessNormalType( material ),
			vertexColorType = bufferGuessVertexColorType( material );
A
alteredq 已提交
795

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

798
		geometryGroup.__vertexArray = new Float32Array( nvertices * 3 );
799

800
		if ( normalType ) {
M
Mr.doob 已提交
801

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

804
		}
805

806
		if ( geometry.hasTangents ) {
807

808
			geometryGroup.__tangentArray = new Float32Array( nvertices * 4 );
809

810
		}
811

812
		if ( vertexColorType ) {
813

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

816
		}
M
Mr.doob 已提交
817

818
		if ( uvType ) {
819

820
			if ( geometry.faceUvs.length > 0 || geometry.faceVertexUvs.length > 0 ) {
821

822 823 824 825 826
				geometryGroup.__uvArray = new Float32Array( nvertices * 2 );

			}

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

828 829 830 831 832 833 834 835 836 837 838 839 840 841 842
				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 );

		}

843
		geometryGroup.__faceArray = new Uint16Array( ntris * 3 );
844
		geometryGroup.__lineArray = new Uint16Array( nlines * 2 );
M
Mr.doob 已提交
845

846 847
		if ( geometryGroup.numMorphTargets ) {

M
Mr.doob 已提交
848
			geometryGroup.__morphTargetsArrays = [];
849

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

852 853
				geometryGroup.__morphTargetsArrays.push( new Float32Array( nvertices * 3 ) );

854 855 856
			}

		}
857

858
		geometryGroup.__needsSmoothNormals = ( normalType === THREE.SmoothShading );
859

860 861 862 863
		geometryGroup.__uvType = uvType;
		geometryGroup.__vertexColorType = vertexColorType;
		geometryGroup.__normalType = normalType;

864
		geometryGroup.__webglFaceCount = ntris * 3;
865
		geometryGroup.__webglLineCount = nlines * 2;
866

M
Mr.doob 已提交
867

868
		// custom attributes
M
Mr.doob 已提交
869

870
		if ( material.attributes ) {
871

872
			if ( geometryGroup.__webglCustomAttributesList === undefined ) {
873

874
				geometryGroup.__webglCustomAttributesList = [];
875

876
			}
877

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

880 881
				// Do a shallow copy of the attribute object so different geometryGroup chunks use different
				// attribute buffers which are correctly indexed in the setMeshBuffers function
882

883
				var originalAttribute = material.attributes[ a ];
884

885
				var attribute = {};
886

887
				for ( var property in originalAttribute ) {
M
Mr.doob 已提交
888

889
					attribute[ property ] = originalAttribute[ property ];
890

891
				}
892

893
				if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
894

895
					attribute.__webglInitialized = true;
896

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

899 900 901 902
					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;
903

904 905 906 907
					attribute.size = size;
					attribute.array = new Float32Array( nvertices * size );
					attribute.buffer = _gl.createBuffer();
					attribute.buffer.belongsToAttribute = a;
908

909 910
					originalAttribute.needsUpdate = true;
					attribute.__original = originalAttribute;
911 912 913

				}

914 915
				geometryGroup.__webglCustomAttributesList.push( attribute );

916
			}
M
Mr.doob 已提交
917

918
		}
919

920 921
		geometryGroup.__inittedArrays = true;

922
	};
M
Mr.doob 已提交
923

924
	function setMeshBuffers( geometryGroup, object, hint, dispose ) {
925

926 927 928 929 930 931 932
		if ( ! geometryGroup.__inittedArrays ) {

			// console.log( object );
			return;

		}

M
Mr.doob 已提交
933
		var f, fl, fi, face,
934 935 936 937 938 939 940 941 942 943
		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,
944
		m, ml, i, il,
945 946
		vn, uvi, uv2i,
		vk, vkl, vka,
947
		a,
M
Mr.doob 已提交
948

949
		vertexIndex = 0,
950

951 952
		offset = 0,
		offset_uv = 0,
953
		offset_uv2 = 0,
954 955 956 957
		offset_face = 0,
		offset_normal = 0,
		offset_tangent = 0,
		offset_line = 0,
958
		offset_color = 0,
A
alteredq 已提交
959
		offset_skin = 0,
960
		offset_morphTarget = 0,
961
		offset_custom = 0,
962
		offset_customSrc = 0,
M
Mr.doob 已提交
963

964 965
		value,

966 967 968 969 970 971
		vertexArray = geometryGroup.__vertexArray,
		uvArray = geometryGroup.__uvArray,
		uv2Array = geometryGroup.__uv2Array,
		normalArray = geometryGroup.__normalArray,
		tangentArray = geometryGroup.__tangentArray,
		colorArray = geometryGroup.__colorArray,
972

973 974 975 976
		skinVertexAArray = geometryGroup.__skinVertexAArray,
		skinVertexBArray = geometryGroup.__skinVertexBArray,
		skinIndexArray = geometryGroup.__skinIndexArray,
		skinWeightArray = geometryGroup.__skinWeightArray,
M
Mr.doob 已提交
977

978 979
		morphTargetsArrays = geometryGroup.__morphTargetsArrays,

980
		customAttributes = geometryGroup.__webglCustomAttributesList,
981
		customAttribute,
982

983 984
		faceArray = geometryGroup.__faceArray,
		lineArray = geometryGroup.__lineArray,
M
Mr.doob 已提交
985

986
		needsSmoothNormals = geometryGroup.__needsSmoothNormals,
987

988
		vertexColorType = geometryGroup.__vertexColorType,
A
alteredq 已提交
989 990
		uvType = geometryGroup.__uvType,
		normalType = geometryGroup.__normalType,
991

992
		geometry = object.geometry, // this is shared for all chunks
993

994
		dirtyVertices = geometry.__dirtyVertices,
995 996 997
		dirtyElements = geometry.__dirtyElements,
		dirtyUvs = geometry.__dirtyUvs,
		dirtyNormals = geometry.__dirtyNormals,
998
		dirtyTangents = geometry.__dirtyTangents,
999
		dirtyColors = geometry.__dirtyColors,
1000
		dirtyMorphTargets = geometry.__dirtyMorphTargets,
M
Mr.doob 已提交
1001

1002
		vertices = geometry.vertices,
1003 1004
		chunk_faces3 = geometryGroup.faces3,
		chunk_faces4 = geometryGroup.faces4,
1005
		obj_faces = geometry.faces,
1006

1007 1008
		obj_uvs  = geometry.faceVertexUvs[ 0 ],
		obj_uvs2 = geometry.faceVertexUvs[ 1 ],
1009

A
alteredq 已提交
1010
		obj_colors = geometry.colors,
1011

A
alteredq 已提交
1012 1013 1014
		obj_skinVerticesA = geometry.skinVerticesA,
		obj_skinVerticesB = geometry.skinVerticesB,
		obj_skinIndices = geometry.skinIndices,
1015
		obj_skinWeights = geometry.skinWeights,
1016

1017
		morphTargets = geometry.morphTargets;
1018

A
alteredq 已提交
1019
		if ( dirtyVertices ) {
1020

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

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

1025 1026 1027
				v1 = vertices[ face.a ].position;
				v2 = vertices[ face.b ].position;
				v3 = vertices[ face.c ].position;
M
Mr.doob 已提交
1028

1029 1030 1031
				vertexArray[ offset ]     = v1.x;
				vertexArray[ offset + 1 ] = v1.y;
				vertexArray[ offset + 2 ] = v1.z;
M
Mr.doob 已提交
1032

1033 1034 1035
				vertexArray[ offset + 3 ] = v2.x;
				vertexArray[ offset + 4 ] = v2.y;
				vertexArray[ offset + 5 ] = v2.z;
1036

1037 1038 1039
				vertexArray[ offset + 6 ] = v3.x;
				vertexArray[ offset + 7 ] = v3.y;
				vertexArray[ offset + 8 ] = v3.z;
M
Mr.doob 已提交
1040

1041
				offset += 9;
M
Mr.doob 已提交
1042

1043
			}
1044

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

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

A
alteredq 已提交
1049 1050 1051 1052
				v1 = vertices[ face.a ].position;
				v2 = vertices[ face.b ].position;
				v3 = vertices[ face.c ].position;
				v4 = vertices[ face.d ].position;
1053

A
alteredq 已提交
1054 1055 1056
				vertexArray[ offset ]     = v1.x;
				vertexArray[ offset + 1 ] = v1.y;
				vertexArray[ offset + 2 ] = v1.z;
1057

A
alteredq 已提交
1058 1059 1060
				vertexArray[ offset + 3 ] = v2.x;
				vertexArray[ offset + 4 ] = v2.y;
				vertexArray[ offset + 5 ] = v2.z;
1061

A
alteredq 已提交
1062 1063 1064
				vertexArray[ offset + 6 ] = v3.x;
				vertexArray[ offset + 7 ] = v3.y;
				vertexArray[ offset + 8 ] = v3.z;
1065

A
alteredq 已提交
1066 1067 1068
				vertexArray[ offset + 9 ]  = v4.x;
				vertexArray[ offset + 10 ] = v4.y;
				vertexArray[ offset + 11 ] = v4.z;
1069

A
alteredq 已提交
1070
				offset += 12;
1071

A
alteredq 已提交
1072
			}
1073

A
alteredq 已提交
1074 1075
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
M
Mr.doob 已提交
1076

A
alteredq 已提交
1077
		}
M
Mr.doob 已提交
1078

A
alteredq 已提交
1079
		if ( dirtyMorphTargets ) {
M
Mr.doob 已提交
1080

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

A
alteredq 已提交
1083
				face = obj_faces[ chunk_faces3[ f ]	];
1084

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

A
alteredq 已提交
1087 1088 1089
					v1 = morphTargets[ vk ].vertices[ face.a ].position;
					v2 = morphTargets[ vk ].vertices[ face.b ].position;
					v3 = morphTargets[ vk ].vertices[ face.c ].position;
M
Mr.doob 已提交
1090

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

A
alteredq 已提交
1093 1094 1095
					vka[ offset_morphTarget ] 	  = v1.x;
					vka[ offset_morphTarget + 1 ] = v1.y;
					vka[ offset_morphTarget + 2 ] = v1.z;
M
Mr.doob 已提交
1096

A
alteredq 已提交
1097 1098 1099
					vka[ offset_morphTarget + 3 ] = v2.x;
					vka[ offset_morphTarget + 4 ] = v2.y;
					vka[ offset_morphTarget + 5 ] = v2.z;
M
Mr.doob 已提交
1100

A
alteredq 已提交
1101 1102 1103
					vka[ offset_morphTarget + 6 ] = v3.x;
					vka[ offset_morphTarget + 7 ] = v3.y;
					vka[ offset_morphTarget + 8 ] = v3.z;
M
Mr.doob 已提交
1104

1105 1106
				}

A
alteredq 已提交
1107 1108
				offset_morphTarget += 9;

1109
			}
1110

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

A
alteredq 已提交
1113
				face = obj_faces[ chunk_faces4[ f ] ];
1114

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

1117 1118 1119
					v1 = morphTargets[ vk ].vertices[ face.a ].position;
					v2 = morphTargets[ vk ].vertices[ face.b ].position;
					v3 = morphTargets[ vk ].vertices[ face.c ].position;
A
alteredq 已提交
1120
					v4 = morphTargets[ vk ].vertices[ face.d ].position;
1121

1122
					vka = morphTargetsArrays[ vk ];
1123

1124 1125 1126
					vka[ offset_morphTarget ] 	  = v1.x;
					vka[ offset_morphTarget + 1 ] = v1.y;
					vka[ offset_morphTarget + 2 ] = v1.z;
1127

1128 1129 1130
					vka[ offset_morphTarget + 3 ] = v2.x;
					vka[ offset_morphTarget + 4 ] = v2.y;
					vka[ offset_morphTarget + 5 ] = v2.z;
1131

1132 1133 1134
					vka[ offset_morphTarget + 6 ] = v3.x;
					vka[ offset_morphTarget + 7 ] = v3.y;
					vka[ offset_morphTarget + 8 ] = v3.z;
1135

A
alteredq 已提交
1136 1137 1138 1139
					vka[ offset_morphTarget + 9 ]  = v4.x;
					vka[ offset_morphTarget + 10 ] = v4.y;
					vka[ offset_morphTarget + 11 ] = v4.z;

1140 1141
				}

A
alteredq 已提交
1142 1143 1144 1145 1146 1147 1148 1149
				offset_morphTarget += 12;

			}

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

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

1151
			}
1152

A
alteredq 已提交
1153 1154 1155 1156 1157 1158 1159
		}

		if ( obj_skinWeights.length ) {

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

				face = obj_faces[ chunk_faces3[ f ]	];
1160

1161
				// weights
A
alteredq 已提交
1162

1163 1164 1165
				sw1 = obj_skinWeights[ face.a ];
				sw2 = obj_skinWeights[ face.b ];
				sw3 = obj_skinWeights[ face.c ];
A
alteredq 已提交
1166

1167 1168 1169 1170
				skinWeightArray[ offset_skin ]     = sw1.x;
				skinWeightArray[ offset_skin + 1 ] = sw1.y;
				skinWeightArray[ offset_skin + 2 ] = sw1.z;
				skinWeightArray[ offset_skin + 3 ] = sw1.w;
A
alteredq 已提交
1171

1172 1173 1174 1175
				skinWeightArray[ offset_skin + 4 ] = sw2.x;
				skinWeightArray[ offset_skin + 5 ] = sw2.y;
				skinWeightArray[ offset_skin + 6 ] = sw2.z;
				skinWeightArray[ offset_skin + 7 ] = sw2.w;
1176

1177 1178 1179 1180
				skinWeightArray[ offset_skin + 8 ]  = sw3.x;
				skinWeightArray[ offset_skin + 9 ]  = sw3.y;
				skinWeightArray[ offset_skin + 10 ] = sw3.z;
				skinWeightArray[ offset_skin + 11 ] = sw3.w;
A
alteredq 已提交
1181

1182
				// indices
A
alteredq 已提交
1183

1184 1185 1186
				si1 = obj_skinIndices[ face.a ];
				si2 = obj_skinIndices[ face.b ];
				si3 = obj_skinIndices[ face.c ];
A
alteredq 已提交
1187

1188 1189 1190 1191
				skinIndexArray[ offset_skin ]     = si1.x;
				skinIndexArray[ offset_skin + 1 ] = si1.y;
				skinIndexArray[ offset_skin + 2 ] = si1.z;
				skinIndexArray[ offset_skin + 3 ] = si1.w;
A
alteredq 已提交
1192

1193 1194 1195 1196
				skinIndexArray[ offset_skin + 4 ] = si2.x;
				skinIndexArray[ offset_skin + 5 ] = si2.y;
				skinIndexArray[ offset_skin + 6 ] = si2.z;
				skinIndexArray[ offset_skin + 7 ] = si2.w;
1197

1198 1199 1200 1201
				skinIndexArray[ offset_skin + 8 ]  = si3.x;
				skinIndexArray[ offset_skin + 9 ]  = si3.y;
				skinIndexArray[ offset_skin + 10 ] = si3.z;
				skinIndexArray[ offset_skin + 11 ] = si3.w;
A
alteredq 已提交
1202

1203
				// vertices A
A
alteredq 已提交
1204

1205 1206 1207
				sa1 = obj_skinVerticesA[ face.a ];
				sa2 = obj_skinVerticesA[ face.b ];
				sa3 = obj_skinVerticesA[ face.c ];
A
alteredq 已提交
1208

1209 1210 1211 1212
				skinVertexAArray[ offset_skin ]     = sa1.x;
				skinVertexAArray[ offset_skin + 1 ] = sa1.y;
				skinVertexAArray[ offset_skin + 2 ] = sa1.z;
				skinVertexAArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader
A
alteredq 已提交
1213

1214 1215 1216 1217
				skinVertexAArray[ offset_skin + 4 ] = sa2.x;
				skinVertexAArray[ offset_skin + 5 ] = sa2.y;
				skinVertexAArray[ offset_skin + 6 ] = sa2.z;
				skinVertexAArray[ offset_skin + 7 ] = 1;
1218

1219 1220 1221 1222
				skinVertexAArray[ offset_skin + 8 ]  = sa3.x;
				skinVertexAArray[ offset_skin + 9 ]  = sa3.y;
				skinVertexAArray[ offset_skin + 10 ] = sa3.z;
				skinVertexAArray[ offset_skin + 11 ] = 1;
A
alteredq 已提交
1223

1224
				// vertices B
A
alteredq 已提交
1225

1226 1227 1228
				sb1 = obj_skinVerticesB[ face.a ];
				sb2 = obj_skinVerticesB[ face.b ];
				sb3 = obj_skinVerticesB[ face.c ];
A
alteredq 已提交
1229

1230 1231 1232 1233
				skinVertexBArray[ offset_skin ]     = sb1.x;
				skinVertexBArray[ offset_skin + 1 ] = sb1.y;
				skinVertexBArray[ offset_skin + 2 ] = sb1.z;
				skinVertexBArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader
A
alteredq 已提交
1234

1235 1236 1237 1238
				skinVertexBArray[ offset_skin + 4 ] = sb2.x;
				skinVertexBArray[ offset_skin + 5 ] = sb2.y;
				skinVertexBArray[ offset_skin + 6 ] = sb2.z;
				skinVertexBArray[ offset_skin + 7 ] = 1;
1239

1240 1241 1242 1243
				skinVertexBArray[ offset_skin + 8 ]  = sb3.x;
				skinVertexBArray[ offset_skin + 9 ]  = sb3.y;
				skinVertexBArray[ offset_skin + 10 ] = sb3.z;
				skinVertexBArray[ offset_skin + 11 ] = 1;
1244

1245
				offset_skin += 12;
1246

1247
			}
1248

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

A
alteredq 已提交
1251
				face = obj_faces[ chunk_faces4[ f ] ];
1252

A
alteredq 已提交
1253
				// weights
1254

A
alteredq 已提交
1255 1256 1257 1258
				sw1 = obj_skinWeights[ face.a ];
				sw2 = obj_skinWeights[ face.b ];
				sw3 = obj_skinWeights[ face.c ];
				sw4 = obj_skinWeights[ face.d ];
1259

A
alteredq 已提交
1260 1261 1262 1263
				skinWeightArray[ offset_skin ]     = sw1.x;
				skinWeightArray[ offset_skin + 1 ] = sw1.y;
				skinWeightArray[ offset_skin + 2 ] = sw1.z;
				skinWeightArray[ offset_skin + 3 ] = sw1.w;
1264

A
alteredq 已提交
1265 1266 1267 1268
				skinWeightArray[ offset_skin + 4 ] = sw2.x;
				skinWeightArray[ offset_skin + 5 ] = sw2.y;
				skinWeightArray[ offset_skin + 6 ] = sw2.z;
				skinWeightArray[ offset_skin + 7 ] = sw2.w;
1269

A
alteredq 已提交
1270 1271 1272 1273
				skinWeightArray[ offset_skin + 8 ]  = sw3.x;
				skinWeightArray[ offset_skin + 9 ]  = sw3.y;
				skinWeightArray[ offset_skin + 10 ] = sw3.z;
				skinWeightArray[ offset_skin + 11 ] = sw3.w;
1274

A
alteredq 已提交
1275 1276 1277 1278
				skinWeightArray[ offset_skin + 12 ] = sw4.x;
				skinWeightArray[ offset_skin + 13 ] = sw4.y;
				skinWeightArray[ offset_skin + 14 ] = sw4.z;
				skinWeightArray[ offset_skin + 15 ] = sw4.w;
1279

A
alteredq 已提交
1280
				// indices
1281

A
alteredq 已提交
1282 1283 1284 1285
				si1 = obj_skinIndices[ face.a ];
				si2 = obj_skinIndices[ face.b ];
				si3 = obj_skinIndices[ face.c ];
				si4 = obj_skinIndices[ face.d ];
1286

A
alteredq 已提交
1287 1288 1289 1290
				skinIndexArray[ offset_skin ]     = si1.x;
				skinIndexArray[ offset_skin + 1 ] = si1.y;
				skinIndexArray[ offset_skin + 2 ] = si1.z;
				skinIndexArray[ offset_skin + 3 ] = si1.w;
1291

A
alteredq 已提交
1292 1293 1294 1295
				skinIndexArray[ offset_skin + 4 ] = si2.x;
				skinIndexArray[ offset_skin + 5 ] = si2.y;
				skinIndexArray[ offset_skin + 6 ] = si2.z;
				skinIndexArray[ offset_skin + 7 ] = si2.w;
M
Mr.doob 已提交
1296

A
alteredq 已提交
1297 1298 1299 1300
				skinIndexArray[ offset_skin + 8 ]  = si3.x;
				skinIndexArray[ offset_skin + 9 ]  = si3.y;
				skinIndexArray[ offset_skin + 10 ] = si3.z;
				skinIndexArray[ offset_skin + 11 ] = si3.w;
M
Mr.doob 已提交
1301

A
alteredq 已提交
1302 1303 1304 1305
				skinIndexArray[ offset_skin + 12 ] = si4.x;
				skinIndexArray[ offset_skin + 13 ] = si4.y;
				skinIndexArray[ offset_skin + 14 ] = si4.z;
				skinIndexArray[ offset_skin + 15 ] = si4.w;
M
Mr.doob 已提交
1306

A
alteredq 已提交
1307
				// vertices A
M
Mr.doob 已提交
1308

A
alteredq 已提交
1309 1310 1311 1312
				sa1 = obj_skinVerticesA[ face.a ];
				sa2 = obj_skinVerticesA[ face.b ];
				sa3 = obj_skinVerticesA[ face.c ];
				sa4 = obj_skinVerticesA[ face.d ];
1313

A
alteredq 已提交
1314 1315 1316 1317
				skinVertexAArray[ offset_skin ]     = sa1.x;
				skinVertexAArray[ offset_skin + 1 ] = sa1.y;
				skinVertexAArray[ offset_skin + 2 ] = sa1.z;
				skinVertexAArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader
M
Mr.doob 已提交
1318

A
alteredq 已提交
1319 1320 1321 1322
				skinVertexAArray[ offset_skin + 4 ] = sa2.x;
				skinVertexAArray[ offset_skin + 5 ] = sa2.y;
				skinVertexAArray[ offset_skin + 6 ] = sa2.z;
				skinVertexAArray[ offset_skin + 7 ] = 1;
1323

A
alteredq 已提交
1324 1325 1326 1327
				skinVertexAArray[ offset_skin + 8 ]  = sa3.x;
				skinVertexAArray[ offset_skin + 9 ]  = sa3.y;
				skinVertexAArray[ offset_skin + 10 ] = sa3.z;
				skinVertexAArray[ offset_skin + 11 ] = 1;
1328

A
alteredq 已提交
1329 1330 1331 1332
				skinVertexAArray[ offset_skin + 12 ] = sa4.x;
				skinVertexAArray[ offset_skin + 13 ] = sa4.y;
				skinVertexAArray[ offset_skin + 14 ] = sa4.z;
				skinVertexAArray[ offset_skin + 15 ] = 1;
M
Mr.doob 已提交
1333

A
alteredq 已提交
1334
				// vertices B
M
Mr.doob 已提交
1335

A
alteredq 已提交
1336 1337 1338 1339
				sb1 = obj_skinVerticesB[ face.a ];
				sb2 = obj_skinVerticesB[ face.b ];
				sb3 = obj_skinVerticesB[ face.c ];
				sb4 = obj_skinVerticesB[ face.d ];
M
Mr.doob 已提交
1340

A
alteredq 已提交
1341 1342 1343 1344
				skinVertexBArray[ offset_skin ]     = sb1.x;
				skinVertexBArray[ offset_skin + 1 ] = sb1.y;
				skinVertexBArray[ offset_skin + 2 ] = sb1.z;
				skinVertexBArray[ offset_skin + 3 ] = 1; // pad for faster vertex shader
M
Mr.doob 已提交
1345

A
alteredq 已提交
1346 1347 1348 1349
				skinVertexBArray[ offset_skin + 4 ] = sb2.x;
				skinVertexBArray[ offset_skin + 5 ] = sb2.y;
				skinVertexBArray[ offset_skin + 6 ] = sb2.z;
				skinVertexBArray[ offset_skin + 7 ] = 1;
1350

A
alteredq 已提交
1351 1352 1353 1354
				skinVertexBArray[ offset_skin + 8 ]  = sb3.x;
				skinVertexBArray[ offset_skin + 9 ]  = sb3.y;
				skinVertexBArray[ offset_skin + 10 ] = sb3.z;
				skinVertexBArray[ offset_skin + 11 ] = 1;
1355

A
alteredq 已提交
1356 1357 1358 1359
				skinVertexBArray[ offset_skin + 12 ] = sb4.x;
				skinVertexBArray[ offset_skin + 13 ] = sb4.y;
				skinVertexBArray[ offset_skin + 14 ] = sb4.z;
				skinVertexBArray[ offset_skin + 15 ] = 1;
1360

A
alteredq 已提交
1361
				offset_skin += 16;
M
Mr.doob 已提交
1362

A
alteredq 已提交
1363
			}
M
Mr.doob 已提交
1364

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

A
alteredq 已提交
1367 1368
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexAArray, hint );
M
Mr.doob 已提交
1369

A
alteredq 已提交
1370 1371 1372 1373 1374 1375 1376 1377
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexBArray, hint );

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

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

1379
			}
1380

A
alteredq 已提交
1381
		}
M
Mr.doob 已提交
1382

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

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

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

A
alteredq 已提交
1389 1390
				vertexColors = face.vertexColors;
				faceColor = face.color;
1391

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

A
alteredq 已提交
1394 1395 1396
					c1 = vertexColors[ 0 ];
					c2 = vertexColors[ 1 ];
					c3 = vertexColors[ 2 ];
1397

A
alteredq 已提交
1398
				} else {
1399

A
alteredq 已提交
1400 1401 1402
					c1 = faceColor;
					c2 = faceColor;
					c3 = faceColor;
1403

A
alteredq 已提交
1404
				}
1405

A
alteredq 已提交
1406 1407 1408
				colorArray[ offset_color ]     = c1.r;
				colorArray[ offset_color + 1 ] = c1.g;
				colorArray[ offset_color + 2 ] = c1.b;
1409

A
alteredq 已提交
1410 1411 1412
				colorArray[ offset_color + 3 ] = c2.r;
				colorArray[ offset_color + 4 ] = c2.g;
				colorArray[ offset_color + 5 ] = c2.b;
1413

A
alteredq 已提交
1414 1415 1416
				colorArray[ offset_color + 6 ] = c3.r;
				colorArray[ offset_color + 7 ] = c3.g;
				colorArray[ offset_color + 8 ] = c3.b;
1417

A
alteredq 已提交
1418
				offset_color += 9;
M
Mr.doob 已提交
1419

A
alteredq 已提交
1420
			}
M
Mr.doob 已提交
1421

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

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

A
alteredq 已提交
1426 1427
				vertexColors = face.vertexColors;
				faceColor = face.color;
M
Mr.doob 已提交
1428

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

A
alteredq 已提交
1431 1432 1433 1434
					c1 = vertexColors[ 0 ];
					c2 = vertexColors[ 1 ];
					c3 = vertexColors[ 2 ];
					c4 = vertexColors[ 3 ];
1435

A
alteredq 已提交
1436
				} else {
M
Mr.doob 已提交
1437

A
alteredq 已提交
1438 1439 1440 1441
					c1 = faceColor;
					c2 = faceColor;
					c3 = faceColor;
					c4 = faceColor;
M
Mr.doob 已提交
1442

A
alteredq 已提交
1443
				}
1444

A
alteredq 已提交
1445 1446 1447
				colorArray[ offset_color ]     = c1.r;
				colorArray[ offset_color + 1 ] = c1.g;
				colorArray[ offset_color + 2 ] = c1.b;
1448

A
alteredq 已提交
1449 1450 1451
				colorArray[ offset_color + 3 ] = c2.r;
				colorArray[ offset_color + 4 ] = c2.g;
				colorArray[ offset_color + 5 ] = c2.b;
M
Mr.doob 已提交
1452

A
alteredq 已提交
1453 1454 1455
				colorArray[ offset_color + 6 ] = c3.r;
				colorArray[ offset_color + 7 ] = c3.g;
				colorArray[ offset_color + 8 ] = c3.b;
M
Mr.doob 已提交
1456

A
alteredq 已提交
1457 1458 1459
				colorArray[ offset_color + 9 ]  = c4.r;
				colorArray[ offset_color + 10 ] = c4.g;
				colorArray[ offset_color + 11 ] = c4.b;
M
Mr.doob 已提交
1460

A
alteredq 已提交
1461
				offset_color += 12;
1462

1463
			}
1464

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

A
alteredq 已提交
1467 1468
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
M
Mr.doob 已提交
1469

1470
			}
1471

A
alteredq 已提交
1472
		}
M
Mr.doob 已提交
1473

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

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

A
alteredq 已提交
1478
				face = obj_faces[ chunk_faces3[ f ]	];
1479

A
alteredq 已提交
1480
				vertexTangents = face.vertexTangents;
M
Mr.doob 已提交
1481

A
alteredq 已提交
1482 1483 1484
				t1 = vertexTangents[ 0 ];
				t2 = vertexTangents[ 1 ];
				t3 = vertexTangents[ 2 ];
1485

A
alteredq 已提交
1486 1487 1488 1489
				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 已提交
1490

A
alteredq 已提交
1491 1492 1493 1494
				tangentArray[ offset_tangent + 4 ] = t2.x;
				tangentArray[ offset_tangent + 5 ] = t2.y;
				tangentArray[ offset_tangent + 6 ] = t2.z;
				tangentArray[ offset_tangent + 7 ] = t2.w;
1495

A
alteredq 已提交
1496 1497 1498 1499
				tangentArray[ offset_tangent + 8 ]  = t3.x;
				tangentArray[ offset_tangent + 9 ]  = t3.y;
				tangentArray[ offset_tangent + 10 ] = t3.z;
				tangentArray[ offset_tangent + 11 ] = t3.w;
1500

A
alteredq 已提交
1501
				offset_tangent += 12;
1502

1503
			}
1504

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

A
alteredq 已提交
1507
				face = obj_faces[ chunk_faces4[ f ] ];
1508

A
alteredq 已提交
1509
				vertexTangents = face.vertexTangents;
1510

A
alteredq 已提交
1511 1512 1513 1514
				t1 = vertexTangents[ 0 ];
				t2 = vertexTangents[ 1 ];
				t3 = vertexTangents[ 2 ];
				t4 = vertexTangents[ 3 ];
1515

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

A
alteredq 已提交
1521 1522 1523 1524
				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 已提交
1525

A
alteredq 已提交
1526 1527 1528 1529
				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 已提交
1530

A
alteredq 已提交
1531 1532 1533 1534
				tangentArray[ offset_tangent + 12 ] = t4.x;
				tangentArray[ offset_tangent + 13 ] = t4.y;
				tangentArray[ offset_tangent + 14 ] = t4.z;
				tangentArray[ offset_tangent + 15 ] = t4.w;
1535

A
alteredq 已提交
1536
				offset_tangent += 16;
1537

A
alteredq 已提交
1538
			}
1539

A
alteredq 已提交
1540 1541
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint );
1542

A
alteredq 已提交
1543
		}
1544

A
alteredq 已提交
1545
		if ( dirtyNormals && normalType ) {
1546

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

A
alteredq 已提交
1549
				face = obj_faces[ chunk_faces3[ f ]	];
1550

A
alteredq 已提交
1551 1552
				vertexNormals = face.vertexNormals;
				faceNormal = face.normal;
1553

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

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

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

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

A
alteredq 已提交
1564
						offset_normal += 3;
1565

A
alteredq 已提交
1566
					}
1567

A
alteredq 已提交
1568
				} else {
M
Mr.doob 已提交
1569

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

A
alteredq 已提交
1572 1573 1574
						normalArray[ offset_normal ]     = faceNormal.x;
						normalArray[ offset_normal + 1 ] = faceNormal.y;
						normalArray[ offset_normal + 2 ] = faceNormal.z;
1575

A
alteredq 已提交
1576
						offset_normal += 3;
M
Mr.doob 已提交
1577

A
alteredq 已提交
1578
					}
1579

A
alteredq 已提交
1580
				}
1581

A
alteredq 已提交
1582
			}
1583

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

A
alteredq 已提交
1586
				face = obj_faces[ chunk_faces4[ f ] ];
1587

A
alteredq 已提交
1588 1589
				vertexNormals = face.vertexNormals;
				faceNormal = face.normal;
1590

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

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

A
alteredq 已提交
1595
						vn = vertexNormals[ i ];
1596

A
alteredq 已提交
1597 1598 1599
						normalArray[ offset_normal ]     = vn.x;
						normalArray[ offset_normal + 1 ] = vn.y;
						normalArray[ offset_normal + 2 ] = vn.z;
1600

A
alteredq 已提交
1601
						offset_normal += 3;
1602

A
alteredq 已提交
1603
					}
M
Mr.doob 已提交
1604

A
alteredq 已提交
1605
				} else {
1606

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

A
alteredq 已提交
1609 1610 1611
						normalArray[ offset_normal ]     = faceNormal.x;
						normalArray[ offset_normal + 1 ] = faceNormal.y;
						normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
1612

A
alteredq 已提交
1613
						offset_normal += 3;
M
Mr.doob 已提交
1614

A
alteredq 已提交
1615
					}
1616

A
alteredq 已提交
1617
				}
1618

A
alteredq 已提交
1619
			}
M
Mr.doob 已提交
1620

A
alteredq 已提交
1621 1622
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
			_gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
M
Mr.doob 已提交
1623

A
alteredq 已提交
1624
		}
M
Mr.doob 已提交
1625

A
alteredq 已提交
1626
		if ( dirtyUvs && obj_uvs && uvType ) {
1627

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

A
alteredq 已提交
1630
				fi = chunk_faces3[ f ];
1631

A
alteredq 已提交
1632 1633
				face = obj_faces[ fi ];
				uv = obj_uvs[ fi ];
1634

A
alteredq 已提交
1635
				if ( uv === undefined ) continue;
1636

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

A
alteredq 已提交
1639
					uvi = uv[ i ];
1640

A
alteredq 已提交
1641 1642
					uvArray[ offset_uv ]     = uvi.u;
					uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
1643

A
alteredq 已提交
1644
					offset_uv += 2;
M
Mr.doob 已提交
1645

A
alteredq 已提交
1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666
				}

			}

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

				fi = chunk_faces4[ f ];

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

				if ( uv === undefined ) continue;

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

					uvi = uv[ i ];

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

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

1668 1669
				}

1670
			}
1671

A
alteredq 已提交
1672
			if ( offset_uv > 0 ) {
1673

A
alteredq 已提交
1674 1675
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
1676

A
alteredq 已提交
1677
			}
1678

A
alteredq 已提交
1679
		}
1680

A
alteredq 已提交
1681
		if ( dirtyUvs && obj_uvs2 && uvType ) {
1682

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

A
alteredq 已提交
1685
				fi = chunk_faces3[ f ];
1686

A
alteredq 已提交
1687 1688
				face = obj_faces[ fi ];
				uv2 = obj_uvs2[ fi ];
1689

A
alteredq 已提交
1690 1691 1692 1693 1694 1695 1696 1697 1698 1699
				if ( uv2 === undefined ) continue;

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

					uv2i = uv2[ i ];

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

					offset_uv2 += 2;
1700

1701 1702
				}

A
alteredq 已提交
1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723
			}

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

				fi = chunk_faces4[ f ];

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

				if ( uv2 === undefined ) continue;

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

					uv2i = uv2[ i ];

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

					offset_uv2 += 2;

				}
1724

1725
			}
1726

A
alteredq 已提交
1727
			if ( offset_uv2 > 0 ) {
1728

A
alteredq 已提交
1729 1730
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
				_gl.bufferData( _gl.ARRAY_BUFFER, uv2Array, hint );
1731

A
alteredq 已提交
1732
			}
1733

A
alteredq 已提交
1734
		}
1735

A
alteredq 已提交
1736
		if ( dirtyElements ) {
1737

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

A
alteredq 已提交
1740
				face = obj_faces[ chunk_faces3[ f ]	];
1741

A
alteredq 已提交
1742 1743 1744
				faceArray[ offset_face ] 	 = vertexIndex;
				faceArray[ offset_face + 1 ] = vertexIndex + 1;
				faceArray[ offset_face + 2 ] = vertexIndex + 2;
1745

A
alteredq 已提交
1746
				offset_face += 3;
1747

A
alteredq 已提交
1748 1749
				lineArray[ offset_line ]     = vertexIndex;
				lineArray[ offset_line + 1 ] = vertexIndex + 1;
1750

A
alteredq 已提交
1751 1752
				lineArray[ offset_line + 2 ] = vertexIndex;
				lineArray[ offset_line + 3 ] = vertexIndex + 2;
1753

A
alteredq 已提交
1754 1755
				lineArray[ offset_line + 4 ] = vertexIndex + 1;
				lineArray[ offset_line + 5 ] = vertexIndex + 2;
1756

A
alteredq 已提交
1757
				offset_line += 6;
1758

A
alteredq 已提交
1759
				vertexIndex += 3;
1760

A
alteredq 已提交
1761
			}
1762

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

A
alteredq 已提交
1765
				face = obj_faces[ chunk_faces4[ f ] ];
1766

A
alteredq 已提交
1767 1768 1769
				faceArray[ offset_face ]     = vertexIndex;
				faceArray[ offset_face + 1 ] = vertexIndex + 1;
				faceArray[ offset_face + 2 ] = vertexIndex + 3;
1770

A
alteredq 已提交
1771 1772 1773
				faceArray[ offset_face + 3 ] = vertexIndex + 1;
				faceArray[ offset_face + 4 ] = vertexIndex + 2;
				faceArray[ offset_face + 5 ] = vertexIndex + 3;
1774

A
alteredq 已提交
1775
				offset_face += 6;
1776

A
alteredq 已提交
1777 1778
				lineArray[ offset_line ]     = vertexIndex;
				lineArray[ offset_line + 1 ] = vertexIndex + 1;
1779

A
alteredq 已提交
1780 1781
				lineArray[ offset_line + 2 ] = vertexIndex;
				lineArray[ offset_line + 3 ] = vertexIndex + 3;
1782

A
alteredq 已提交
1783 1784
				lineArray[ offset_line + 4 ] = vertexIndex + 1;
				lineArray[ offset_line + 5 ] = vertexIndex + 2;
1785

A
alteredq 已提交
1786 1787
				lineArray[ offset_line + 6 ] = vertexIndex + 2;
				lineArray[ offset_line + 7 ] = vertexIndex + 3;
1788

A
alteredq 已提交
1789
				offset_line += 8;
1790

A
alteredq 已提交
1791
				vertexIndex += 4;
1792

1793
			}
1794

A
alteredq 已提交
1795 1796
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint );
1797

A
alteredq 已提交
1798 1799
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
1800

A
alteredq 已提交
1801
		}
1802

A
alteredq 已提交
1803
		if ( customAttributes ) {
1804

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

1807
				customAttribute = customAttributes[ i ];
1808

1809
				if ( ! customAttribute.__original.needsUpdate ) continue;
1810

1811 1812
				offset_custom = 0;
				offset_customSrc = 0;
1813

1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870
				if ( customAttribute.size === 1 ) {

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

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

							face = obj_faces[ chunk_faces3[ f ]	];

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

							offset_custom += 3;

						}

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

							face = obj_faces[ chunk_faces4[ f ] ];

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

							offset_custom += 4;

						}

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

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

							value = customAttribute.value[ offset_customSrc ];

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

							offset_custom += 3;
							offset_customSrc += 1;

						}

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

							value = customAttribute.value[ offset_customSrc ];

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

							offset_custom += 4;
							offset_customSrc += 1;

						}
1871

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

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

1876 1877 1878
							customAttribute.array[ offset_custom ] 	   = customAttribute.value[ offset_customSrc ];
							customAttribute.array[ offset_custom + 1 ] = customAttribute.value[ offset_customSrc + 1 ];
							customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ offset_customSrc + 2 ];
1879

1880 1881
							offset_custom += 3;
							offset_customSrc += 3;
M
Mr.doob 已提交
1882

1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915
						}

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

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

							offset_custom += 4;
							offset_customSrc += 4;

						}

					}

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

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

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

							face = obj_faces[ chunk_faces3[ f ]	];

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

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

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

1917 1918
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
1919

1920
							offset_custom += 6;
A
alteredq 已提交
1921

1922
						}
A
alteredq 已提交
1923

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

1926
							face = obj_faces[ chunk_faces4[ f ] ];
A
alteredq 已提交
1927

1928 1929 1930 1931
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
							v4 = customAttribute.value[ face.d ];
A
alteredq 已提交
1932

1933 1934
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
1935

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

1939 1940
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
1941

1942 1943
							customAttribute.array[ offset_custom + 6 ] = v4.x;
							customAttribute.array[ offset_custom + 7 ] = v4.y;
A
alteredq 已提交
1944

1945
							offset_custom += 8;
A
alteredq 已提交
1946

1947
						}
A
alteredq 已提交
1948

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

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

1953
							value = customAttribute.value[ offset_customSrc ];
A
alteredq 已提交
1954

1955 1956 1957
							v1 = value;
							v2 = value;
							v3 = value;
A
alteredq 已提交
1958

1959 1960
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
1961

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

1965 1966
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
1967

1968 1969
							offset_custom += 6;
							offset_customSrc += 1;
A
alteredq 已提交
1970

1971
						}
A
alteredq 已提交
1972

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

1975
							value = customAttribute.value[ offset_customSrc ];
A
alteredq 已提交
1976

1977 1978 1979 1980
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
A
alteredq 已提交
1981

1982 1983
							customAttribute.array[ offset_custom ] 	   = v1.x;
							customAttribute.array[ offset_custom + 1 ] = v1.y;
A
alteredq 已提交
1984

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

1988 1989
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
A
alteredq 已提交
1990

1991 1992
							customAttribute.array[ offset_custom + 6 ] = v4.x;
							customAttribute.array[ offset_custom + 7 ] = v4.y;
M
Mr.doob 已提交
1993

1994 1995
							offset_custom += 8;
							offset_customSrc += 1;
M
Mr.doob 已提交
1996

1997
						}
M
Mr.doob 已提交
1998

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

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

2003 2004 2005
							v1 = customAttribute.value[ offset_customSrc ];
							v2 = customAttribute.value[ offset_customSrc + 1 ];
							v3 = customAttribute.value[ offset_customSrc + 2 ];
M
Mr.doob 已提交
2006

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

2010 2011
							customAttribute.array[ offset_custom + 2 ] = v2.x;
							customAttribute.array[ offset_custom + 3 ] = v2.y;
2012

2013 2014
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
M
Mr.doob 已提交
2015

2016 2017
							offset_custom += 6;
							offset_customSrc += 3;
M
Mr.doob 已提交
2018

2019
						}
M
Mr.doob 已提交
2020

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

2023 2024 2025 2026
							v1 = customAttribute.value[ offset_customSrc ];
							v2 = customAttribute.value[ offset_customSrc + 1 ];
							v3 = customAttribute.value[ offset_customSrc + 2 ];
							v4 = customAttribute.value[ offset_customSrc + 3 ];
2027

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

2031 2032
							customAttribute.array[ offset_custom + 2 ] = v2.x;
							customAttribute.array[ offset_custom + 3 ] = v2.y;
2033

2034 2035
							customAttribute.array[ offset_custom + 4 ] = v3.x;
							customAttribute.array[ offset_custom + 5 ] = v3.y;
M
Mr.doob 已提交
2036

2037 2038
							customAttribute.array[ offset_custom + 6 ] = v4.x;
							customAttribute.array[ offset_custom + 7 ] = v4.y;
M
Mr.doob 已提交
2039

2040 2041
							offset_custom += 8;
							offset_customSrc += 4;
A
alteredq 已提交
2042 2043

						}
M
Mr.doob 已提交
2044 2045

					}
M
Mr.doob 已提交
2046

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

2049
					var pp;
2050

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

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

2055
					} else {
M
Mr.doob 已提交
2056

2057
						pp = [ "x", "y", "z" ];
2058

2059
					}
2060

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

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

2065
							face = obj_faces[ chunk_faces3[ f ]	];
2066

2067 2068 2069
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
2070

2071 2072 2073
							customAttribute.array[ offset_custom ] 	   = v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
2074

2075 2076 2077
							customAttribute.array[ offset_custom + 3 ] = v2[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 4 ] = v2[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 5 ] = v2[ pp[ 2 ] ];
2078

2079 2080 2081
							customAttribute.array[ offset_custom + 6 ] = v3[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 7 ] = v3[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 8 ] = v3[ pp[ 2 ] ];
M
Mr.doob 已提交
2082

2083
							offset_custom += 9;
M
Mr.doob 已提交
2084

2085
						}
M
Mr.doob 已提交
2086

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

2089
							face = obj_faces[ chunk_faces4[ f ] ];
M
Mr.doob 已提交
2090

2091 2092 2093 2094
							v1 = customAttribute.value[ face.a ];
							v2 = customAttribute.value[ face.b ];
							v3 = customAttribute.value[ face.c ];
							v4 = customAttribute.value[ face.d ];
M
Mr.doob 已提交
2095

2096 2097 2098
							customAttribute.array[ offset_custom  ] 	= v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1  ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2  ] = v1[ pp[ 2 ] ];
M
Mr.doob 已提交
2099

2100 2101 2102
							customAttribute.array[ offset_custom + 3  ] = v2[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 4  ] = v2[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 5  ] = v2[ pp[ 2 ] ];
M
Mr.doob 已提交
2103

2104 2105 2106
							customAttribute.array[ offset_custom + 6  ] = v3[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 7  ] = v3[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 8  ] = v3[ pp[ 2 ] ];
M
Mr.doob 已提交
2107

2108 2109 2110
							customAttribute.array[ offset_custom + 9  ] = v4[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 10 ] = v4[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 11 ] = v4[ pp[ 2 ] ];
M
Mr.doob 已提交
2111

2112 2113
							offset_custom += 12;
							offset_customSrc += 1;
M
Mr.doob 已提交
2114

2115
						}
M
Mr.doob 已提交
2116

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

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

2121
							value = customAttribute.value[ offset_customSrc ];
2122

2123 2124 2125
							v1 = value;
							v2 = value;
							v3 = value;
M
Mr.doob 已提交
2126

2127 2128 2129
							customAttribute.array[ offset_custom ] 	   = v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
M
Mr.doob 已提交
2130

2131 2132 2133
							customAttribute.array[ offset_custom + 3 ] = v2[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 4 ] = v2[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 5 ] = v2[ pp[ 2 ] ];
M
Mr.doob 已提交
2134

2135 2136 2137
							customAttribute.array[ offset_custom + 6 ] = v3[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 7 ] = v3[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 8 ] = v3[ pp[ 2 ] ];
M
Mr.doob 已提交
2138

2139 2140
							offset_custom += 9;
							offset_customSrc += 1;
M
Mr.doob 已提交
2141

2142
						}
2143

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

2146
							value = customAttribute.value[ offset_customSrc ];
2147

2148 2149 2150 2151
							v1 = value;
							v2 = value;
							v3 = value;
							v4 = value;
2152

2153 2154 2155
							customAttribute.array[ offset_custom  ] 	= v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1  ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2  ] = v1[ pp[ 2 ] ];
2156

2157 2158 2159
							customAttribute.array[ offset_custom + 3  ] = v2[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 4  ] = v2[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 5  ] = v2[ pp[ 2 ] ];
2160

2161 2162 2163
							customAttribute.array[ offset_custom + 6  ] = v3[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 7  ] = v3[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 8  ] = v3[ pp[ 2 ] ];
2164

2165 2166 2167
							customAttribute.array[ offset_custom + 9  ] = v4[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 10 ] = v4[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 11 ] = v4[ pp[ 2 ] ];
2168

2169 2170
							offset_custom += 12;
							offset_customSrc += 1;
2171

2172
						}
2173

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

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

2178 2179 2180
							v1 = customAttribute.value[ offset_customSrc ];
							v2 = customAttribute.value[ offset_customSrc + 1 ];
							v3 = customAttribute.value[ offset_customSrc + 2 ];
2181

2182 2183 2184
							customAttribute.array[ offset_custom ] 	   = v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
2185

2186 2187 2188
							customAttribute.array[ offset_custom + 3 ] = v2[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 4 ] = v2[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 5 ] = v2[ pp[ 2 ] ];
M
Mr.doob 已提交
2189

2190 2191 2192
							customAttribute.array[ offset_custom + 6 ] = v3[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 7 ] = v3[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 8 ] = v3[ pp[ 2 ] ];
M
Mr.doob 已提交
2193

2194 2195
							offset_custom += 9;
							offset_customSrc += 3;
2196

2197
						}
2198

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

2201 2202 2203 2204
							v1 = customAttribute.value[ offset_customSrc ];
							v2 = customAttribute.value[ offset_customSrc + 1 ];
							v3 = customAttribute.value[ offset_customSrc + 2 ];
							v4 = customAttribute.value[ offset_customSrc + 3 ];
2205

2206 2207 2208
							customAttribute.array[ offset_custom  ] 	= v1[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 1  ] = v1[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 2  ] = v1[ pp[ 2 ] ];
M
Mr.doob 已提交
2209

2210 2211 2212
							customAttribute.array[ offset_custom + 3  ] = v2[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 4  ] = v2[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 5  ] = v2[ pp[ 2 ] ];
M
Mr.doob 已提交
2213

2214 2215 2216
							customAttribute.array[ offset_custom + 6  ] = v3[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 7  ] = v3[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 8  ] = v3[ pp[ 2 ] ];
M
Mr.doob 已提交
2217

2218 2219 2220
							customAttribute.array[ offset_custom + 9  ] = v4[ pp[ 0 ] ];
							customAttribute.array[ offset_custom + 10 ] = v4[ pp[ 1 ] ];
							customAttribute.array[ offset_custom + 11 ] = v4[ pp[ 2 ] ];
2221

2222 2223
							offset_custom += 12;
							offset_customSrc += 4;
2224

A
alteredq 已提交
2225
						}
2226

A
alteredq 已提交
2227
					}
M
Mr.doob 已提交
2228

2229
				} else if ( customAttribute.size === 4 ) {
2230

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

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

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

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

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

							customAttribute.array[ offset_custom + 4  ] = v2.x;
							customAttribute.array[ offset_custom + 5  ] = v2.y;
							customAttribute.array[ offset_custom + 6  ] = v2.z;
							customAttribute.array[ offset_custom + 7  ] = v2.w;

							customAttribute.array[ offset_custom + 8  ] = v3.x;
							customAttribute.array[ offset_custom + 9  ] = v3.y;
							customAttribute.array[ offset_custom + 10 ] = v3.z;
							customAttribute.array[ offset_custom + 11 ] = v3.w;

							offset_custom += 12;

						}

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

							face = obj_faces[ chunk_faces4[ f ] ];

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

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

							customAttribute.array[ offset_custom + 4  ] = v2.x;
							customAttribute.array[ offset_custom + 5  ] = v2.y;
							customAttribute.array[ offset_custom + 6  ] = v2.z;
							customAttribute.array[ offset_custom + 7  ] = v2.w;

							customAttribute.array[ offset_custom + 8  ] = v3.x;
							customAttribute.array[ offset_custom + 9  ] = v3.y;
							customAttribute.array[ offset_custom + 10 ] = v3.z;
							customAttribute.array[ offset_custom + 11 ] = v3.w;

							customAttribute.array[ offset_custom + 12 ] = v4.x;
							customAttribute.array[ offset_custom + 13 ] = v4.y;
							customAttribute.array[ offset_custom + 14 ] = v4.z;
							customAttribute.array[ offset_custom + 15 ] = v4.w;

							offset_custom += 16;

						}

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

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

							value = customAttribute.value[ offset_customSrc ];

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

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

							customAttribute.array[ offset_custom + 4  ] = v2.x;
							customAttribute.array[ offset_custom + 5  ] = v2.y;
							customAttribute.array[ offset_custom + 6  ] = v2.z;
							customAttribute.array[ offset_custom + 7  ] = v2.w;

							customAttribute.array[ offset_custom + 8  ] = v3.x;
							customAttribute.array[ offset_custom + 9  ] = v3.y;
							customAttribute.array[ offset_custom + 10 ] = v3.z;
							customAttribute.array[ offset_custom + 11 ] = v3.w;

							offset_custom += 12;
							offset_customSrc += 1;

						}

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

							value = customAttribute.value[ offset_customSrc ];

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

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

							customAttribute.array[ offset_custom + 4  ] = v2.x;
							customAttribute.array[ offset_custom + 5  ] = v2.y;
							customAttribute.array[ offset_custom + 6  ] = v2.z;
							customAttribute.array[ offset_custom + 7  ] = v2.w;

							customAttribute.array[ offset_custom + 8  ] = v3.x;
							customAttribute.array[ offset_custom + 9  ] = v3.y;
							customAttribute.array[ offset_custom + 10 ] = v3.z;
							customAttribute.array[ offset_custom + 11 ] = v3.w;

							customAttribute.array[ offset_custom + 12 ] = v4.x;
							customAttribute.array[ offset_custom + 13 ] = v4.y;
							customAttribute.array[ offset_custom + 14 ] = v4.z;
							customAttribute.array[ offset_custom + 15 ] = v4.w;

							offset_custom += 16;
							offset_customSrc += 1;

						}

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

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

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

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

2370 2371 2372 2373
							customAttribute.array[ offset_custom + 4  ] = v2.x;
							customAttribute.array[ offset_custom + 5  ] = v2.y;
							customAttribute.array[ offset_custom + 6  ] = v2.z;
							customAttribute.array[ offset_custom + 7  ] = v2.w;
A
alteredq 已提交
2374

2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417
							customAttribute.array[ offset_custom + 8  ] = v3.x;
							customAttribute.array[ offset_custom + 9  ] = v3.y;
							customAttribute.array[ offset_custom + 10 ] = v3.z;
							customAttribute.array[ offset_custom + 11 ] = v3.w;

							offset_custom += 12;
							offset_customSrc += 3;

						}

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

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

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

							customAttribute.array[ offset_custom + 4  ] = v2.x;
							customAttribute.array[ offset_custom + 5  ] = v2.y;
							customAttribute.array[ offset_custom + 6  ] = v2.z;
							customAttribute.array[ offset_custom + 7  ] = v2.w;

							customAttribute.array[ offset_custom + 8  ] = v3.x;
							customAttribute.array[ offset_custom + 9  ] = v3.y;
							customAttribute.array[ offset_custom + 10 ] = v3.z;
							customAttribute.array[ offset_custom + 11 ] = v3.w;

							customAttribute.array[ offset_custom + 12 ] = v4.x;
							customAttribute.array[ offset_custom + 13 ] = v4.y;
							customAttribute.array[ offset_custom + 14 ] = v4.z;
							customAttribute.array[ offset_custom + 15 ] = v4.w;

							offset_custom += 16;
							offset_customSrc += 4;

						}

					}
A
alteredq 已提交
2418

A
alteredq 已提交
2419
				}
A
alteredq 已提交
2420

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

A
alteredq 已提交
2424
			}
2425

A
alteredq 已提交
2426
		}
2427

2428
		if ( dispose ) {
2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444

			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;

		}
2445

2446
	};
2447

2448
	function setLineBuffers ( geometry, hint ) {
M
Mr.doob 已提交
2449

2450
		var v, c, vertex, offset,
2451 2452 2453 2454
		vertices = geometry.vertices,
		colors = geometry.colors,
		vl = vertices.length,
		cl = colors.length,
M
Mr.doob 已提交
2455

2456 2457
		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,
2458

2459
		dirtyVertices = geometry.__dirtyVertices,
A
alteredq 已提交
2460 2461 2462 2463 2464 2465
		dirtyColors = geometry.__dirtyColors,

		customAttributes = geometry.__webglCustomAttributesList,
		i, il,
		a, ca, cal, value,
		customAttribute;
M
Mr.doob 已提交
2466

2467
		if ( dirtyVertices ) {
M
Mr.doob 已提交
2468

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

2471
				vertex = vertices[ v ].position;
M
Mr.doob 已提交
2472

2473
				offset = v * 3;
M
Mr.doob 已提交
2474

2475 2476 2477
				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;
M
Mr.doob 已提交
2478

2479 2480
			}

2481
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
A
alteredq 已提交
2482 2483
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );

2484
		}
M
Mr.doob 已提交
2485

2486 2487
		if ( dirtyColors ) {

2488
			for ( c = 0; c < cl; c ++ ) {
2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499

				color = colors[ c ];

				offset = c * 3;

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

			}

2500
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
2501 2502 2503 2504
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}

A
alteredq 已提交
2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574
		if ( customAttributes ) {

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

				customAttribute = customAttributes[ i ];

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

					offset = 0;

					cal = customAttribute.value.length;

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

						if ( customAttribute.size === 1 ) {

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

						} else {

							value = customAttribute.value[ ca ];

							if ( customAttribute.size === 2 ) {

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

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

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

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


								} else {

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

								}

							} else {

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

							}

						}

						offset += customAttribute.size;

					}

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

				}

			}

		}

2575
	};
M
Mr.doob 已提交
2576

2577
	function setRibbonBuffers ( geometry, hint ) {
A
alteredq 已提交
2578 2579

		var v, c, vertex, offset,
2580 2581 2582 2583
		vertices = geometry.vertices,
		colors = geometry.colors,
		vl = vertices.length,
		cl = colors.length,
A
alteredq 已提交
2584

2585 2586
		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,
2587

2588 2589
		dirtyVertices = geometry.__dirtyVertices,
		dirtyColors = geometry.__dirtyColors;
A
alteredq 已提交
2590 2591 2592

		if ( dirtyVertices ) {

2593
			for ( v = 0; v < vl; v ++ ) {
A
alteredq 已提交
2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604

				vertex = vertices[ v ].position;

				offset = v * 3;

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

			}

2605
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
A
alteredq 已提交
2606 2607 2608 2609 2610 2611
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );

		}

		if ( dirtyColors ) {

2612
			for ( c = 0; c < cl; c ++ ) {
A
alteredq 已提交
2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623

				color = colors[ c ];

				offset = c * 3;

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

			}

2624
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
A
alteredq 已提交
2625 2626 2627 2628 2629
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}

	};
2630

2631
	function setParticleBuffers ( geometry, hint, object ) {
2632

A
alteredq 已提交
2633
		var v, c, vertex, offset,
2634 2635
		vertices = geometry.vertices,
		vl = vertices.length,
2636

2637 2638
		colors = geometry.colors,
		cl = colors.length,
2639

2640 2641
		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,
2642

2643
		sortArray = geometry.__sortArray,
2644

2645 2646
		dirtyVertices = geometry.__dirtyVertices,
		dirtyElements = geometry.__dirtyElements,
2647 2648
		dirtyColors = geometry.__dirtyColors,

2649 2650
		customAttributes = geometry.__webglCustomAttributesList,
		i, il,
2651
		a, ca, cal, value,
2652 2653
		customAttribute;

2654
		if ( object.sortParticles ) {
2655

2656
			_projScreenMatrix.multiplySelf( object.matrixWorld );
2657

2658
			for ( v = 0; v < vl; v ++ ) {
2659 2660

				vertex = vertices[ v ].position;
2661

2662 2663
				_vector3.copy( vertex );
				_projScreenMatrix.multiplyVector3( _vector3 );
2664

2665
				sortArray[ v ] = [ _vector3.z, v ];
2666

2667
			}
2668

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

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

2673
				vertex = vertices[ sortArray[v][1] ].position;
2674

2675
				offset = v * 3;
2676

2677 2678 2679
				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;
2680

2681
			}
2682

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

A
alteredq 已提交
2685
				offset = c * 3;
2686

A
alteredq 已提交
2687 2688 2689 2690 2691
				color = colors[ sortArray[c][1] ];

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

2693
			}
2694

2695 2696
			if ( customAttributes ) {

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

2699
					customAttribute = customAttributes[ i ];
2700

2701 2702 2703 2704
					if ( ! ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) ) continue;

					offset = 0;

2705 2706 2707 2708
					cal = customAttribute.value.length;

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

A
alteredq 已提交
2709
						index = sortArray[ ca ][ 1 ];
2710 2711 2712

						if ( customAttribute.size === 1 ) {

2713
							customAttribute.array[ offset ] = customAttribute.value[ index ];
2714 2715 2716

						} else {

2717
							value = customAttribute.value[ index ];
2718 2719 2720

							if ( customAttribute.size === 2 ) {

2721 2722
								customAttribute.array[ offset ] 	= value.x;
								customAttribute.array[ offset + 1 ] = value.y;
2723 2724 2725 2726 2727

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

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

2728 2729 2730
									customAttribute.array[ offset ]     = value.r;
									customAttribute.array[ offset + 1 ] = value.g;
									customAttribute.array[ offset + 2 ] = value.b;
2731 2732 2733

								} else {

2734 2735 2736
									customAttribute.array[ offset ] 	= value.x;
									customAttribute.array[ offset + 1 ] = value.y;
									customAttribute.array[ offset + 2 ] = value.z;
2737 2738 2739 2740 2741

								}

							} else {

2742 2743 2744 2745
								customAttribute.array[ offset ]      = value.x;
								customAttribute.array[ offset + 1  ] = value.y;
								customAttribute.array[ offset + 2  ] = value.z;
								customAttribute.array[ offset + 3  ] = value.w;
2746 2747 2748 2749 2750

							}

						}

2751
						offset += customAttribute.size;
2752 2753 2754 2755 2756 2757 2758

					}

				}

			}

2759
		} else {
2760

2761 2762
			if ( dirtyVertices ) {

2763
				for ( v = 0; v < vl; v ++ ) {
2764 2765 2766 2767 2768 2769 2770 2771 2772 2773

					vertex = vertices[ v ].position;

					offset = v * 3;

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

				}
2774 2775

			}
2776

A
alteredq 已提交
2777
			if ( dirtyColors ) {
2778

2779
				for ( c = 0; c < cl; c ++ ) {
A
alteredq 已提交
2780 2781 2782 2783 2784 2785 2786 2787 2788

					color = colors[ c ];

					offset = c * 3;

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

2789
				}
2790

A
alteredq 已提交
2791
			}
2792

2793 2794
			if ( customAttributes ) {

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

2797
					customAttribute = customAttributes[ i ];
2798

2799 2800 2801
					if ( customAttribute.__original.needsUpdate &&
					     ( customAttribute.boundTo === undefined ||
						   customAttribute.boundTo === "vertices") ) {
2802 2803 2804

						cal = customAttribute.value.length;

2805 2806
						offset = 0;

2807 2808 2809 2810 2811 2812
						for ( ca = 0; ca < cal; ca ++ ) {

							offset_custom = customAttribute.offset;

							if ( customAttribute.size === 1 ) {

2813
								customAttribute.array[ offset ] = customAttribute.value[ ca ];
2814 2815 2816

							} else {

2817
								value = customAttribute.value[ ca ];
2818 2819 2820

								if ( customAttribute.size === 2 ) {

2821 2822
									customAttribute.array[ offset ] 	= value.x;
									customAttribute.array[ offset + 1 ] = value.y;
2823 2824 2825 2826 2827

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

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

2828 2829 2830
										customAttribute.array[ offset ] 	= value.r;
										customAttribute.array[ offset + 1 ] = value.g;
										customAttribute.array[ offset + 2 ] = value.b;
2831 2832 2833 2834


									} else {

2835 2836 2837
										customAttribute.array[ offset ] 	= value.x;
										customAttribute.array[ offset + 1 ] = value.y;
										customAttribute.array[ offset + 2 ] = value.z;
2838 2839 2840 2841 2842

									}

								} else {

2843 2844 2845 2846
									customAttribute.array[ offset ]      = value.x;
									customAttribute.array[ offset + 1  ] = value.y;
									customAttribute.array[ offset + 2  ] = value.z;
									customAttribute.array[ offset + 3  ] = value.w;
2847 2848 2849 2850 2851

								}

							}

2852
							offset += customAttribute.size;
2853 2854 2855 2856 2857 2858 2859 2860 2861

						}

					}

				}

			}

2862
		}
2863

A
alteredq 已提交
2864
		if ( dirtyVertices || object.sortParticles ) {
2865

2866
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
A
alteredq 已提交
2867
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
2868

A
alteredq 已提交
2869
		}
2870

A
alteredq 已提交
2871
		if ( dirtyColors || object.sortParticles ) {
2872

2873
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
A
alteredq 已提交
2874
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
2875

A
alteredq 已提交
2876
		}
2877

2878 2879
		if ( customAttributes ) {

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

2882
				customAttribute = customAttributes[ i ];
2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895

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

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

				}

			}

		}


2896
	};
M
Mr.doob 已提交
2897

2898
	function setMaterialShaders( material, shaders ) {
2899

2900
		material.uniforms = THREE.UniformsUtils.clone( shaders.uniforms );
2901 2902
		material.vertexShader = shaders.vertexShader;
		material.fragmentShader = shaders.fragmentShader;
2903

M
Mr.doob 已提交
2904
	};
2905

2906
	function refreshUniformsCommon( uniforms, material ) {
M
Mr.doob 已提交
2907

A
alteredq 已提交
2908
		uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
2909

2910 2911 2912 2913 2914 2915 2916 2917 2918 2919
		if ( _this.gammaInput ) {

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

		} else {

			uniforms.diffuse.value = material.color;

		}

A
alteredq 已提交
2920
		uniforms.map.texture = material.map;
2921

2922
		if ( material.map ) {
M
Mr.doob 已提交
2923

2924 2925 2926
			uniforms.offsetRepeat.value.set( material.map.offset.x, material.map.offset.y, material.map.repeat.x, material.map.repeat.y );

		}
2927

2928
		uniforms.lightMap.texture = material.lightMap;
2929

2930
		uniforms.envMap.texture = material.envMap;
2931
		uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : -1;
2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943

		if ( _this.gammaInput ) {

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

		} else {

			uniforms.reflectivity.value = material.reflectivity;

		}

2944
		uniforms.refractionRatio.value = material.refractionRatio;
A
alteredq 已提交
2945
		uniforms.combine.value = material.combine;
2946
		uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
2947

2948
	};
2949

2950
	function refreshUniformsLine( uniforms, material ) {
2951

M
Mr.doob 已提交
2952
		uniforms.diffuse.value = material.color;
A
alteredq 已提交
2953
		uniforms.opacity.value = material.opacity;
2954 2955

	};
M
Mr.doob 已提交
2956

2957
	function refreshUniformsParticle( uniforms, material ) {
2958

M
Mr.doob 已提交
2959
		uniforms.psColor.value = material.color;
A
alteredq 已提交
2960 2961
		uniforms.opacity.value = material.opacity;
		uniforms.size.value = material.size;
M
Mr.doob 已提交
2962
		uniforms.scale.value = _canvas.height / 2.0; // TODO: Cache this.
2963

A
alteredq 已提交
2964
		uniforms.map.texture = material.map;
2965

A
alteredq 已提交
2966
	};
2967

2968
	function refreshUniformsFog( uniforms, fog ) {
2969

M
Mr.doob 已提交
2970
		uniforms.fogColor.value = fog.color;
2971

A
alteredq 已提交
2972
		if ( fog instanceof THREE.Fog ) {
2973

A
alteredq 已提交
2974 2975
			uniforms.fogNear.value = fog.near;
			uniforms.fogFar.value = fog.far;
2976

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

A
alteredq 已提交
2979
			uniforms.fogDensity.value = fog.density;
2980 2981

		}
2982

2983 2984
	};

2985
	function refreshUniformsPhong( uniforms, material ) {
M
Mr.doob 已提交
2986

A
alteredq 已提交
2987
		uniforms.shininess.value = material.shininess;
M
Mr.doob 已提交
2988

2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000
		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;

		}

3001
	};
M
Mr.doob 已提交
3002

3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015
	function refreshUniformsLambert( uniforms, material ) {

		if ( _this.gammaInput ) {

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

		} else {

			uniforms.ambient.value = material.ambient;

		}

	};
M
Mr.doob 已提交
3016

3017
	function refreshUniformsLights( uniforms, lights ) {
M
Mr.doob 已提交
3018

A
alteredq 已提交
3019 3020
		uniforms.enableLighting.value = lights.directional.length + lights.point.length;
		uniforms.ambientLightColor.value = lights.ambient;
3021

A
alteredq 已提交
3022 3023
		uniforms.directionalLightColor.value = lights.directional.colors;
		uniforms.directionalLightDirection.value = lights.directional.positions;
3024

A
alteredq 已提交
3025 3026
		uniforms.pointLightColor.value = lights.point.colors;
		uniforms.pointLightPosition.value = lights.point.positions;
3027
		uniforms.pointLightDistance.value = lights.point.distances;
M
Mr.doob 已提交
3028

A
alteredq 已提交
3029
	};
M
Mr.doob 已提交
3030

3031 3032 3033 3034
	function refreshUniformsShadow( uniforms, material ) {

		if ( uniforms.shadowMatrix ) {

3035 3036 3037 3038 3039 3040 3041
			for ( var i = 0; i < _shadowMatrix.length; i ++ ) {

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


			}
3042 3043 3044 3045 3046 3047 3048 3049

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

		}

	};

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

3052
		var u, a, identifiers, i, parameters, maxLightCount, maxBones, maxShadows, shaderID;
3053

A
alteredq 已提交
3054
		if ( material instanceof THREE.MeshDepthMaterial ) {
3055

3056
			shaderID = 'depth';
3057

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

3060
			shaderID = 'normal';
3061

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

3064
			shaderID = 'basic';
3065

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

3068
			shaderID = 'lambert';
M
Mr.doob 已提交
3069

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

3072
			shaderID = 'phong';
M
Mr.doob 已提交
3073

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

3076
			shaderID = 'basic';
3077

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

3080 3081 3082 3083 3084 3085 3086
			shaderID = 'particle_basic';

		}

		if ( shaderID ) {

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

A
alteredq 已提交
3088
		}
3089

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

3093
		maxLightCount = allocateLights( lights );
3094

3095 3096
		maxShadows = allocateShadows( lights );

3097
		maxBones = allocateBones( object );
M
Mr.doob 已提交
3098

3099
		parameters = {
3100

M
Mr.doob 已提交
3101
			map: !!material.map, envMap: !!material.envMap, lightMap: !!material.lightMap,
3102
			vertexColors: material.vertexColors,
M
Mr.doob 已提交
3103 3104
			fog: fog, useFog: material.fog,
			sizeAttenuation: material.sizeAttenuation,
3105 3106
			skinning: material.skinning,
			morphTargets: material.morphTargets,
3107
			maxMorphTargets: this.maxMorphTargets,
3108
			maxDirLights: maxLightCount.directional, maxPointLights: maxLightCount.point,
3109
			maxBones: maxBones,
3110
			shadowMapEnabled: this.shadowMapEnabled && object.receiveShadow,
3111 3112 3113
			shadowMapSoft: this.shadowMapSoft,
			shadowMapWidth: this.shadowMapWidth,
			shadowMapHeight: this.shadowMapHeight,
3114
			maxShadows: maxShadows,
3115 3116 3117
			alphaTest: material.alphaTest,
			metal: material.metal,
			perPixel: material.perPixel
3118

3119
		};
M
Mikael Emtinger 已提交
3120

3121
		material.program = buildProgram( shaderID, material.fragmentShader, material.vertexShader, material.uniforms, material.attributes, parameters );
3122

3123
		var attributes = material.program.attributes;
3124

3125
		if ( attributes.position >= 0 ) _gl.enableVertexAttribArray( attributes.position );
3126 3127 3128
		if ( attributes.color >= 0 ) _gl.enableVertexAttribArray( attributes.color );
		if ( attributes.normal >= 0 ) _gl.enableVertexAttribArray( attributes.normal );
		if ( attributes.tangent >= 0 ) _gl.enableVertexAttribArray( attributes.tangent );
3129

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

3134 3135 3136 3137
			_gl.enableVertexAttribArray( attributes.skinVertexA );
			_gl.enableVertexAttribArray( attributes.skinVertexB );
			_gl.enableVertexAttribArray( attributes.skinIndex );
			_gl.enableVertexAttribArray( attributes.skinWeight );
3138

3139
		}
3140

3141
		if ( material.attributes ) {
M
Mr.doob 已提交
3142

3143
			for ( a in material.attributes ) {
M
Mr.doob 已提交
3144

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

3147
			}
M
Mr.doob 已提交
3148

3149
		}
3150

3151
		if ( material.morphTargets ) {
3152

3153
			material.numSupportedMorphTargets = 0;
3154

3155
			var id, base = "morphTarget";
3156

3157
			for ( i = 0; i < this.maxMorphTargets; i ++ ) {
3158

3159
				id = base + i;
3160

3161
				if ( attributes[ id ] >= 0 ) {
3162

3163 3164
					_gl.enableVertexAttribArray( attributes[ id ] );
					material.numSupportedMorphTargets ++;
3165

3166
				}
3167

3168
			}
3169

3170
		}
M
Mr.doob 已提交
3171

M
Mr.doob 已提交
3172 3173 3174 3175 3176 3177 3178 3179
		material.uniformsList = [];

		for ( u in material.uniforms ) {

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

		}

3180
	};
3181

3182
	function setProgram( camera, lights, fog, material, object ) {
3183

3184
		if ( ! material.program ) {
3185 3186 3187 3188

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

		}
M
Mr.doob 已提交
3189

3190 3191 3192 3193 3194 3195
		if ( material.morphTargets ) {

			if ( ! object.__webglMorphTargetInfluences ) {

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

3196
				for ( var i = 0, il = _this.maxMorphTargets; i < il; i ++ ) {
3197 3198 3199 3200 3201 3202 3203 3204 3205

					object.__webglMorphTargetInfluences[ i ] = 0;

				}

			}

		}

M
Mr.doob 已提交
3206 3207
		var refreshMaterial = false;

3208
		var program = material.program,
A
alteredq 已提交
3209 3210
			p_uniforms = program.uniforms,
			m_uniforms = material.uniforms;
3211

3212
		if ( program !== _currentProgram ) {
M
Mr.doob 已提交
3213

M
Mr.doob 已提交
3214
			_gl.useProgram( program );
3215
			_currentProgram = program;
3216

M
Mr.doob 已提交
3217 3218
			refreshMaterial = true;

M
Mr.doob 已提交
3219
		}
3220

3221
		if ( material.id !== _currentMaterialId ) {
3222

M
Mr.doob 已提交
3223 3224
			_currentMaterialId = material.id;
			refreshMaterial = true;
3225

M
Mr.doob 已提交
3226
		}
3227

M
Mr.doob 已提交
3228
		if ( refreshMaterial ) {
3229

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

M
Mr.doob 已提交
3232
			// refresh uniforms common to several materials
3233

M
Mr.doob 已提交
3234
			if ( fog && material.fog ) {
M
Mr.doob 已提交
3235

M
Mr.doob 已提交
3236
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
3237

M
Mr.doob 已提交
3238
			}
M
Mr.doob 已提交
3239

M
Mr.doob 已提交
3240 3241 3242
			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material.lights ) {
M
Mr.doob 已提交
3243

M
Mr.doob 已提交
3244 3245
				setupLights( program, lights );
				refreshUniformsLights( m_uniforms, _lights );
M
Mr.doob 已提交
3246

M
Mr.doob 已提交
3247
			}
3248

M
Mr.doob 已提交
3249 3250 3251
			if ( material instanceof THREE.MeshBasicMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
3252

M
Mr.doob 已提交
3253
				refreshUniformsCommon( m_uniforms, material );
3254

M
Mr.doob 已提交
3255
			}
3256

M
Mr.doob 已提交
3257
			// refresh single material specific uniforms
3258

M
Mr.doob 已提交
3259
			if ( material instanceof THREE.LineBasicMaterial ) {
M
Mr.doob 已提交
3260

M
Mr.doob 已提交
3261
				refreshUniformsLine( m_uniforms, material );
M
Mr.doob 已提交
3262

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

M
Mr.doob 已提交
3265
				refreshUniformsParticle( m_uniforms, material );
3266

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

M
Mr.doob 已提交
3269
				refreshUniformsPhong( m_uniforms, material );
3270

3271 3272 3273 3274
			} else if ( material instanceof THREE.MeshLambertMaterial ) {

				refreshUniformsLambert( m_uniforms, material );

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

M
Mr.doob 已提交
3277 3278 3279
				m_uniforms.mNear.value = camera.near;
				m_uniforms.mFar.value = camera.far;
				m_uniforms.opacity.value = material.opacity;
3280

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

M
Mr.doob 已提交
3283
				m_uniforms.opacity.value = material.opacity;
3284

M
Mr.doob 已提交
3285
			}
3286

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

M
Mr.doob 已提交
3289
				refreshUniformsShadow( m_uniforms, material );
3290

M
Mr.doob 已提交
3291
			}
3292

M
Mr.doob 已提交
3293
			// load common uniforms
M
Mr.doob 已提交
3294

M
Mr.doob 已提交
3295
			loadUniformsGeneric( program, material.uniformsList );
M
Mr.doob 已提交
3296

M
Mr.doob 已提交
3297 3298
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)
3299

M
Mr.doob 已提交
3300 3301 3302
			if ( material instanceof THREE.ShaderMaterial ||
				 material instanceof THREE.MeshPhongMaterial ||
				 material.envMap ) {
3303

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

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

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

3310
			}
3311

M
Mr.doob 已提交
3312 3313 3314 3315
			if ( material instanceof THREE.MeshPhongMaterial ||
				 material instanceof THREE.MeshLambertMaterial ||
				 material instanceof THREE.ShaderMaterial ||
				 material.skinning ) {
3316

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

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

M
Mr.doob 已提交
3321 3322 3323 3324 3325 3326 3327
				}

			}

			if ( material.skinning ) {

				loadUniformsSkinning( p_uniforms, object );
M
Mr.doob 已提交
3328 3329

			}
3330

A
alteredq 已提交
3331
		}
3332

M
Mr.doob 已提交
3333 3334 3335 3336 3337 3338 3339 3340 3341 3342
		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 );
3343

M
Mr.doob 已提交
3344
			}
3345

A
alteredq 已提交
3346
		}
3347

A
alteredq 已提交
3348
		return program;
3349

A
alteredq 已提交
3350
	};
3351

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

3354
		if ( material.opacity === 0 ) return;
3355

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

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

3360
		attributes = program.attributes;
M
Mr.doob 已提交
3361

M
Mr.doob 已提交
3362
		var updateBuffers = false,
3363 3364
			wireframeBit = material.wireframe ? 1 : 0,
			geometryGroupHash = ( geometryGroup.id * 0xffffff ) + ( program.id * 2 ) + wireframeBit;
M
Mr.doob 已提交
3365

3366
		if ( geometryGroupHash !== _currentGeometryGroupHash ) {
M
Mr.doob 已提交
3367 3368 3369 3370 3371 3372

			_currentGeometryGroupHash = geometryGroupHash;
			updateBuffers = true;

		}

3373
		// vertices
M
Mr.doob 已提交
3374

3375
		if ( !material.morphTargets && attributes.position >= 0 ) {
3376

M
Mr.doob 已提交
3377 3378 3379 3380 3381 3382
			if ( updateBuffers ) {

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

			}
3383

3384
		} else {
3385

3386 3387 3388 3389 3390
			if ( object.morphTargetBase ) {

				setupMorphTargets( material, geometryGroup, object );

			}
3391

3392 3393
		}

3394

M
Mr.doob 已提交
3395
		if ( updateBuffers ) {
3396

M
Mr.doob 已提交
3397
			// custom attributes
3398

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

3401
			if ( geometryGroup.__webglCustomAttributesList ) {
M
Mr.doob 已提交
3402

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

3405
					attribute = geometryGroup.__webglCustomAttributesList[ i ];
M
Mr.doob 已提交
3406

3407
					if( attributes[ attribute.buffer.belongsToAttribute ] >= 0 ) {
M
Mr.doob 已提交
3408 3409

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

					}
M
Mr.doob 已提交
3413

3414
				}
M
Mr.doob 已提交
3415

3416
			}
M
Mr.doob 已提交
3417

3418

M
Mr.doob 已提交
3419
			// colors
3420

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

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

M
Mr.doob 已提交
3426
			}
A
alteredq 已提交
3427

M
Mr.doob 已提交
3428
			// normals
A
alteredq 已提交
3429

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

M
Mr.doob 已提交
3432 3433
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
				_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
3434

M
Mr.doob 已提交
3435
			}
3436

M
Mr.doob 已提交
3437
			// tangents
3438

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

M
Mr.doob 已提交
3441 3442
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
				_gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
3443

M
Mr.doob 已提交
3444
			}
3445

M
Mr.doob 已提交
3446
			// uvs
3447

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

M
Mr.doob 已提交
3450
				if ( geometryGroup.__webglUVBuffer ) {
M
Mr.doob 已提交
3451

M
Mr.doob 已提交
3452 3453
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
					_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
3454

M
Mr.doob 已提交
3455
					_gl.enableVertexAttribArray( attributes.uv );
3456

M
Mr.doob 已提交
3457
				} else {
3458

M
Mr.doob 已提交
3459
					_gl.disableVertexAttribArray( attributes.uv );
3460

M
Mr.doob 已提交
3461
				}
M
Mr.doob 已提交
3462

3463
			}
3464

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

M
Mr.doob 已提交
3467
				if ( geometryGroup.__webglUV2Buffer ) {
3468

M
Mr.doob 已提交
3469 3470
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
					_gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );
3471

M
Mr.doob 已提交
3472
					_gl.enableVertexAttribArray( attributes.uv2 );
3473

M
Mr.doob 已提交
3474
				} else {
3475

M
Mr.doob 已提交
3476
					_gl.disableVertexAttribArray( attributes.uv2 );
3477

M
Mr.doob 已提交
3478
				}
3479 3480 3481

			}

M
Mr.doob 已提交
3482 3483 3484
			if ( material.skinning &&
				 attributes.skinVertexA >= 0 && attributes.skinVertexB >= 0 &&
				 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
3485

M
Mr.doob 已提交
3486 3487
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
				_gl.vertexAttribPointer( attributes.skinVertexA, 4, _gl.FLOAT, false, 0, 0 );
3488

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

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

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

M
Mr.doob 已提交
3498
			}
3499

A
alteredq 已提交
3500
		}
3501

3502
		// render mesh
M
Mr.doob 已提交
3503

3504
		if ( object instanceof THREE.Mesh ) {
3505

3506
			// wireframe
3507

3508
			if ( material.wireframe ) {
M
Mr.doob 已提交
3509

3510
				_gl.lineWidth( material.wireframeLinewidth );
M
Mr.doob 已提交
3511 3512

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

3515
			// triangles
3516

3517
			} else {
3518

M
Mr.doob 已提交
3519
				if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
3520 3521
				_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );

3522
			}
3523

M
Mr.doob 已提交
3524 3525 3526
			_this.info.render.calls ++;
			_this.info.render.vertices += geometryGroup.__webglFaceCount;
			_this.info.render.faces += geometryGroup.__webglFaceCount / 3;
3527

3528
		// render lines
3529

3530
		} else if ( object instanceof THREE.Line ) {
3531

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

3534
			_gl.lineWidth( material.linewidth );
3535
			_gl.drawArrays( primitives, 0, geometryGroup.__webglLineCount );
3536

M
Mr.doob 已提交
3537
			_this.info.render.calls ++;
3538

3539
		// render particles
3540

3541
		} else if ( object instanceof THREE.ParticleSystem ) {
3542

3543
			_gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webglParticleCount );
3544

M
Mr.doob 已提交
3545
			_this.info.render.calls ++;
3546

A
alteredq 已提交
3547
		// render ribbon
3548

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

3551
			_gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webglVertexCount );
3552

M
Mr.doob 已提交
3553
			_this.info.render.calls ++;
3554

3555 3556 3557 3558
		}

	};

M
Mikael Emtinger 已提交
3559

M
Mikael Emtinger 已提交
3560
	function setupMorphTargets( material, geometryGroup, object ) {
3561

M
Mikael Emtinger 已提交
3562
		// set base
3563

M
Mikael Emtinger 已提交
3564
		var attributes = material.program.attributes;
3565

3566
		if ( object.morphTargetBase !== - 1 ) {
3567 3568

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

3571
		} else if ( attributes.position >= 0 ) {
3572 3573

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

M
Mikael Emtinger 已提交
3576
		}
3577

3578
		if ( object.morphTargetForcedOrder.length ) {
M
Mikael Emtinger 已提交
3579 3580

			// set forced order
3581

M
Mikael Emtinger 已提交
3582 3583 3584
			var m = 0;
			var order = object.morphTargetForcedOrder;
			var influences = object.morphTargetInfluences;
3585 3586 3587 3588

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

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

3591
				object.__webglMorphTargetInfluences[ m ] = influences[ order[ m ] ];
3592 3593 3594

				m ++;
			}
3595

M
Mikael Emtinger 已提交
3596
		} else {
3597

M
Mikael Emtinger 已提交
3598
			// find most influencing
3599

M
Mikael Emtinger 已提交
3600
			var used = [];
3601
			var candidateInfluence = - 1;
M
Mikael Emtinger 已提交
3602 3603 3604 3605
			var candidate = 0;
			var influences = object.morphTargetInfluences;
			var i, il = influences.length;
			var m = 0;
3606

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

M
Mikael Emtinger 已提交
3609
				used[ object.morphTargetBase ] = true;
3610

M
Mikael Emtinger 已提交
3611
			}
3612 3613 3614

			while ( m < material.numSupportedMorphTargets ) {

3615
				for ( i = 0; i < il; i ++ ) {
3616 3617 3618

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

M
Mikael Emtinger 已提交
3619 3620
						candidate = i;
						candidateInfluence = influences[ candidate ];
3621

M
Mikael Emtinger 已提交
3622
					}
3623

M
Mikael Emtinger 已提交
3624
				}
3625 3626

				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ candidate ] );
M
Mikael Emtinger 已提交
3627
				_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
3628 3629 3630

				object.__webglMorphTargetInfluences[ m ] = candidateInfluence;

M
Mikael Emtinger 已提交
3631 3632
				used[ candidate ] = 1;
				candidateInfluence = -1;
3633
				m ++;
3634

M
Mikael Emtinger 已提交
3635
			}
3636

M
Mikael Emtinger 已提交
3637 3638 3639
		}

		// load updated influences uniform
3640

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

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

3645 3646
		}

M
Mikael Emtinger 已提交
3647 3648 3649
	}


3650
	function renderBufferImmediate( object, program, shading ) {
3651

3652 3653
		if ( ! object.__webglVertexBuffer ) object.__webglVertexBuffer = _gl.createBuffer();
		if ( ! object.__webglNormalBuffer ) object.__webglNormalBuffer = _gl.createBuffer();
3654

A
alteredq 已提交
3655
		if ( object.hasPos ) {
3656

3657 3658 3659 3660
			_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 );
3661

A
alteredq 已提交
3662
		}
3663

A
alteredq 已提交
3664
		if ( object.hasNormal ) {
3665

3666
			_gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglNormalBuffer );
3667

3668
			if ( shading === THREE.FlatShading ) {
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

				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 已提交
3695
					normalArray[ i ] 	 = nx;
3696 3697 3698
					normalArray[ i + 1 ] = ny;
					normalArray[ i + 2 ] = nz;

M
Mr.doob 已提交
3699
					normalArray[ i + 3 ] = nx;
3700 3701 3702
					normalArray[ i + 4 ] = ny;
					normalArray[ i + 5 ] = nz;

M
Mr.doob 已提交
3703
					normalArray[ i + 6 ] = nx;
3704 3705 3706 3707 3708 3709 3710
					normalArray[ i + 7 ] = ny;
					normalArray[ i + 8 ] = nz;

				}

			}

3711 3712 3713
			_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 );
3714

A
alteredq 已提交
3715
		}
3716

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

A
alteredq 已提交
3719
		object.count = 0;
3720

A
alteredq 已提交
3721
	};
3722

3723
	function setObjectFaces( object ) {
3724

3725
		if ( _oldDoubleSided !== object.doubleSided ) {
3726

3727
			if( object.doubleSided ) {
3728

3729
				_gl.disable( _gl.CULL_FACE );
3730

3731
			} else {
3732

A
alteredq 已提交
3733
				_gl.enable( _gl.CULL_FACE );
3734

A
alteredq 已提交
3735
			}
3736

3737
			_oldDoubleSided = object.doubleSided;
3738

3739
		}
3740

3741
		if ( _oldFlipSided !== object.flipSided ) {
3742

3743 3744 3745 3746
			if( object.flipSided ) {

				_gl.frontFace( _gl.CW );

3747
			} else {
3748 3749 3750 3751

				_gl.frontFace( _gl.CCW );

			}
3752

3753
			_oldFlipSided = object.flipSided;
3754 3755

		}
3756

3757
	};
3758

M
Mr.doob 已提交
3759
	function setDepthTest( depthTest ) {
3760

3761
		if ( _oldDepthTest !== depthTest ) {
A
alteredq 已提交
3762

M
Mr.doob 已提交
3763
			if( depthTest ) {
3764

A
alteredq 已提交
3765
				_gl.enable( _gl.DEPTH_TEST );
3766

A
alteredq 已提交
3767
			} else {
3768

A
alteredq 已提交
3769
				_gl.disable( _gl.DEPTH_TEST );
3770

A
alteredq 已提交
3771
			}
3772

M
Mr.doob 已提交
3773 3774 3775 3776 3777 3778 3779 3780
			_oldDepthTest = depthTest;

		}

	};

	function setDepthWrite( depthWrite ) {

3781
		if ( _oldDepthWrite !== depthWrite ) {
M
Mr.doob 已提交
3782 3783 3784

			_gl.depthMask( depthWrite );
			_oldDepthWrite = depthWrite;
A
alteredq 已提交
3785 3786

		}
3787

A
alteredq 已提交
3788
	};
M
Mr.doob 已提交
3789 3790 3791

	function setPolygonOffset ( polygonoffset, factor, units ) {

3792
		if ( _oldPolygonOffset !== polygonoffset ) {
M
Mr.doob 已提交
3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807

			if ( polygonoffset ) {

				_gl.enable( _gl.POLYGON_OFFSET_FILL );

			} else {

				_gl.disable( _gl.POLYGON_OFFSET_FILL );

			}

			_oldPolygonOffset = polygonoffset;

		}

3808
		if ( polygonoffset && ( _oldPolygonOffsetFactor !== factor || _oldPolygonOffsetUnits !== units ) ) {
M
Mr.doob 已提交
3809 3810 3811 3812 3813 3814 3815 3816 3817

			_gl.polygonOffset( factor, units );

			_oldPolygonOffsetFactor = factor;
			_oldPolygonOffsetUnits = units;

		}

	};
3818

M
Mr.doob 已提交
3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854
	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;

	};

3855
	function addToFixedArray( where, what ) {
3856

3857 3858
		where.list[ where.count ] = what;
		where.count += 1;
3859

3860
	};
3861

3862
	function unrollImmediateBufferMaterial( globject ) {
3863

3864 3865
		var object = globject.object,
			material = object.material;
3866

3867
		if ( material.transparent ) {
3868

3869 3870
			globject.transparent = material;
			globject.opaque = null;
3871

3872 3873 3874 3875
		} else {

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

3877
		}
3878

3879
	};
3880

3881
	function unrollBufferMaterial( globject ) {
3882

3883
		var object = globject.object,
3884
			buffer = globject.buffer,
3885 3886 3887 3888 3889 3890 3891
			material, materialIndex, meshMaterial;

		meshMaterial = object.material;

		if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {

			materialIndex = buffer.materialIndex;
3892

3893
			if ( materialIndex >= 0 ) {
3894

3895
				material = object.geometry.materials[ materialIndex ];
3896

3897
				if ( material.transparent ) {
3898

3899 3900
					globject.transparent = material;
					globject.opaque = null;
3901

3902
				} else {
3903

3904 3905
					globject.opaque = material;
					globject.transparent = null;
3906 3907 3908

				}

3909 3910 3911
			}

		} else {
3912

3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927
			material = meshMaterial;

			if ( material ) {

				if ( material.transparent ) {

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

				} else {

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

				}
3928

3929 3930 3931
			}

		}
3932

3933
	};
3934

3935
	function painterSort( a, b ) {
3936

3937
		return b.z - a.z;
3938 3939

	};
3940

3941 3942 3943
	function renderShadowMap( scene, camera ) {

		var i, il, light,
3944 3945
			j = 0,
			shadowMap, shadowMatrix,
3946 3947 3948
			oil,
			material,
			o, ol, webglObject, object,
3949
			lights = scene.lights,
3950 3951 3952 3953
			fog = null;

		if ( ! _cameraLight ) {

M
Mr.doob 已提交
3954
			_cameraLight = new THREE.PerspectiveCamera( _this.shadowCameraFov, _this.shadowMapWidth / _this.shadowMapHeight, _this.shadowCameraNear, _this.shadowCameraFar );
3955 3956 3957 3958 3959 3960 3961 3962 3963

		}

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

			light = lights[ i ];

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

M
Mr.doob 已提交
3964 3965
				_currentMaterialId = -1;

3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981
				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 ];

3982
				_cameraLight.position.copy( light.position );
M
Mr.doob 已提交
3983
				_cameraLight.lookAt( light.target.position );
3984

A
alteredq 已提交
3985
				if ( _cameraLight.parent == null ) {
3986

A
alteredq 已提交
3987 3988 3989 3990 3991
					console.warn( "Camera is not on the Scene. Adding it..." );
					scene.add( _cameraLight );

				}

3992
				if ( this.autoUpdateScene ) scene.updateMatrixWorld();
A
alteredq 已提交
3993 3994

				_cameraLight.matrixWorldInverse.getInverse( _cameraLight.matrixWorld );
3995

3996 3997
				// compute shadow matrix

3998 3999 4000 4001
				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 );
4002

4003 4004
				shadowMatrix.multiplySelf( _cameraLight.projectionMatrix );
				shadowMatrix.multiplySelf( _cameraLight.matrixWorldInverse );
4005 4006 4007 4008 4009 4010 4011 4012 4013

				// render shadow map

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

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

4014
				setRenderTarget( shadowMap );
4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038

				// 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 已提交
4039
						if ( ! ( object instanceof THREE.Mesh ) || ! ( object.frustumCulled ) || isInFrustum( object ) ) {
4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076

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

4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089
						if ( object.customDepthMaterial ) {

							material =  object.customDepthMaterial;

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

							material =  _depthMaterialMorph;

						} else {

							material = _depthMaterial;

						}
4090 4091 4092 4093 4094 4095 4096 4097

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

					}

				}


4098
				for ( o = 0; o < oil; o ++ ) {
4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110

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

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

						if( object.matrixAutoUpdate ) {

							object.matrixWorld.flattenToArray( object._objectMatrixArray );

						}

M
Mr.doob 已提交
4111 4112
						_currentGeometryGroupHash = -1;

4113 4114 4115 4116 4117
						setupMatrices( object, _cameraLight, false );

						setObjectFaces( object );

						program = setProgram( _cameraLight, lights, fog, _depthMaterial, object );
M
Mr.doob 已提交
4118 4119 4120 4121 4122 4123 4124 4125 4126 4127

						if ( object.immediateRenderCallback ) {

							object.immediateRenderCallback( program, _gl, _frustum );

						} else {

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

						}
4128 4129 4130 4131 4132 4133 4134

					}

				}

				//_gl.cullFace( _gl.BACK );

4135 4136
				j ++;

4137 4138 4139 4140 4141 4142
			}

		}

	};

M
Mr.doob 已提交
4143
	this.clearTarget = function ( renderTarget, color, depth, stencil ) {
4144 4145

		setRenderTarget( renderTarget );
M
Mr.doob 已提交
4146
		this.clear( color, depth, stencil );
4147 4148 4149

	};

4150 4151 4152 4153 4154 4155
	this.updateShadowMap = function ( scene, camera ) {

		renderShadowMap( scene, camera );

	};

4156
	this.render = function( scene, camera, renderTarget, forceClear ) {
4157

4158
		var i, program, material,
4159
			o, ol, oil, webglObject, object, buffer,
4160
			lights = scene.lights,
N
Nicholas Kinsey 已提交
4161
			fog = scene.fog;
4162

M
Mr.doob 已提交
4163 4164
		_currentMaterialId = -1;

4165 4166 4167
		if ( this.autoUpdateObjects ) this.initWebGLObjects( scene );

		if ( this.shadowMapEnabled && this.shadowMapAutoUpdate ) renderShadowMap( scene, camera );
4168

M
Mr.doob 已提交
4169 4170 4171
		_this.info.render.calls = 0;
		_this.info.render.vertices = 0;
		_this.info.render.faces = 0;
4172

M
Mr.doob 已提交
4173 4174 4175 4176 4177 4178
		if ( camera.parent === undefined ) {

			console.warn( 'DEPRECATED: Camera hasn\'t been added to a Scene. Adding it...' );
			scene.add( camera );

		}
4179

M
Mr.doob 已提交
4180
		if ( this.autoUpdateScene ) scene.updateMatrixWorld();
A
alteredq 已提交
4181 4182

		camera.matrixWorldInverse.getInverse( camera.matrixWorld );
M
Mr.doob 已提交
4183
		camera.matrixWorldInverse.flattenToArray( _viewMatrixArray );
4184
		camera.projectionMatrix.flattenToArray( _projectionMatrixArray );
M
Mr.doob 已提交
4185

M
Mr.doob 已提交
4186
		_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
M
Mr.doob 已提交
4187
		computeFrustum( _projScreenMatrix );
4188

M
Mr.doob 已提交
4189
		setRenderTarget( renderTarget );
M
Mr.doob 已提交
4190

M
Mr.doob 已提交
4191
		if ( this.autoClear || forceClear ) {
M
Mr.doob 已提交
4192

M
Mr.doob 已提交
4193
			this.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil );
M
Mr.doob 已提交
4194

4195 4196
		}

4197
		// set matrices
4198

4199
		ol = scene.__webglObjects.length;
4200

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

4203 4204
			webglObject = scene.__webglObjects[ o ];
			object = webglObject.object;
M
Mr.doob 已提交
4205

4206
			if ( object.visible ) {
4207

A
alteredq 已提交
4208
				if ( ! ( object instanceof THREE.Mesh ) || ! ( object.frustumCulled ) || isInFrustum( object ) ) {
4209

4210
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
4211

4212
					setupMatrices( object, camera, true );
4213

4214
					unrollBufferMaterial( webglObject );
4215

4216
					webglObject.render = true;
4217

4218
					if ( this.sortObjects ) {
4219

4220
						if ( object.renderDepth ) {
M
Mr.doob 已提交
4221

4222
							webglObject.z = object.renderDepth;
M
Mr.doob 已提交
4223

4224
						} else {
M
Mr.doob 已提交
4225

4226 4227
							_vector3.copy( object.position );
							_projScreenMatrix.multiplyVector3( _vector3 );
M
Mr.doob 已提交
4228

4229
							webglObject.z = _vector3.z;
M
Mr.doob 已提交
4230

4231
						}
4232

4233
					}
4234

4235
				} else {
4236

4237
					webglObject.render = false;
4238

4239
				}
4240

4241
			} else {
4242

4243
				webglObject.render = false;
4244

4245
			}
4246

4247
		}
4248

4249
		if ( this.sortObjects ) {
4250

4251
			scene.__webglObjects.sort( painterSort );
4252

4253
		}
4254

4255
		oil = scene.__webglObjectsImmediate.length;
4256

4257
		for ( o = 0; o < oil; o ++ ) {
4258

4259 4260
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
4261

4262
			if ( object.visible ) {
4263 4264 4265

				if( object.matrixAutoUpdate ) {

4266
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
4267

A
alteredq 已提交
4268
				}
4269

4270
				setupMatrices( object, camera, true );
4271

4272
				unrollImmediateBufferMaterial( webglObject );
4273

4274
			}
4275

4276
		}
A
alteredq 已提交
4277

M
Mr.doob 已提交
4278
		if ( scene.overrideMaterial ) {
4279

M
Mr.doob 已提交
4280 4281
			setDepthTest( scene.overrideMaterial.depthTest );
			setBlending( scene.overrideMaterial.blending );
4282

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

M
Mr.doob 已提交
4285 4286 4287
				webglObject = scene.__webglObjects[ o ];

				if ( webglObject.render ) {
4288

M
Mr.doob 已提交
4289 4290
					object = webglObject.object;
					buffer = webglObject.buffer;
4291

M
Mr.doob 已提交
4292 4293 4294 4295 4296 4297 4298 4299
					setObjectFaces( object );

					renderBuffer( camera, lights, fog, scene.overrideMaterial, buffer, object );

				}

			}

4300
			for ( o = 0; o < oil; o ++ ) {
M
Mr.doob 已提交
4301 4302

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

M
Mr.doob 已提交
4305 4306
				if ( object.visible ) {

M
Mr.doob 已提交
4307 4308
					_currentGeometryGroupHash = -1;

M
Mr.doob 已提交
4309 4310 4311
					setObjectFaces( object );

					program = setProgram( camera, lights, fog, scene.overrideMaterial, object );
M
Mr.doob 已提交
4312 4313 4314 4315 4316 4317 4318 4319 4320 4321

					if ( object.immediateRenderCallback ) {

						object.immediateRenderCallback( program, _gl, _frustum );

					} else {

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

					}
M
Mr.doob 已提交
4322 4323 4324 4325 4326 4327 4328 4329

				}

			}

		} else {

			// opaque pass
4330
			// (front-to-back order)
M
Mr.doob 已提交
4331 4332 4333

			setBlending( THREE.NormalBlending );

4334
			for ( o = ol - 1; o >= 0; o -- ) {
M
Mr.doob 已提交
4335 4336 4337 4338 4339 4340 4341

				webglObject = scene.__webglObjects[ o ];

				if ( webglObject.render ) {

					object = webglObject.object;
					buffer = webglObject.buffer;
4342
					material = webglObject.opaque;
4343

4344
					if ( ! material ) continue;
4345

4346
					setObjectFaces( object );
4347

4348 4349 4350 4351
					setDepthTest( material.depthTest );
					setDepthWrite( material.depthWrite );
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
					renderBuffer( camera, lights, fog, material, buffer, object );
4352

4353
				}
4354 4355 4356

			}

M
Mr.doob 已提交
4357
			// opaque pass (immediate simulator)
4358

4359
			for ( o = 0; o < oil; o ++ ) {
4360

M
Mr.doob 已提交
4361 4362
				webglObject = scene.__webglObjectsImmediate[ o ];
				object = webglObject.object;
4363

M
Mr.doob 已提交
4364
				if ( object.visible ) {
4365

M
Mr.doob 已提交
4366 4367
					_currentGeometryGroupHash = -1;

4368
					material = webglObject.opaque;
4369

4370
					if ( ! material ) continue;
4371

4372
					setObjectFaces( object );
4373

4374 4375 4376
					setDepthTest( material.depthTest );
					setDepthWrite( material.depthWrite );
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
M
Mr.doob 已提交
4377

4378
					program = setProgram( camera, lights, fog, material, object );
M
Mr.doob 已提交
4379

4380
					if ( object.immediateRenderCallback ) {
M
Mr.doob 已提交
4381

4382
						object.immediateRenderCallback( program, _gl, _frustum );
M
Mr.doob 已提交
4383

4384
					} else {
M
Mr.doob 已提交
4385

4386
						object.render( function( object ) { renderBufferImmediate( object, program, material.shading ); } );
4387

M
Mr.doob 已提交
4388
					}
4389

4390
				}
4391

A
alteredq 已提交
4392
			}
4393

M
Mr.doob 已提交
4394
			// transparent pass
4395
			// (back-to-front order)
A
alteredq 已提交
4396

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

M
Mr.doob 已提交
4399
				webglObject = scene.__webglObjects[ o ];
4400

M
Mr.doob 已提交
4401
				if ( webglObject.render ) {
4402

M
Mr.doob 已提交
4403 4404
					object = webglObject.object;
					buffer = webglObject.buffer;
4405
					material = webglObject.transparent;
4406

4407
					if ( ! material ) continue;
4408

4409
					setObjectFaces( object );
4410

4411 4412 4413 4414
					setBlending( material.blending );
					setDepthTest( material.depthTest );
					setDepthWrite( material.depthWrite );
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
4415

4416
					renderBuffer( camera, lights, fog, material, buffer, object );
4417

4418
				}
4419

4420
			}
M
Mr.doob 已提交
4421

M
Mr.doob 已提交
4422
			// transparent pass (immediate simulator)
M
Mr.doob 已提交
4423

4424
			for ( o = 0; o < oil; o ++ ) {
4425

M
Mr.doob 已提交
4426 4427
				webglObject = scene.__webglObjectsImmediate[ o ];
				object = webglObject.object;
4428

M
Mr.doob 已提交
4429
				if ( object.visible ) {
4430

M
Mr.doob 已提交
4431 4432
					_currentGeometryGroupHash = -1;

4433
					material = webglObject.transparent;
4434

4435
					if ( ! material ) continue;
4436

4437
					setObjectFaces( object );
4438

4439 4440 4441 4442
					setBlending( material.blending );
					setDepthTest( material.depthTest );
					setDepthWrite( material.depthWrite );
					setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
M
Mr.doob 已提交
4443

4444
					program = setProgram( camera, lights, fog, material, object );
M
Mr.doob 已提交
4445

4446
					if ( object.immediateRenderCallback ) {
M
Mr.doob 已提交
4447

4448
						object.immediateRenderCallback( program, _gl, _frustum );
M
Mr.doob 已提交
4449

4450
					} else {
M
Mr.doob 已提交
4451

4452
						object.render( function( object ) { renderBufferImmediate( object, program, material.shading ); } );
4453

M
Mr.doob 已提交
4454
					}
4455

4456
				}
4457

4458
			}
4459

4460
		}
4461

M
Mikael Emtinger 已提交
4462
		// render 2d
4463

M
Mr.doob 已提交
4464
		if ( scene.__webglSprites.length ) {
4465

4466
			renderSprites( scene, camera );
4467

M
Mikael Emtinger 已提交
4468 4469
		}

M
Mikael Emtinger 已提交
4470 4471 4472 4473 4474 4475 4476 4477
		// Generate mipmap if we're using any kind of mipmap filtering

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

			updateRenderTargetMipmap( renderTarget );

		}

4478
		//_gl.finish();
4479

M
Mikael Emtinger 已提交
4480 4481
	};

4482 4483
	/*
	 * Render sprites
M
Mr.doob 已提交
4484
	 *
4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499
	 */

	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
4500

4501 4502
		_gl.useProgram( _sprite.program );
		_currentProgram = _sprite.program;
4503
		_oldBlending = -1;
M
Mr.doob 已提交
4504 4505
		_oldDepthTest = -1;
		_currentGeometryGroupHash = -1;
4506

M
Mr.doob 已提交
4507
		if ( !_spriteAttributesEnabled ) {
4508

M
Mr.doob 已提交
4509 4510
			_gl.enableVertexAttribArray( _sprite.attributes.position );
			_gl.enableVertexAttribArray( _sprite.attributes.uv );
4511

M
Mr.doob 已提交
4512 4513 4514
			_spriteAttributesEnabled = true;

		}
4515

4516
		_gl.disable( _gl.CULL_FACE );
4517
		_gl.enable( _gl.BLEND );
4518
		_gl.depthMask( true );
4519 4520 4521 4522 4523 4524

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

4526 4527 4528 4529
		_gl.uniformMatrix4fv( uniforms.projectionMatrix, false, _projectionMatrixArray );

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

4531
		// update positions and sort
4532

M
Mr.doob 已提交
4533
		for( o = 0, ol = scene.__webglSprites.length; o < ol; o ++ ) {
4534

4535
			object = scene.__webglSprites[ o ];
4536

4537
			if ( !object.visible || object.opacity === 0 ) continue;
M
Mr.doob 已提交
4538

4539
			if( !object.useScreenCoordinates ) {
4540

4541 4542
				object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
				object.z = -object._modelViewMatrix.n34;
4543

4544
			} else {
4545

4546
				object.z = -object.position.z;
4547

4548
			}
4549

4550 4551 4552
		}

		scene.__webglSprites.sort( painterSort );
4553

M
Mr.doob 已提交
4554
		// render all sprites
4555

M
Mr.doob 已提交
4556
		for ( o = 0, ol = scene.__webglSprites.length; o < ol; o ++ ) {
4557 4558 4559

			object = scene.__webglSprites[ o ];

4560
			if ( !object.visible || object.opacity === 0 ) continue;
4561

M
Mr.doob 已提交
4562
			if ( object.map && object.map.image && object.map.image.width ) {
4563

M
Mr.doob 已提交
4564
				if ( object.useScreenCoordinates ) {
4565

M
Mr.doob 已提交
4566 4567 4568 4569
					_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 )));
4570

M
Mr.doob 已提交
4571
				} else {
4572

M
Mr.doob 已提交
4573 4574 4575
					_gl.uniform1i( uniforms.useScreenCoordinates, 0 );
					_gl.uniform1i( uniforms.affectedByDistance, object.affectedByDistance ? 1 : 0 );
					_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray );
4576

M
Mr.doob 已提交
4577
				}
4578

M
Mr.doob 已提交
4579
				size = object.map.image.width / ( object.scaleByViewport ? _viewportHeight : 1 );
4580

M
Mr.doob 已提交
4581 4582
				scale[ 0 ] = size * invAspect * object.scale.x;
				scale[ 1 ] = size * object.scale.y;
4583

M
Mr.doob 已提交
4584 4585 4586
				_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 );
4587

M
Mr.doob 已提交
4588 4589
				_gl.uniform1f( uniforms.opacity, object.opacity );
				_gl.uniform3f( uniforms.color, object.color.r, object.color.g, object.color.b );
4590

M
Mr.doob 已提交
4591 4592
				_gl.uniform1f( uniforms.rotation, object.rotation );
				_gl.uniform2fv( uniforms.scale, scale );
4593

M
Mr.doob 已提交
4594
				if ( object.mergeWith3D && !mergeWith3D ) {
4595

M
Mr.doob 已提交
4596 4597
					_gl.enable( _gl.DEPTH_TEST );
					mergeWith3D = true;
4598

M
Mr.doob 已提交
4599
				} else if ( !object.mergeWith3D && mergeWith3D ) {
4600

M
Mr.doob 已提交
4601 4602
					_gl.disable( _gl.DEPTH_TEST );
					mergeWith3D = false;
4603

4604
				}
4605

M
Mr.doob 已提交
4606 4607
				setBlending( object.blending );
				setTexture( object.map, 0 );
4608

M
Mr.doob 已提交
4609
				_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
4610

4611
			}
4612

4613 4614 4615 4616 4617 4618 4619
		}


		// restore gl

		_gl.enable( _gl.CULL_FACE );
		_gl.enable( _gl.DEPTH_TEST );
M
Mr.doob 已提交
4620
		_gl.depthMask( _oldDepthWrite );
4621 4622 4623

	}

4624
	function setupMatrices( object, camera, computeNormalMatrix ) {
4625

4626
		object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
4627 4628 4629 4630 4631 4632

		if ( computeNormalMatrix ) {

			THREE.Matrix4.makeInvert3x3( object._modelViewMatrix ).transposeIntoArray( object._normalMatrixArray );

		}
4633

M
Mr.doob 已提交
4634
	}
4635

A
alteredq 已提交
4636
	this.initWebGLObjects = function ( scene ) {
4637

4638
		if ( !scene.__webglObjects ) {
4639

4640 4641
			scene.__webglObjects = [];
			scene.__webglObjectsImmediate = [];
M
Mikael Emtinger 已提交
4642
			scene.__webglSprites = [];
4643

4644 4645
		}

M
Mr.doob 已提交
4646
		while ( scene.__objectsAdded.length ) {
4647

M
Mr.doob 已提交
4648 4649
			addObject( scene.__objectsAdded[ 0 ], scene );
			scene.__objectsAdded.splice( 0, 1 );
4650 4651 4652

		}

M
Mr.doob 已提交
4653
		while ( scene.__objectsRemoved.length ) {
4654

M
Mr.doob 已提交
4655 4656
			removeObject( scene.__objectsRemoved[ 0 ], scene );
			scene.__objectsRemoved.splice( 0, 1 );
4657 4658

		}
4659

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

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

4664
			updateObject( scene.__webglObjects[ o ].object );
A
alteredq 已提交
4665 4666

		}
4667

4668
	};
4669

M
Mr.doob 已提交
4670
	function addObject( object, scene ) {
4671

M
Mr.doob 已提交
4672
		var g, geometry, geometryGroup;
4673

M
Mr.doob 已提交
4674
		if ( ! object.__webglInit ) {
4675

M
Mr.doob 已提交
4676
			object.__webglInit = true;
M
Mr.doob 已提交
4677

M
Mr.doob 已提交
4678
			object._modelViewMatrix = new THREE.Matrix4();
A
alteredq 已提交
4679

M
Mr.doob 已提交
4680 4681 4682
			object._normalMatrixArray = new Float32Array( 9 );
			object._modelViewMatrixArray = new Float32Array( 16 );
			object._objectMatrixArray = new Float32Array( 16 );
4683

M
Mr.doob 已提交
4684
			object.matrixWorld.flattenToArray( object._objectMatrixArray );
4685

M
Mr.doob 已提交
4686
			if ( object instanceof THREE.Mesh ) {
4687

M
Mr.doob 已提交
4688
				geometry = object.geometry;
4689

4690
				if ( geometry.geometryGroups === undefined ) {
A
alteredq 已提交
4691

M
Mr.doob 已提交
4692
					sortFacesByMaterial( geometry );
A
alteredq 已提交
4693

M
Mr.doob 已提交
4694
				}
M
Mr.doob 已提交
4695

M
Mr.doob 已提交
4696
				// create separate VBOs per geometry chunk
M
Mr.doob 已提交
4697

M
Mr.doob 已提交
4698
				for ( g in geometry.geometryGroups ) {
M
Mr.doob 已提交
4699

M
Mr.doob 已提交
4700
					geometryGroup = geometry.geometryGroups[ g ];
A
alteredq 已提交
4701

M
Mr.doob 已提交
4702
					// initialise VBO on the first access
M
Mr.doob 已提交
4703

M
Mr.doob 已提交
4704
					if ( ! geometryGroup.__webglVertexBuffer ) {
4705

M
Mr.doob 已提交
4706 4707
						createMeshBuffers( geometryGroup );
						initMeshBuffers( geometryGroup, object );
M
Mr.doob 已提交
4708

M
Mr.doob 已提交
4709 4710 4711 4712 4713 4714 4715
						geometry.__dirtyVertices = true;
						geometry.__dirtyMorphTargets = true;
						geometry.__dirtyElements = true;
						geometry.__dirtyUvs = true;
						geometry.__dirtyNormals = true;
						geometry.__dirtyTangents = true;
						geometry.__dirtyColors = true;
A
alteredq 已提交
4716

M
Mr.doob 已提交
4717
					}
4718

M
Mr.doob 已提交
4719
				}
A
alteredq 已提交
4720

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

M
Mr.doob 已提交
4723
				geometry = object.geometry;
A
alteredq 已提交
4724

M
Mr.doob 已提交
4725
				if( ! geometry.__webglVertexBuffer ) {
A
alteredq 已提交
4726

M
Mr.doob 已提交
4727 4728
					createRibbonBuffers( geometry );
					initRibbonBuffers( geometry );
M
Mr.doob 已提交
4729

M
Mr.doob 已提交
4730 4731
					geometry.__dirtyVertices = true;
					geometry.__dirtyColors = true;
4732

M
Mr.doob 已提交
4733
				}
M
Mr.doob 已提交
4734

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

M
Mr.doob 已提交
4737
				geometry = object.geometry;
M
Mr.doob 已提交
4738

M
Mr.doob 已提交
4739
				if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
4740

M
Mr.doob 已提交
4741
					createLineBuffers( geometry );
A
alteredq 已提交
4742
					initLineBuffers( geometry, object );
A
alteredq 已提交
4743

M
Mr.doob 已提交
4744 4745
					geometry.__dirtyVertices = true;
					geometry.__dirtyColors = true;
A
alteredq 已提交
4746

M
Mr.doob 已提交
4747
				}
A
alteredq 已提交
4748

M
Mr.doob 已提交
4749
			} else if ( object instanceof THREE.ParticleSystem ) {
A
alteredq 已提交
4750

M
Mr.doob 已提交
4751
				geometry = object.geometry;
4752

M
Mr.doob 已提交
4753
				if ( ! geometry.__webglVertexBuffer ) {
4754

M
Mr.doob 已提交
4755 4756
					createParticleBuffers( geometry );
					initParticleBuffers( geometry, object );
M
Mr.doob 已提交
4757

M
Mr.doob 已提交
4758 4759
					geometry.__dirtyVertices = true;
					geometry.__dirtyColors = true;
M
Mr.doob 已提交
4760

M
Mr.doob 已提交
4761
				}
M
Mr.doob 已提交
4762

M
Mr.doob 已提交
4763
			}
M
Mr.doob 已提交
4764

M
Mr.doob 已提交
4765
		}
M
Mr.doob 已提交
4766

M
Mr.doob 已提交
4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785
		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;
4786
				addBuffer( scene.__webglObjects, geometry, object );
M
Mr.doob 已提交
4787

M
Mr.doob 已提交
4788
			} else if ( THREE.MarchingCubes !== undefined && object instanceof THREE.MarchingCubes || object.immediateRenderCallback ) {
A
alteredq 已提交
4789

4790
				addBufferImmediate( scene.__webglObjectsImmediate, object );
A
alteredq 已提交
4791

4792
			} else if ( object instanceof THREE.Sprite ) {
4793

4794
				scene.__webglSprites.push( object );
4795

4796
			}
4797

M
Mr.doob 已提交
4798
			object.__webglActive = true;
4799 4800

		}
A
alteredq 已提交
4801 4802 4803

	};

4804
	function areCustomAttributesDirty( material ) {
4805

4806
		for ( var a in material.attributes ) {
4807

4808
			if ( material.attributes[ a ].needsUpdate ) return true;
4809 4810 4811 4812 4813 4814 4815

		}

		return false;

	};

4816
	function clearCustomAttributes( material ) {
4817

4818
		for ( var a in material.attributes ) {
4819

4820
			material.attributes[ a ].needsUpdate = false;
4821 4822 4823 4824 4825

		}

	};

4826
	function updateObject( object ) {
A
alteredq 已提交
4827

4828 4829
		var geometry = object.geometry,
			geometryGroup, customAttributesDirty, material;
A
alteredq 已提交
4830 4831 4832 4833 4834

		if ( object instanceof THREE.Mesh ) {

			// check all geometry groups

4835
			for( var i = 0, il = geometry.geometryGroupsList.length; i < il; i ++ ) {
A
alteredq 已提交
4836

4837
				geometryGroup = geometry.geometryGroupsList[ i ];
A
alteredq 已提交
4838

4839 4840 4841
				material = getBufferMaterial( object, geometryGroup );

				customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
4842

4843
				if ( geometry.__dirtyVertices || geometry.__dirtyMorphTargets || geometry.__dirtyElements ||
4844
					 geometry.__dirtyUvs || geometry.__dirtyNormals ||
4845
					 geometry.__dirtyColors || geometry.__dirtyTangents || customAttributesDirty ) {
A
alteredq 已提交
4846

4847
					setMeshBuffers( geometryGroup, object, _gl.DYNAMIC_DRAW, !geometry.dynamic );
A
alteredq 已提交
4848 4849 4850 4851 4852

				}

			}

4853
			geometry.__dirtyVertices = false;
4854
			geometry.__dirtyMorphTargets = false;
A
alteredq 已提交
4855 4856 4857
			geometry.__dirtyElements = false;
			geometry.__dirtyUvs = false;
			geometry.__dirtyNormals = false;
4858
			geometry.__dirtyColors = false;
4859
			geometry.__dirtyTangents = false;
M
Mr.doob 已提交
4860

4861
			material.attributes && clearCustomAttributes( material );
4862

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

4865
			if ( geometry.__dirtyVertices || geometry.__dirtyColors ) {
M
Mr.doob 已提交
4866

A
alteredq 已提交
4867
				setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
4868

A
alteredq 已提交
4869 4870 4871 4872 4873 4874 4875
			}

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

		} else if ( object instanceof THREE.Line ) {

A
alteredq 已提交
4876 4877 4878 4879 4880
			material = getBufferMaterial( object, geometryGroup );

			customAttributesDirty = material.attributes && areCustomAttributesDirty( material );

			if ( geometry.__dirtyVertices ||  geometry.__dirtyColors || customAttributesDirty ) {
A
alteredq 已提交
4881 4882

				setLineBuffers( geometry, _gl.DYNAMIC_DRAW );
4883

4884
			}
4885

A
alteredq 已提交
4886 4887 4888
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;

A
alteredq 已提交
4889 4890
			material.attributes && clearCustomAttributes( material );

A
alteredq 已提交
4891 4892
		} else if ( object instanceof THREE.ParticleSystem ) {

4893
			material = getBufferMaterial( object, geometryGroup );
A
alteredq 已提交
4894

4895
			customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
4896

4897
			if ( geometry.__dirtyVertices || geometry.__dirtyColors || object.sortParticles || customAttributesDirty ) {
M
Mr.doob 已提交
4898

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

4901
			}
M
Mr.doob 已提交
4902

4903 4904
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
M
Mr.doob 已提交
4905

4906
			material.attributes && clearCustomAttributes( material );
4907

M
Mr.doob 已提交
4908
		}
4909

4910
	};
4911

4912
	function removeInstances( objlist, object ) {
M
Mr.doob 已提交
4913

4914
		for ( var o = objlist.length - 1; o >= 0; o -- ) {
M
Mr.doob 已提交
4915

4916
			if ( objlist[ o ].object === object ) {
4917

4918
				objlist.splice( o, 1 );
4919

4920
			}
4921

4922
		}
M
Mr.doob 已提交
4923

4924
	};
4925

4926 4927
	function removeInstancesDirect( objlist, object ) {

4928
		for ( var o = objlist.length - 1; o >= 0; o -- ) {
4929

4930
			if ( objlist[ o ] === object ) {
4931 4932 4933 4934 4935 4936 4937 4938 4939

				objlist.splice( o, 1 );

			}

		}

	};

4940
	function removeObject( object, scene ) {
4941

M
Mr.doob 已提交
4942
		if ( object instanceof THREE.Mesh  ||
4943 4944
			 object instanceof THREE.ParticleSystem ||
			 object instanceof THREE.Ribbon ||
4945
			 object instanceof THREE.Line ) {
4946

4947
			removeInstances( scene.__webglObjects, object );
4948

4949
		} else if ( object instanceof THREE.Sprite ) {
M
Mr.doob 已提交
4950

4951
			removeInstancesDirect( scene.__webglSprites, object );
M
Mr.doob 已提交
4952

M
Mr.doob 已提交
4953
		} else if ( object instanceof THREE.MarchingCubes || object.immediateRenderCallback ) {
4954

4955 4956 4957
			removeInstances( scene.__webglObjectsImmediate, object );

		}
M
Mr.doob 已提交
4958

M
Mr.doob 已提交
4959 4960
		object.__webglActive = false;

M
Mr.doob 已提交
4961 4962
	};

4963
	function sortFacesByMaterial( geometry ) {
4964

4965 4966 4967
		var f, fl, face, materialIndex, vertices,
			materialHash, groupHash,
			hash_map = {};
4968

4969
		var numMorphTargets = geometry.morphTargets.length;
4970 4971 4972

		geometry.geometryGroups = {};

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

			face = geometry.faces[ f ];
4976
			materialIndex = face.materialIndex;
4977

4978
			materialHash = ( materialIndex !== undefined ) ? materialIndex : -1;
4979

4980
			if ( hash_map[ materialHash ] === undefined ) {
4981

4982
				hash_map[ materialHash ] = { 'hash': materialHash, 'counter': 0 };
4983 4984 4985

			}

4986
			groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
4987

4988
			if ( geometry.geometryGroups[ groupHash ] === undefined ) {
4989

4990
				geometry.geometryGroups[ groupHash ] = { 'faces3': [], 'faces4': [], 'materialIndex': materialIndex, 'vertices': 0, 'numMorphTargets': numMorphTargets };
4991 4992 4993 4994 4995

			}

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

4996
			if ( geometry.geometryGroups[ groupHash ].vertices + vertices > 65535 ) {
4997

4998 4999
				hash_map[ materialHash ].counter += 1;
				groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
5000

5001
				if ( geometry.geometryGroups[ groupHash ] === undefined ) {
5002

5003
					geometry.geometryGroups[ groupHash ] = { 'faces3': [], 'faces4': [], 'materialIndex': materialIndex, 'vertices': 0, 'numMorphTargets': numMorphTargets };
5004 5005 5006 5007 5008

				}

			}

5009 5010 5011 5012 5013 5014 5015 5016 5017 5018
			if ( face instanceof THREE.Face3 ) {

				geometry.geometryGroups[ groupHash ].faces3.push( f );

			} else {

				geometry.geometryGroups[ groupHash ].faces4.push( f );

			}

5019
			geometry.geometryGroups[ groupHash ].vertices += vertices;
5020 5021 5022

		}

5023 5024 5025 5026
		geometry.geometryGroupsList = [];

		for ( var g in geometry.geometryGroups ) {

M
Mr.doob 已提交
5027 5028
			geometry.geometryGroups[ g ].id = _geometryGroupCounter ++;

5029 5030 5031 5032
			geometry.geometryGroupsList.push( geometry.geometryGroups[ g ] );

		}

5033 5034
	};

5035
	function addBuffer( objlist, buffer, object ) {
5036

5037 5038 5039 5040 5041 5042 5043 5044
		objlist.push(
			{
				buffer: buffer,
				object: object,
				opaque: null,
				transparent: null
			}
		);
M
Mr.doob 已提交
5045

5046
	};
5047

5048
	function addBufferImmediate( objlist, object ) {
5049

5050 5051 5052 5053 5054 5055 5056
		objlist.push(
			{
				object: object,
				opaque: null,
				transparent: null
			}
		);
5057

5058
	};
5059

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

5062
		if ( cullFace ) {
M
Mr.doob 已提交
5063

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

5066
				_gl.frontFace( _gl.CCW );
M
Mr.doob 已提交
5067

5068
			} else {
M
Mr.doob 已提交
5069

5070
				_gl.frontFace( _gl.CW );
M
Mr.doob 已提交
5071

5072
			}
M
Mr.doob 已提交
5073

5074
			if( cullFace === "back" ) {
M
Mr.doob 已提交
5075

5076
				_gl.cullFace( _gl.BACK );
M
Mr.doob 已提交
5077

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

5080
				_gl.cullFace( _gl.FRONT );
M
Mr.doob 已提交
5081

5082
			} else {
M
Mr.doob 已提交
5083

5084
				_gl.cullFace( _gl.FRONT_AND_BACK );
M
Mr.doob 已提交
5085

5086
			}
M
Mr.doob 已提交
5087

5088
			_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
5089

5090
		} else {
M
Mr.doob 已提交
5091

5092
			_gl.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
5093

5094 5095 5096
		}

	};
N
Nicolas Garcia Belmonte 已提交
5097

5098
	this.supportsVertexTextures = function () {
5099

A
alteredq 已提交
5100
		return _supportsVertexTextures;
5101

5102
	};
5103

5104
	function maxVertexTextures() {
5105

5106 5107 5108
		return _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );

	};
5109

5110
	function buildProgram( shaderID, fragmentShader, vertexShader, uniforms, attributes, parameters ) {
5111

5112
		var p, pl, program, code;
5113
		var chunks = [];
5114 5115 5116

		// Generate code

5117 5118 5119 5120 5121 5122 5123 5124 5125 5126
		if ( shaderID ) {

			chunks.push( shaderID );

		} else {

			chunks.push( fragmentShader );
			chunks.push( vertexShader );

		}
5127 5128 5129

		for ( p in parameters ) {

5130 5131
			chunks.push( p );
			chunks.push( parameters[ p ] );
5132 5133 5134

		}

5135 5136
		code = chunks.join();

5137 5138 5139 5140
		// Check if code has been already compiled

		for ( p = 0, pl = _programs.length; p < pl; p ++ ) {

5141
			if ( _programs[ p ].code === code ) {
5142 5143

				// console.log( "Code already compiled." /*: \n\n" + code*/ );
5144

5145 5146 5147 5148 5149
				return _programs[ p ].program;

			}

		}
5150

5151
		//console.log( "building new program " );
5152 5153 5154

		//

5155
		program = _gl.createProgram();
M
Mr.doob 已提交
5156

5157
		var prefix_vertex = [
M
Mr.doob 已提交
5158

A
alteredq 已提交
5159
			_supportsVertexTextures ? "#define VERTEX_TEXTURES" : "",
5160

5161 5162 5163 5164
			_this.gammaInput ? "#define GAMMA_INPUT" : "",
			_this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
			_this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",

5165 5166 5167
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

5168 5169
			"#define MAX_SHADOWS " + parameters.maxShadows,

5170 5171
			"#define MAX_BONES " + parameters.maxBones,

5172
			parameters.map ? "#define USE_MAP" : "",
5173 5174 5175
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
5176
			parameters.skinning ? "#define USE_SKINNING" : "",
5177
			parameters.morphTargets ? "#define USE_MORPHTARGETS" : "",
A
alteredq 已提交
5178
			parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",
5179

5180
			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
5181
			parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
5182

5183 5184
			parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",

M
Mr.doob 已提交
5185 5186 5187
			"uniform mat4 objectMatrix;",
			"uniform mat4 modelViewMatrix;",
			"uniform mat4 projectionMatrix;",
5188 5189
			"uniform mat4 viewMatrix;",
			"uniform mat3 normalMatrix;",
M
Mr.doob 已提交
5190
			"uniform vec3 cameraPosition;",
A
alteredq 已提交
5191 5192 5193

			"uniform mat4 cameraInverseMatrix;",

M
Mr.doob 已提交
5194 5195 5196
			"attribute vec3 position;",
			"attribute vec3 normal;",
			"attribute vec2 uv;",
5197
			"attribute vec2 uv2;",
5198

5199
			"#ifdef USE_COLOR",
5200

5201
				"attribute vec3 color;",
5202

5203 5204
			"#endif",

5205
			"#ifdef USE_MORPHTARGETS",
5206

5207 5208 5209 5210 5211 5212 5213 5214
				"attribute vec3 morphTarget0;",
				"attribute vec3 morphTarget1;",
				"attribute vec3 morphTarget2;",
				"attribute vec3 morphTarget3;",
				"attribute vec3 morphTarget4;",
				"attribute vec3 morphTarget5;",
				"attribute vec3 morphTarget6;",
				"attribute vec3 morphTarget7;",
5215

5216 5217 5218
			"#endif",

			"#ifdef USE_SKINNING",
5219

5220 5221 5222 5223
				"attribute vec4 skinVertexA;",
				"attribute vec4 skinVertexB;",
				"attribute vec4 skinIndex;",
				"attribute vec4 skinWeight;",
5224

5225
			"#endif",
5226

M
Mr.doob 已提交
5227
			""
A
alteredq 已提交
5228

M
Mr.doob 已提交
5229
		].join("\n");
5230

M
Mr.doob 已提交
5231 5232 5233 5234 5235 5236 5237 5238 5239
		var prefix_fragment = [

			"#ifdef GL_ES",
			"precision highp float;",
			"#endif",

			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

5240 5241
			"#define MAX_SHADOWS " + parameters.maxShadows,

5242 5243
			parameters.alphaTest ? "#define ALPHATEST " + parameters.alphaTest: "",

5244 5245 5246 5247
			_this.gammaInput ? "#define GAMMA_INPUT" : "",
			_this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
			_this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",

M
Mr.doob 已提交
5248 5249
			( parameters.useFog && parameters.fog ) ? "#define USE_FOG" : "",
			( parameters.useFog && parameters.fog instanceof THREE.FogExp2 ) ? "#define FOG_EXP2" : "",
M
Mr.doob 已提交
5250 5251 5252 5253 5254

			parameters.map ? "#define USE_MAP" : "",
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
5255

5256 5257 5258
			parameters.metal ? "#define METAL" : "",
			parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",

5259
			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
5260 5261 5262
			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 已提交
5263 5264 5265 5266 5267 5268 5269

			"uniform mat4 viewMatrix;",
			"uniform vec3 cameraPosition;",
			""

		].join("\n");

5270 5271
		_gl.attachShader( program, getShader( "fragment", prefix_fragment + fragmentShader ) );
		_gl.attachShader( program, getShader( "vertex", prefix_vertex + vertexShader ) );
M
Mr.doob 已提交
5272

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

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

5277
			console.error( "Could not initialise shader\n" + "VALIDATE_STATUS: " + _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) + ", gl error [" + _gl.getError() + "]" );
M
Mr.doob 已提交
5278

N
Nicolas Garcia Belmonte 已提交
5279
		}
5280

5281 5282
		//console.log( prefix_fragment + fragmentShader );
		//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
5283

M
Mr.doob 已提交
5284
		program.uniforms = {};
5285
		program.attributes = {};
M
Mr.doob 已提交
5286

5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304
		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 );
5305

5306 5307 5308 5309 5310 5311 5312 5313 5314
		// cache attributes locations

		identifiers = [

			"position", "normal", "uv", "uv2", "tangent", "color",
			"skinVertexA", "skinVertexB", "skinIndex", "skinWeight"

		];

5315
		for ( i = 0; i < parameters.maxMorphTargets; i ++ ) {
5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328

			identifiers.push( "morphTarget" + i );

		}

		for ( a in attributes ) {

			identifiers.push( a );

		}

		cacheAttributeLocations( program, identifiers );

M
Mr.doob 已提交
5329 5330
		program.id = _programs.length;

5331 5332
		_programs.push( { program: program, code: code } );

M
Mr.doob 已提交
5333 5334
		_this.info.memory.programs = _programs.length;

M
Mr.doob 已提交
5335
		return program;
M
Mr.doob 已提交
5336

M
Mr.doob 已提交
5337
	};
M
Mr.doob 已提交
5338

5339
	function loadUniformsSkinning( uniforms, object ) {
5340

M
Mr.doob 已提交
5341
		_gl.uniformMatrix4fv( uniforms.cameraInverseMatrix, false, _viewMatrixArray );
A
alteredq 已提交
5342
		_gl.uniformMatrix4fv( uniforms.boneGlobalMatrices, false, object.boneMatrices );
5343

5344
	};
5345

5346

5347
	function loadUniformsMatrices( uniforms, object ) {
5348

A
alteredq 已提交
5349
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray );
A
alteredq 已提交
5350 5351 5352 5353 5354 5355

		if ( uniforms.normalMatrix ) {

			_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrixArray );

		}
A
alteredq 已提交
5356 5357

	};
5358

5359
	function loadUniformsGeneric( program, uniforms ) {
M
Mr.doob 已提交
5360

M
Mr.doob 已提交
5361
		var uniform, value, type, location, texture, i, il, j, jl, offset;
M
Mr.doob 已提交
5362

M
Mr.doob 已提交
5363
		for( j = 0, jl = uniforms.length; j < jl; j ++ ) {
M
Mr.doob 已提交
5364

M
Mr.doob 已提交
5365
			location = program.uniforms[ uniforms[ j ][ 1 ] ];
5366
			if ( !location ) continue;
M
Mr.doob 已提交
5367

M
Mr.doob 已提交
5368
			uniform = uniforms[ j ][ 0 ];
M
Mr.doob 已提交
5369

5370 5371
			type = uniform.type;
			value = uniform.value;
M
Mr.doob 已提交
5372

5373 5374
			// single integer

5375
			if( type === "i" ) {
M
Mr.doob 已提交
5376

M
Mr.doob 已提交
5377
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
5378

5379 5380
			// single float

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

M
Mr.doob 已提交
5383
				_gl.uniform1f( location, value );
5384

5385 5386
			// single THREE.Vector2

5387
			} else if( type === "v2" ) {
5388 5389 5390 5391 5392

				_gl.uniform2f( location, value.x, value.y );

			// single THREE.Vector3

5393
			} else if( type === "v3" ) {
5394 5395 5396 5397 5398

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

			// single THREE.Vector4

5399
			} else if( type === "v4" ) {
5400 5401 5402 5403 5404

				_gl.uniform4f( location, value.x, value.y, value.z, value.w );

			// single THREE.Color

5405
			} else if( type === "c" ) {
5406 5407 5408 5409 5410

				_gl.uniform3f( location, value.r, value.g, value.b );

			// flat array of floats (JS or typed array)

5411
			} else if( type === "fv1" ) {
A
alteredq 已提交
5412 5413

				_gl.uniform1fv( location, value );
M
Mr.doob 已提交
5414

5415 5416
			// flat array of floats with 3 x N size (JS or typed array)

5417
			} else if( type === "fv" ) {
5418 5419 5420

				_gl.uniform3fv( location, value );

5421
			// array of THREE.Vector3
5422

5423
			} else if( type === "v3v" ) {
5424

5425
				if ( ! uniform._array ) {
5426

5427
					uniform._array = new Float32Array( 3 * value.length );
5428

5429
				}
5430

5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443
				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
5444

5445
			} else if( type === "m4" ) {
5446 5447 5448 5449 5450 5451 5452 5453 5454 5455

				if ( ! uniform._array ) {

					uniform._array = new Float32Array( 16 );

				}

				value.flattenToArray( uniform._array );
				_gl.uniformMatrix4fv( location, false, uniform._array );

5456 5457
			// array of THREE.Matrix4

5458
			} else if( type === "m4v" ) {
5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 5473

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

5474

5475
			// single THREE.Texture (2d or cube)
M
Mr.doob 已提交
5476

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

M
Mr.doob 已提交
5479
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
5480

5481
				texture = uniform.texture;
M
Mr.doob 已提交
5482

5483
				if ( !texture ) continue;
M
Mr.doob 已提交
5484

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

5487
					setCubeTexture( texture, value );
M
Mr.doob 已提交
5488

A
alteredq 已提交
5489 5490 5491 5492
				} else if ( texture instanceof THREE.WebGLRenderTargetCube ) {

					setCubeTextureDynamic( texture, value );

5493
				} else {
M
Mr.doob 已提交
5494

5495
					setTexture( texture, value );
M
Mr.doob 已提交
5496

5497
				}
M
Mr.doob 已提交
5498

5499 5500
			// array of THREE.Texture (2d)

5501
			} else if( type === "tv" ) {
5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 5523 5524 5525 5526

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

				}

5527
			}
M
Mr.doob 已提交
5528

5529
		}
M
Mr.doob 已提交
5530

5531
	};
M
Mr.doob 已提交
5532

5533
	function setBlending( blending ) {
A
alteredq 已提交
5534

5535
		if ( blending !== _oldBlending ) {
5536

A
alteredq 已提交
5537 5538 5539 5540 5541
			switch ( blending ) {

				case THREE.AdditiveBlending:

					_gl.blendEquation( _gl.FUNC_ADD );
5542
					_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE );
A
alteredq 已提交
5543 5544 5545 5546 5547

					break;

				case THREE.SubtractiveBlending:

5548 5549 5550 5551
					// TODO: Find blendFuncSeparate() combination

					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.ZERO, _gl.ONE_MINUS_SRC_COLOR );
A
alteredq 已提交
5552 5553 5554

					break;

5555 5556 5557
				case THREE.MultiplyBlending:

					// TODO: Find blendFuncSeparate() combination
A
alteredq 已提交
5558 5559

					_gl.blendEquation( _gl.FUNC_ADD );
5560
					_gl.blendFunc( _gl.ZERO, _gl.SRC_COLOR );
A
alteredq 已提交
5561 5562 5563 5564 5565

					break;

				default:

5566 5567
					_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 已提交
5568 5569

					break;
5570

A
alteredq 已提交
5571
			}
5572

A
alteredq 已提交
5573
			_oldBlending = blending;
5574

A
alteredq 已提交
5575 5576 5577
		}

	};
5578

5579
	function setTextureParameters( textureType, texture, image ) {
5580

5581
		if ( isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ) ) {
M
Mr.doob 已提交
5582

5583 5584
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
M
Mr.doob 已提交
5585

5586 5587
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
M
Mr.doob 已提交
5588

5589
			_gl.generateMipmap( textureType );
M
Mr.doob 已提交
5590

5591
		} else {
M
Mr.doob 已提交
5592

5593 5594
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
5595

5596 5597
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
M
Mr.doob 已提交
5598

5599
		}
M
Mr.doob 已提交
5600

5601
	};
5602

5603
	function setTexture( texture, slot ) {
5604

5605
		if ( texture.needsUpdate ) {
A
alteredq 已提交
5606

5607
			if ( ! texture.__webglInit ) {
M
Mr.doob 已提交
5608

5609
				texture.__webglInit = true;
5610
				texture.__webglTexture = _gl.createTexture();
A
alteredq 已提交
5611

M
Mr.doob 已提交
5612 5613
				_this.info.memory.textures ++;

5614
			}
M
Mr.doob 已提交
5615

5616
			_gl.activeTexture( _gl.TEXTURE0 + slot );
5617 5618
			_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );

5619
			if ( texture instanceof THREE.DataTexture ) {
5620 5621

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

A
alteredq 已提交
5623
			} else {
M
Mr.doob 已提交
5624

M
Mr.doob 已提交
5625
				_gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image );
M
Mr.doob 已提交
5626 5627 5628

			}

5629
			setTextureParameters( _gl.TEXTURE_2D, texture, texture.image );
M
Mr.doob 已提交
5630

A
alteredq 已提交
5631
			texture.needsUpdate = false;
5632

5633
		} else {
5634

5635 5636
			_gl.activeTexture( _gl.TEXTURE0 + slot );
			_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
5637 5638

		}
M
Mr.doob 已提交
5639

5640
	};
M
Mr.doob 已提交
5641

5642
	function setCubeTexture( texture, slot ) {
5643

5644
		if ( texture.image.length === 6 ) {
5645 5646 5647

			if ( texture.needsUpdate ) {

A
alteredq 已提交
5648
				if ( ! texture.image.__webglTextureCube ) {
5649 5650

					texture.image.__webglTextureCube = _gl.createTexture();
5651

A
alteredq 已提交
5652
				}
5653

A
alteredq 已提交
5654 5655
				_gl.activeTexture( _gl.TEXTURE0 + slot );
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
5656

A
alteredq 已提交
5657
				for ( var i = 0; i < 6; i ++ ) {
5658

A
alteredq 已提交
5659
					_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image[ i ] );
5660

A
alteredq 已提交
5661
				}
5662

A
alteredq 已提交
5663
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, texture.image[ 0 ] );
5664

A
alteredq 已提交
5665
				texture.needsUpdate = false;
5666

A
alteredq 已提交
5667
			} else {
5668

A
alteredq 已提交
5669 5670
				_gl.activeTexture( _gl.TEXTURE0 + slot );
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
5671

A
alteredq 已提交
5672
			}
5673

A
alteredq 已提交
5674
		}
5675

A
alteredq 已提交
5676
	};
5677

A
alteredq 已提交
5678
	function setCubeTextureDynamic( texture, slot ) {
5679

A
alteredq 已提交
5680 5681
		_gl.activeTexture( _gl.TEXTURE0 + slot );
		_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.__webglTexture );
5682 5683 5684

	};

5685
	function setupFrameBuffer( framebuffer, renderTarget, textureTarget ) {
5686

5687 5688
		_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
		_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureTarget, renderTarget.__webglTexture, 0 );
A
alteredq 已提交
5689

5690
	};
M
Mr.doob 已提交
5691

5692
	function setupRenderBuffer( renderbuffer, renderTarget  ) {
M
Mikael Emtinger 已提交
5693

5694
		_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );
5695

5696
		if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
M
Mr.doob 已提交
5697

5698 5699
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
A
alteredq 已提交
5700

5701 5702
		/* For some reason this is not working. Defaulting to RGBA4.
		} else if( ! renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
A
alteredq 已提交
5703

5704 5705 5706 5707
			_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 已提交
5708

5709 5710
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );
			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
A
alteredq 已提交
5711

5712
		} else {
A
alteredq 已提交
5713

5714
			_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );
A
alteredq 已提交
5715

5716
		}
A
alteredq 已提交
5717

5718
	};
A
alteredq 已提交
5719

5720
	function setRenderTarget( renderTarget ) {
A
alteredq 已提交
5721

5722
		var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
A
alteredq 已提交
5723

5724
		if ( renderTarget && ! renderTarget.__webglFramebuffer ) {
A
alteredq 已提交
5725

5726 5727
			if( renderTarget.depthBuffer === undefined ) renderTarget.depthBuffer = true;
			if( renderTarget.stencilBuffer === undefined ) renderTarget.stencilBuffer = true;
A
alteredq 已提交
5728

5729
			renderTarget.__webglTexture = _gl.createTexture();
A
alteredq 已提交
5730

5731
			// Setup texture, create render and frame buffers
5732

5733
			if ( isCube ) {
M
Mr.doob 已提交
5734

5735 5736
				renderTarget.__webglFramebuffer = [];
				renderTarget.__webglRenderbuffer = [];
M
Mikael Emtinger 已提交
5737

5738 5739
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, renderTarget.__webglTexture );
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget, renderTarget );
A
alteredq 已提交
5740

5741
				for ( var i = 0; i < 6; i ++ ) {
A
alteredq 已提交
5742

5743 5744
					renderTarget.__webglFramebuffer[ i ] = _gl.createFramebuffer();
					renderTarget.__webglRenderbuffer[ i ] = _gl.createRenderbuffer();
A
alteredq 已提交
5745

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

5748
					setupFrameBuffer( renderTarget.__webglFramebuffer[ i ], renderTarget, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
A
alteredq 已提交
5749

5750
					setupRenderBuffer( renderTarget.__webglRenderbuffer[ i ], renderTarget );
A
alteredq 已提交
5751

5752
				}
5753

5754
			} else {
5755

5756 5757
				renderTarget.__webglFramebuffer = _gl.createFramebuffer();
				renderTarget.__webglRenderbuffer = _gl.createRenderbuffer();
5758

5759 5760
				_gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
				setTextureParameters( _gl.TEXTURE_2D, renderTarget, renderTarget );
5761

5762
				_gl.texImage2D( _gl.TEXTURE_2D, 0, paramThreeToGL( renderTarget.format ), renderTarget.width, renderTarget.height, 0, paramThreeToGL( renderTarget.format ), paramThreeToGL( renderTarget.type ), null );
5763

5764
				setupFrameBuffer( renderTarget.__webglFramebuffer, renderTarget, _gl.TEXTURE_2D );
5765

5766
				_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderTarget.__webglRenderbuffer );
5767

5768
				setupRenderBuffer( renderTarget.__webglRenderbuffer, renderTarget );
5769

M
Mikael Emtinger 已提交
5770
			}
5771

5772
			// Release everything
M
Mr.doob 已提交
5773

A
alteredq 已提交
5774 5775 5776 5777 5778 5779 5780 5781 5782 5783
			if ( isCube ) {

				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );

			} else {

				_gl.bindTexture( _gl.TEXTURE_2D, null );

			}

5784 5785
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
M
Mr.doob 已提交
5786

5787 5788
		}

5789
		var framebuffer, width, height, vx, vy;
M
Mr.doob 已提交
5790

5791
		if ( renderTarget ) {
M
Mr.doob 已提交
5792

A
alteredq 已提交
5793 5794
			if ( isCube ) {

5795
				framebuffer = renderTarget.__webglFramebuffer[ renderTarget.activeCubeFace ];
A
alteredq 已提交
5796 5797 5798

			} else {

5799
				framebuffer = renderTarget.__webglFramebuffer;
A
alteredq 已提交
5800 5801 5802

			}

5803 5804
			width = renderTarget.width;
			height = renderTarget.height;
M
Mr.doob 已提交
5805

5806 5807 5808
			vx = 0;
			vy = 0;

5809
		} else {
M
Mr.doob 已提交
5810

5811
			framebuffer = null;
5812

5813 5814
			width = _viewportWidth;
			height = _viewportHeight;
5815

5816 5817
			vx = _viewportX;
			vy = _viewportY;
M
Mr.doob 已提交
5818

5819
		}
M
Mr.doob 已提交
5820

5821
		if ( framebuffer !== _currentFramebuffer ) {
M
Mr.doob 已提交
5822

5823
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
5824
			_gl.viewport( vx, vy, width, height );
M
Mr.doob 已提交
5825

5826
			_currentFramebuffer = framebuffer;
M
Mr.doob 已提交
5827

5828
		}
5829

5830
	};
M
Mr.doob 已提交
5831

5832
	function updateRenderTargetMipmap( renderTarget ) {
M
Mr.doob 已提交
5833

A
alteredq 已提交
5834 5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845 5846
		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 已提交
5847 5848

	};
5849

5850
	function cacheUniformLocations( program, identifiers ) {
M
Mr.doob 已提交
5851

M
Mr.doob 已提交
5852
		var i, l, id;
M
Mr.doob 已提交
5853

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

5856 5857
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
5858

M
Mr.doob 已提交
5859
		}
M
Mr.doob 已提交
5860

M
Mr.doob 已提交
5861
	};
M
Mr.doob 已提交
5862

5863
	function cacheAttributeLocations( program, identifiers ) {
5864

5865
		var i, l, id;
M
Mr.doob 已提交
5866

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

5869 5870
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
M
Mr.doob 已提交
5871

5872
		}
M
Mr.doob 已提交
5873

M
Mr.doob 已提交
5874
	};
M
Mr.doob 已提交
5875

5876
	function getShader( type, string ) {
N
Nicolas Garcia Belmonte 已提交
5877 5878 5879

		var shader;

5880
		if ( type === "fragment" ) {
N
Nicolas Garcia Belmonte 已提交
5881 5882 5883

			shader = _gl.createShader( _gl.FRAGMENT_SHADER );

5884
		} else if ( type === "vertex" ) {
N
Nicolas Garcia Belmonte 已提交
5885 5886 5887 5888 5889 5890 5891 5892 5893 5894

			shader = _gl.createShader( _gl.VERTEX_SHADER );

		}

		_gl.shaderSource( shader, string );
		_gl.compileShader( shader );

		if ( !_gl.getShaderParameter( shader, _gl.COMPILE_STATUS ) ) {

5895
			console.error( _gl.getShaderInfoLog( shader ) );
5896
			console.error( string );
N
Nicolas Garcia Belmonte 已提交
5897 5898 5899 5900 5901
			return null;

		}

		return shader;
M
Mr.doob 已提交
5902

5903
	};
N
Nicolas Garcia Belmonte 已提交
5904

5905
	// fallback filters for non-power-of-2 textures
5906

5907
	function filterFallback( f ) {
5908

5909 5910 5911 5912 5913 5914 5915 5916
		switch ( f ) {

			case THREE.NearestFilter:
			case THREE.NearestMipMapNearestFilter:
			case THREE.NearestMipMapLinearFilter: return _gl.NEAREST; break;

			case THREE.LinearFilter:
			case THREE.LinearMipMapNearestFilter:
M
Mr.doob 已提交
5917
			case THREE.LinearMipMapLinearFilter:
M
Mikael Emtinger 已提交
5918
			default:
5919

M
Mikael Emtinger 已提交
5920
				return _gl.LINEAR; break;
5921 5922

		}
5923

5924
	};
5925 5926

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

5928
		switch ( p ) {
M
Mr.doob 已提交
5929 5930 5931 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941

			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;

5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955
			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;

5956
		}
M
Mr.doob 已提交
5957

5958
		return 0;
M
Mr.doob 已提交
5959

5960 5961
	};

5962
	function isPowerOfTwo( value ) {
5963

5964
		return ( value & ( value - 1 ) ) === 0;
5965 5966 5967

	};

5968
	function materialNeedsSmoothNormals( material ) {
5969

5970
		return material && material.shading !== undefined && material.shading === THREE.SmoothShading;
5971 5972

	};
5973

5974
	function bufferGuessVertexColorType( material ) {
5975

5976
		if ( material.vertexColors ) {
5977

5978
			return material.vertexColors;
5979

5980
		}
5981

5982
		return false;
5983

5984 5985
	};

5986
	function bufferGuessNormalType( material ) {
5987

5988
		// only MeshBasicMaterial and MeshDepthMaterial don't need normals
5989

5990
		if ( ( material instanceof THREE.MeshBasicMaterial && !material.envMap ) || material instanceof THREE.MeshDepthMaterial ) {
5991

5992
			return false;
5993

5994
		}
5995

5996
		if ( materialNeedsSmoothNormals( material ) ) {
5997

5998
			return THREE.SmoothShading;
5999

6000
		} else {
6001

6002
			return THREE.FlatShading;
6003 6004

		}
6005

6006 6007
	};

6008
	function bufferGuessUVType( material ) {
6009

6010
		// material must use some texture to require uvs
6011

6012
		if ( material.map || material.lightMap || material instanceof THREE.ShaderMaterial ) {
6013

6014
			return true;
6015

6016
		}
6017

6018
		return false;
6019

6020
	};
6021

6022
	function allocateBones( object ) {
6023

6024 6025 6026 6027 6028 6029 6030
		// 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)
6031

6032
		var maxBones = 50;
6033

6034
		if ( object !== undefined && object instanceof THREE.SkinnedMesh ) {
6035

6036 6037 6038 6039 6040
			maxBones = object.bones.length;

		}

		return maxBones;
6041

6042
	};
6043

6044
	function allocateLights( lights ) {
6045

6046 6047
		var l, ll, light, dirLights, pointLights, maxDirLights, maxPointLights;
		dirLights = pointLights = maxDirLights = maxPointLights = 0;
6048

6049
		for ( l = 0, ll = lights.length; l < ll; l++ ) {
6050

6051
			light = lights[ l ];
6052

6053 6054 6055
			if ( light instanceof THREE.SpotLight ) dirLights ++; // hack, not a proper spotlight
			if ( light instanceof THREE.DirectionalLight ) dirLights ++;
			if ( light instanceof THREE.PointLight ) pointLights ++;
6056

6057
		}
6058

6059
		if ( ( pointLights + dirLights ) <= _maxLights ) {
6060

6061 6062
			maxDirLights = dirLights;
			maxPointLights = pointLights;
6063

6064
		} else {
6065

6066 6067
			maxDirLights = Math.ceil( _maxLights * dirLights / ( pointLights + dirLights ) );
			maxPointLights = _maxLights - maxDirLights;
6068 6069 6070

		}

6071
		return { 'directional' : maxDirLights, 'point' : maxPointLights };
6072 6073

	};
M
Mr.doob 已提交
6074

6075 6076
	function allocateShadows( lights ) {

M
Mr.doob 已提交
6077
		var l, ll, light, maxShadows = 0;
6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091

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

			light = lights[ l ];

			if ( light instanceof THREE.SpotLight && light.castShadow ) maxShadows ++;

		}

		return maxShadows;

	};


A
alteredq 已提交
6092
	/* DEBUG
6093
	function getGLParams() {
M
Mr.doob 已提交
6094

6095
		var params  = {
M
Mr.doob 已提交
6096

6097 6098
			'MAX_VARYING_VECTORS': _gl.getParameter( _gl.MAX_VARYING_VECTORS ),
			'MAX_VERTEX_ATTRIBS': _gl.getParameter( _gl.MAX_VERTEX_ATTRIBS ),
M
Mr.doob 已提交
6099

6100 6101 6102
			'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 已提交
6103

6104 6105 6106
			'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 已提交
6107

6108 6109
		return params;
	};
M
Mr.doob 已提交
6110

6111
	function dumpObject( obj ) {
M
Mr.doob 已提交
6112

6113 6114
		var p, str = "";
		for ( p in obj ) {
M
Mr.doob 已提交
6115

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

6118
		}
M
Mr.doob 已提交
6119

6120 6121
		return str;
	}
A
alteredq 已提交
6122
	*/
6123
};