WebGLRenderer.js 122.5 KB
Newer Older
N
Nicolas Garcia Belmonte 已提交
1 2 3
/**
 * @author supereggbert / http://www.paulbrunt.co.uk/
 * @author mrdoob / http://mrdoob.com/
4
 * @author alteredq / http://alteredqualia.com/
5
 * @author szimek / https://github.com/szimek/
N
Nicolas Garcia Belmonte 已提交
6 7
 */

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

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

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

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

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

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

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

A
alteredq 已提交
30
	_this = this,
31

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

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

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

45
	// camera matrices caches
46 47

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

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

60
	_vector3 = new THREE.Vector4(),
61

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

A
alteredq 已提交
64 65
	_lights = {

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

	},

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

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

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

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

86
	}
M
Mr.doob 已提交
87

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

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

95 96
	this.context = _gl;

M
Mikael Emtinger 已提交
97

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

160 161 162 163
	_lensFlare.vertexBuffer     = _gl.createBuffer();
	_lensFlare.elementBuffer    = _gl.createBuffer();
	_lensFlare.tempTexture      = _gl.createTexture();
	_lensFlare.occlusionTexture = _gl.createTexture();
M
Mr.doob 已提交
164

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

M
Mikael Emtinger 已提交
168 169 170 171 172 173 174 175 176 177
	_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _lensFlare.elementBuffer );
	_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, _lensFlare.faces, _gl.STATIC_DRAW );

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

178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
	_gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.occlusionTexture );
	_gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, 16, 16, 0, _gl.RGBA, _gl.UNSIGNED_BYTE, null );
	_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
	_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
	_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, _gl.NEAREST );
	_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, _gl.NEAREST );

	if( _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ) <= 0 ) {
		
		_lensFlare.hasVertexTexture = false;

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

		
	} else {

		_lensFlare.hasVertexTexture = true;
		
		_lensFlare.program = _gl.createProgram();
		_gl.attachShader( _lensFlare.program, getShader( "fragment", THREE.ShaderLib.lensFlareVertexTexture.fragmentShader ));
		_gl.attachShader( _lensFlare.program, getShader( "vertex",   THREE.ShaderLib.lensFlareVertexTexture.vertexShader   ));
		_gl.linkProgram( _lensFlare.program );
		
	}
M
Mikael Emtinger 已提交
205 206 207 208 209

	_lensFlare.attributes = {};
	_lensFlare.uniforms = {};
	_lensFlare.attributes.vertex       = _gl.getAttribLocation ( _lensFlare.program, "position" );
	_lensFlare.attributes.uv           = _gl.getAttribLocation ( _lensFlare.program, "UV" );
210
	_lensFlare.uniforms.renderType     = _gl.getUniformLocation( _lensFlare.program, "renderType" );
M
Mikael Emtinger 已提交
211
	_lensFlare.uniforms.map            = _gl.getUniformLocation( _lensFlare.program, "map" );
212
	_lensFlare.uniforms.occlusionMap   = _gl.getUniformLocation( _lensFlare.program, "occlusionMap" );
M
Mikael Emtinger 已提交
213 214 215 216 217
	_lensFlare.uniforms.opacity        = _gl.getUniformLocation( _lensFlare.program, "opacity" );
	_lensFlare.uniforms.scale          = _gl.getUniformLocation( _lensFlare.program, "scale" );
	_lensFlare.uniforms.rotation       = _gl.getUniformLocation( _lensFlare.program, "rotation" );
	_lensFlare.uniforms.screenPosition = _gl.getUniformLocation( _lensFlare.program, "screenPosition" );

M
Mikael Emtinger 已提交
218

M
Mikael Emtinger 已提交
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269
	// prepare sprites
	
	_sprite = {};

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

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

	i = 0;
	_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 );
	_gl.bufferData( _gl.ARRAY_BUFFER,  _sprite.vertices, _gl.STATIC_DRAW );

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


	_sprite.program = _gl.createProgram();
	_gl.attachShader( _sprite.program, getShader( "fragment", THREE.ShaderLib.sprite.fragmentShader ));
	_gl.attachShader( _sprite.program, getShader( "vertex",   THREE.ShaderLib.sprite.vertexShader   ));
	_gl.linkProgram( _sprite.program );

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






N
Nicolas Garcia Belmonte 已提交
270 271 272 273
	this.setSize = function ( width, height ) {

		_canvas.width = width;
		_canvas.height = height;
274

275 276 277
		this.setViewport( 0, 0, _canvas.width, _canvas.height );

	};
N
Nicolas Garcia Belmonte 已提交
278

279
	this.setViewport = function ( x, y, width, height ) {
280

281 282
		_viewportX = x;
		_viewportY = y;
283

284 285
		_viewportWidth = width;
		_viewportHeight = height;
286

287
		_gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight );
288

N
Nicolas Garcia Belmonte 已提交
289
	};
290

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

293
		_gl.scissor( x, y, width, height );
294

295
	};
296

297
	this.enableScissorTest = function ( enable ) {
298

299 300 301 302
		if ( enable )
			_gl.enable( _gl.SCISSOR_TEST );
		else
			_gl.disable( _gl.SCISSOR_TEST );
303

304
	};
305

306
	this.enableDepthBufferWrite = function ( enable ) {
307

308
		_currentDepthMask = enable;
309 310 311
		_gl.depthMask( enable );

	};
312

313
	this.setClearColorHex = function ( hex, alpha ) {
314

315 316
		var color = new THREE.Color( hex );
		_gl.clearColor( color.r, color.g, color.b, alpha );
317

318
	};
A
alteredq 已提交
319

320
	this.setClearColor = function ( color, alpha ) {
A
alteredq 已提交
321 322 323 324

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

	};
325

N
Nicolas Garcia Belmonte 已提交
326 327
	this.clear = function () {

M
Mikael Emtinger 已提交
328
		_gl.clear( _gl.COLOR_BUFFER_BIT | _gl.DEPTH_BUFFER_BIT | _gl.STENCIL_BUFFER_BIT );
N
Nicolas Garcia Belmonte 已提交
329 330 331

	};

M
Mikael Emtinger 已提交
332 333 334 335 336
	this.setStencilShadowDarkness = function( value ) {
		
		_stencilShadow.darkness = value;
	};

M
Mr.doob 已提交
337

A
alteredq 已提交
338
	function setupLights ( program, lights ) {
339

340
		var l, ll, light, r = 0, g = 0, b = 0,
341
		color, position, intensity, distance,
M
Mr.doob 已提交
342

343
		zlights = _lights,
M
Mr.doob 已提交
344

345
		dcolors = zlights.directional.colors,
346
		dpositions = zlights.directional.positions,
347

348
		pcolors = zlights.point.colors,
349
		ppositions = zlights.point.positions,
350
		pdistances = zlights.point.distances,
351

352 353
		dlength = 0,
		plength = 0,
354

355 356
		doffset = 0,
		poffset = 0;
M
Mr.doob 已提交
357

358
		for ( l = 0, ll = lights.length; l < ll; l++ ) {
359

360
			light = lights[ l ];
361
			color = light.color;
362

363 364
			position = light.position;
			intensity = light.intensity;
365
			distance = light.distance;
366 367 368

			if ( light instanceof THREE.AmbientLight ) {

369 370 371
				r += color.r;
				g += color.g;
				b += color.b;
M
Mr.doob 已提交
372

373
			} else if ( light instanceof THREE.DirectionalLight ) {
374

375
				doffset = dlength * 3;
376

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

381
				dpositions[ doffset ] = position.x;
382 383
				dpositions[ doffset + 1 ] = position.y;
				dpositions[ doffset + 2 ] = position.z;
384

385
				dlength += 1;
M
Mr.doob 已提交
386

387 388
			} else if( light instanceof THREE.PointLight ) {

389
				poffset = plength * 3;
390

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

395
				ppositions[ poffset ] = position.x;
396 397
				ppositions[ poffset + 1 ] = position.y;
				ppositions[ poffset + 2 ] = position.z;
M
Mr.doob 已提交
398

399 400
				pdistances[ plength ] = distance;

401
				plength += 1;
M
Mr.doob 已提交
402

403 404 405
			}

		}
406

407 408
		// null eventual remains from removed lights
		// (this is to avoid if in shader)
409

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

413 414
		zlights.point.length = plength;
		zlights.directional.length = dlength;
M
Mr.doob 已提交
415

416 417 418
		zlights.ambient[ 0 ] = r;
		zlights.ambient[ 1 ] = g;
		zlights.ambient[ 2 ] = b;
M
Mr.doob 已提交
419

420
	};
M
Mr.doob 已提交
421

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

424 425
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
M
Mr.doob 已提交
426

427
	};
M
Mr.doob 已提交
428

429
	function createLineBuffers( geometry ) {
M
Mr.doob 已提交
430

431 432
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
M
Mr.doob 已提交
433

434
	};
435

436
	function createRibbonBuffers( geometry ) {
A
alteredq 已提交
437

438 439
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
A
alteredq 已提交
440 441 442

	};

443
	function createMeshBuffers( geometryGroup ) {
M
Mr.doob 已提交
444

445 446 447 448 449 450
		geometryGroup.__webglVertexBuffer = _gl.createBuffer();
		geometryGroup.__webglNormalBuffer = _gl.createBuffer();
		geometryGroup.__webglTangentBuffer = _gl.createBuffer();
		geometryGroup.__webglColorBuffer = _gl.createBuffer();
		geometryGroup.__webglUVBuffer = _gl.createBuffer();
		geometryGroup.__webglUV2Buffer = _gl.createBuffer();
451

452 453 454 455 456 457 458 459 460
		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 ) {
461

462
			var m, ml;
463 464 465 466 467 468
			geometryGroup.__webglMorphTargetsBuffers = []; 

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

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

469 470 471
			}

		}
M
Mr.doob 已提交
472

473
	};
474

475
	function initLineBuffers ( geometry ) {
M
Mr.doob 已提交
476

477 478 479
		var nvertices = geometry.vertices.length;

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

482
		geometry.__webglLineCount = nvertices;
M
Mr.doob 已提交
483

484
	};
M
Mr.doob 已提交
485

486
	function initRibbonBuffers ( geometry ) {
A
alteredq 已提交
487 488 489 490 491 492

		var nvertices = geometry.vertices.length;

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

493
		geometry.__webglVertexCount = nvertices;
A
alteredq 已提交
494 495

	};
496

497
	function initParticleBuffers ( geometry ) {
498 499 500 501

		var nvertices = geometry.vertices.length;

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

504
		geometry.__sortArray = [];
505

506
		geometry.__webglParticleCount = nvertices;
507 508 509

	};

510
	function initMeshBuffers ( geometryGroup, object ) {
M
Mr.doob 已提交
511

M
Mikael Emtinger 已提交
512
		var f, fl, fi, face,
513
		m, ml, size,
514 515 516 517 518 519
		nvertices = 0, ntris = 0, nlines = 0,

		uvType,
		vertexColorType,
		normalType,
		materials,
520
		attribute,
521 522 523 524

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

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

528 529
			fi = chunk_faces[ f ];
			face = obj_faces[ fi ];
M
Mr.doob 已提交
530

531
			if ( face instanceof THREE.Face3 ) {
M
Mr.doob 已提交
532

533 534 535
				nvertices += 3;
				ntris += 1;
				nlines += 3;
M
Mr.doob 已提交
536

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

539 540
				nvertices += 4;
				ntris += 2;
541
				nlines += 4;
M
Mr.doob 已提交
542

543
			}
M
Mr.doob 已提交
544

545
		}
546 547 548

		materials = unrollGroupMaterials( geometryGroup, object );

549 550
		uvType = bufferGuessUVType( materials, geometryGroup, object );
		normalType = bufferGuessNormalType( materials, geometryGroup, object );
A
alteredq 已提交
551 552
		vertexColorType = bufferGuessVertexColorType( materials, geometryGroup, object );

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

555
		geometryGroup.__vertexArray = new Float32Array( nvertices * 3 );
556

557
		if ( normalType ) {
M
Mr.doob 已提交
558

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

561
		}
562

563
		if ( geometry.hasTangents ) {
564

565
			geometryGroup.__tangentArray = new Float32Array( nvertices * 4 );
566

567
		}
568

569
		if ( vertexColorType ) {
570

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

573
		}
M
Mr.doob 已提交
574

575
		if ( uvType ) {
576

577
			if ( geometry.faceUvs.length > 0 || geometry.faceVertexUvs.length > 0 ) {
578

579 580 581 582 583
				geometryGroup.__uvArray = new Float32Array( nvertices * 2 );

			}

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

585 586 587 588 589 590 591 592 593 594 595 596 597 598 599
				geometryGroup.__uv2Array = new Float32Array( nvertices * 2 );

			}

		}

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

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

		}

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

603 604
		if ( geometryGroup.numMorphTargets ) {

605
			geometryGroup.__morphTargetsArrays = []; 
606 607 608

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

609 610
				geometryGroup.__morphTargetsArrays.push( new Float32Array( nvertices * 3 ) );

611 612 613
			}

		}
614

615
		geometryGroup.__needsSmoothNormals = ( normalType == THREE.SmoothShading );
616

617 618 619 620
		geometryGroup.__uvType = uvType;
		geometryGroup.__vertexColorType = vertexColorType;
		geometryGroup.__normalType = normalType;

621 622
		geometryGroup.__webglFaceCount = ntris * 3 + ( object.geometry.edgeFaces ? object.geometry.edgeFaces.length * 2 * 3 : 0 );
		geometryGroup.__webglLineCount = nlines * 2;
623

M
Mr.doob 已提交
624

625
		// custom attributes
M
Mr.doob 已提交
626 627 628 629 630

		for ( m = 0, ml = materials.length; m < ml; m ++ ) {

			if ( materials[ m ].attributes ) {

631 632
				geometryGroup.__webglCustomAttributes = {};

M
Mr.doob 已提交
633 634
				for ( a in materials[ m ].attributes ) {

635
					attribute = materials[ m ].attributes[ a ];
M
Mr.doob 已提交
636

637
					size = 1;		// "f" and "i"
M
Mr.doob 已提交
638 639

					if( attribute.type === "v2" ) size = 2;
640 641 642
					else if( attribute.type === "v3" ) size = 3;
					else if( attribute.type === "v4" ) size = 4;
					else if( attribute.type === "c"  ) size = 3;
M
Mr.doob 已提交
643

644
					attribute.size = size;
M
Mr.doob 已提交
645
					attribute.needsUpdate = true;
646 647 648 649 650 651 652 653
					attribute.array = new Float32Array( nvertices * size );
					attribute.buffer = _gl.createBuffer();

					geometryGroup.__webglCustomAttributes[ a ] = attribute;

				}

			}
M
Mr.doob 已提交
654

655
		}
656

657
	};
M
Mr.doob 已提交
658

659

660
	function setMeshBuffers ( geometryGroup, object, hint ) {
661

M
Mr.doob 已提交
662
		var f, fl, fi, face,
663 664 665 666 667 668 669 670 671 672 673 674 675
		vertexNormals, faceNormal, normal,
		vertexColors, faceColor,
		vertexTangents,
		uvType, vertexColorType, normalType,
		uv, uv2, v1, v2, v3, v4, t1, t2, t3, t4,
		c1, c2, c3, c4,
		sw1, sw2, sw3, sw4,
		si1, si2, si3, si4,
		sa1, sa2, sa3, sa4,
		sb1, sb2, sb3, sb4,
		m, ml, i,
		vn, uvi, uv2i,
		vk, vkl, vka,
676
		a,
M
Mr.doob 已提交
677

678
		vertexIndex = 0,
679

680 681
		offset = 0,
		offset_uv = 0,
682
		offset_uv2 = 0,
683 684 685 686
		offset_face = 0,
		offset_normal = 0,
		offset_tangent = 0,
		offset_line = 0,
687
		offset_color = 0,
A
alteredq 已提交
688
		offset_skin = 0,
689
		offset_morphTarget = 0,
690
		offset_custom = 0,
691
		offset_customSrc = 0,
M
Mr.doob 已提交
692

693 694 695 696 697 698
		vertexArray = geometryGroup.__vertexArray,
		uvArray = geometryGroup.__uvArray,
		uv2Array = geometryGroup.__uv2Array,
		normalArray = geometryGroup.__normalArray,
		tangentArray = geometryGroup.__tangentArray,
		colorArray = geometryGroup.__colorArray,
699

700 701 702 703
		skinVertexAArray = geometryGroup.__skinVertexAArray,
		skinVertexBArray = geometryGroup.__skinVertexBArray,
		skinIndexArray = geometryGroup.__skinIndexArray,
		skinWeightArray = geometryGroup.__skinWeightArray,
M
Mr.doob 已提交
704

705 706
		morphTargetsArrays = geometryGroup.__morphTargetsArrays,

707 708
		customAttributes = geometryGroup.__webglCustomAttributes,
		customAttribute,
709

710 711
		faceArray = geometryGroup.__faceArray,
		lineArray = geometryGroup.__lineArray,
M
Mr.doob 已提交
712

713
		needsSmoothNormals = geometryGroup.__needsSmoothNormals,
714

715
		vertexColorType = geometryGroup.__vertexColorType,
A
alteredq 已提交
716 717
		uvType = geometryGroup.__uvType,
		normalType = geometryGroup.__normalType,
718

719
		geometry = object.geometry, // this is shared for all chunks
720

721
		dirtyVertices = geometry.__dirtyVertices,
722 723 724
		dirtyElements = geometry.__dirtyElements,
		dirtyUvs = geometry.__dirtyUvs,
		dirtyNormals = geometry.__dirtyNormals,
725
		dirtyTangents = geometry.__dirtyTangents,
726
		dirtyColors = geometry.__dirtyColors,
727
		dirtyMorphTargets = geometry.__dirtyMorphTargets,
M
Mr.doob 已提交
728

729
		vertices = geometry.vertices,
730
		chunk_faces = geometryGroup.faces,
731
		obj_faces = geometry.faces,
732

733 734
		obj_uvs  = geometry.faceVertexUvs[ 0 ],
		obj_uvs2 = geometry.faceVertexUvs[ 1 ],
735

A
alteredq 已提交
736
		obj_colors = geometry.colors,
737

A
alteredq 已提交
738 739 740
		obj_skinVerticesA = geometry.skinVerticesA,
		obj_skinVerticesB = geometry.skinVerticesB,
		obj_skinIndices = geometry.skinIndices,
741
		obj_skinWeights = geometry.skinWeights,
M
Mikael Emtinger 已提交
742
		obj_edgeFaces = geometry.edgeFaces,
743 744

		morphTargets = geometry.morphTargets;
745

746
		if ( customAttributes ) {
M
Mr.doob 已提交
747

748
			for ( a in customAttributes ) {
M
Mr.doob 已提交
749

750
				customAttributes[ a ].offset = 0;
751
				customAttributes[ a ].offsetSrc = 0;
M
Mr.doob 已提交
752

753 754
			}

M
Mr.doob 已提交
755
		}
756 757


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

760 761
			fi = chunk_faces[ f ];
			face = obj_faces[ fi ];
762 763

			if ( obj_uvs ) {
A
alteredq 已提交
764 765 766 767

				uv = obj_uvs[ fi ];

			}
768 769 770

			if ( obj_uvs2 ) {

A
alteredq 已提交
771 772 773
				uv2 = obj_uvs2[ fi ];

			}
M
Mr.doob 已提交
774

775
			vertexNormals = face.vertexNormals;
776
			faceNormal = face.normal;
777

778 779
			vertexColors = face.vertexColors;
			faceColor = face.color;
780

781
			vertexTangents = face.vertexTangents;
782 783 784

			if ( face instanceof THREE.Face3 ) {

785
				if ( dirtyVertices ) {
M
Mr.doob 已提交
786

787 788 789
					v1 = vertices[ face.a ].position;
					v2 = vertices[ face.b ].position;
					v3 = vertices[ face.c ].position;
M
Mr.doob 已提交
790

791 792 793
					vertexArray[ offset ]     = v1.x;
					vertexArray[ offset + 1 ] = v1.y;
					vertexArray[ offset + 2 ] = v1.z;
M
Mr.doob 已提交
794

795 796 797
					vertexArray[ offset + 3 ] = v2.x;
					vertexArray[ offset + 4 ] = v2.y;
					vertexArray[ offset + 5 ] = v2.z;
798

799 800 801
					vertexArray[ offset + 6 ] = v3.x;
					vertexArray[ offset + 7 ] = v3.y;
					vertexArray[ offset + 8 ] = v3.z;
M
Mr.doob 已提交
802

803
					offset += 9;
M
Mr.doob 已提交
804

805
				}
806

807
				if ( customAttributes ) {
M
Mr.doob 已提交
808

809
					for ( a in customAttributes ) {
M
Mr.doob 已提交
810

811 812
						customAttribute = customAttributes[ a ];

M
Mr.doob 已提交
813 814
						if ( customAttribute.needsUpdate ) {

815
							offset_custom = customAttribute.offset;
816
							offset_customSrc = customAttribute.offsetSrc;
M
Mr.doob 已提交
817

818
							if( customAttribute.size === 1 ) {
M
Mr.doob 已提交
819

820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842
								if( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {
									
									customAttribute.array[ offset_custom + 0 ] = customAttribute.value[ face.a ];
									customAttribute.array[ offset_custom + 1 ] = customAttribute.value[ face.b ];
									customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ face.c ];
									
								} else if( customAttribute.boundTo === "faces" ) {
									
									customAttribute.array[ offset_custom + 0 ] = customAttribute.value[ offset_customSrc ];
									customAttribute.array[ offset_custom + 1 ] = customAttribute.value[ offset_customSrc ];
									customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ offset_customSrc ];

									customAttribute.offsetSrc++;
								
								} else if( customAttribute.boundTo === "faceVertices" ) {
									
									customAttribute.array[ offset_custom + 0 ] = customAttribute.value[ offset_customSrc + 0 ];
									customAttribute.array[ offset_custom + 1 ] = customAttribute.value[ offset_customSrc + 1 ];
									customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ offset_customSrc + 2 ];
									
									customAttribute.offsetSrc += 3;
	
								}
M
Mr.doob 已提交
843

844
								customAttribute.offset += 3;
M
Mr.doob 已提交
845

846
							} else {
M
Mr.doob 已提交
847

848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870
								if( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {
									
									v1 = customAttribute.value[ face.a ];
									v2 = customAttribute.value[ face.b ];
									v3 = customAttribute.value[ face.c ];
									
								} else if( customAttribute.boundTo === "faces" ) {
									
									v1 = customAttribute.value[ offset_customSrc ];
									v2 = customAttribute.value[ offset_customSrc ];
									v3 = customAttribute.value[ offset_customSrc ];

									customAttribute.offsetSrc++;
									
								} else if( customAttribute.boundTo === "faceVertices" ) {
									
									v1 = customAttribute.value[ offset_customSrc + 0 ];
									v2 = customAttribute.value[ offset_customSrc + 1 ];
									v3 = customAttribute.value[ offset_customSrc + 2 ];
									
									customAttribute.offsetSrc += 3;
								}
								
M
Mr.doob 已提交
871

872
								if( customAttribute.size === 2 ) {
M
Mr.doob 已提交
873 874 875

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

M
Mr.doob 已提交
877 878
									customAttribute.array[ offset_custom + 2 ] = v2.x;
									customAttribute.array[ offset_custom + 3 ] = v2.y;
879

M
Mr.doob 已提交
880
									customAttribute.array[ offset_custom + 4 ] = v3.x;
881
									customAttribute.array[ offset_custom + 5 ] = v3.y;
M
Mr.doob 已提交
882

883
									customAttribute.offset += 6;
M
Mr.doob 已提交
884

885
								} else if( customAttribute.size === 3 ) {
M
Mr.doob 已提交
886

887 888 889 890 891
									if( customAttribute.type === "c" ) {
										
										customAttribute.array[ offset_custom + 0 ] = v1.r;
										customAttribute.array[ offset_custom + 1 ] = v1.g;
										customAttribute.array[ offset_custom + 2 ] = v1.b;
892

893 894 895
										customAttribute.array[ offset_custom + 3 ] = v2.r;
										customAttribute.array[ offset_custom + 4 ] = v2.g;
										customAttribute.array[ offset_custom + 5 ] = v2.b;
896

897 898 899 900 901 902 903 904 905
										customAttribute.array[ offset_custom + 6 ] = v3.r;
										customAttribute.array[ offset_custom + 7 ] = v3.g;
										customAttribute.array[ offset_custom + 8 ] = v3.b;
										
									} else {
										
										customAttribute.array[ offset_custom + 0 ] = v1.x;
										customAttribute.array[ offset_custom + 1 ] = v1.y;
										customAttribute.array[ offset_custom + 2 ] = v1.z;
906

907 908 909
										customAttribute.array[ offset_custom + 3 ] = v2.x;
										customAttribute.array[ offset_custom + 4 ] = v2.y;
										customAttribute.array[ offset_custom + 5 ] = v2.z;
910

911 912 913 914 915
										customAttribute.array[ offset_custom + 6 ] = v3.x;
										customAttribute.array[ offset_custom + 7 ] = v3.y;
										customAttribute.array[ offset_custom + 8 ] = v3.z;
										
									}
M
Mr.doob 已提交
916

917
									customAttribute.offset += 9;
M
Mr.doob 已提交
918

919
								} else {
M
Mr.doob 已提交
920 921 922 923 924

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

M
Mr.doob 已提交
926 927 928 929
									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;
930

M
Mr.doob 已提交
931
									customAttribute.array[ offset_custom + 8  ] = v3.x;
932 933 934
									customAttribute.array[ offset_custom + 9  ] = v3.y;
									customAttribute.array[ offset_custom + 10 ] = v3.z;
									customAttribute.array[ offset_custom + 11 ] = v3.w;
M
Mr.doob 已提交
935

936
									customAttribute.offset += 12;
M
Mr.doob 已提交
937

938
								}
M
Mr.doob 已提交
939

940
							}
M
Mr.doob 已提交
941

942
						}
M
Mr.doob 已提交
943

944
					}
M
Mr.doob 已提交
945

946 947 948
				}


949
				if ( dirtyMorphTargets ) {
950 951 952

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

953 954 955
						v1 = morphTargets[ vk ].vertices[ face.a ].position;
						v2 = morphTargets[ vk ].vertices[ face.b ].position;
						v3 = morphTargets[ vk ].vertices[ face.c ].position;
956

957
						vka = morphTargetsArrays[ vk ];
958

959 960 961
						vka[ offset_morphTarget + 0 ] = v1.x;
						vka[ offset_morphTarget + 1 ] = v1.y;
						vka[ offset_morphTarget + 2 ] = v1.z;
962

963 964 965
						vka[ offset_morphTarget + 3 ] = v2.x;
						vka[ offset_morphTarget + 4 ] = v2.y;
						vka[ offset_morphTarget + 5 ] = v2.z;
966

967 968 969
						vka[ offset_morphTarget + 6 ] = v3.x;
						vka[ offset_morphTarget + 7 ] = v3.y;
						vka[ offset_morphTarget + 8 ] = v3.z;
970 971
					}

972
					offset_morphTarget += 9;
973

974 975
				}

A
alteredq 已提交
976 977 978
				if ( obj_skinWeights.length ) {

					// weights
979

A
alteredq 已提交
980 981 982
					sw1 = obj_skinWeights[ face.a ];
					sw2 = obj_skinWeights[ face.b ];
					sw3 = obj_skinWeights[ face.c ];
983

A
alteredq 已提交
984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999
					skinWeightArray[ offset_skin ]     = sw1.x;
					skinWeightArray[ offset_skin + 1 ] = sw1.y;
					skinWeightArray[ offset_skin + 2 ] = sw1.z;
					skinWeightArray[ offset_skin + 3 ] = sw1.w;

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

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

					// indices
1000

A
alteredq 已提交
1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020
					si1 = obj_skinIndices[ face.a ];
					si2 = obj_skinIndices[ face.b ];
					si3 = obj_skinIndices[ face.c ];

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

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

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

					// vertices A
1021

A
alteredq 已提交
1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041
					sa1 = obj_skinVerticesA[ face.a ];
					sa2 = obj_skinVerticesA[ face.b ];
					sa3 = obj_skinVerticesA[ face.c ];

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

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

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

					// vertices B
1042

A
alteredq 已提交
1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062
					sb1 = obj_skinVerticesB[ face.a ];
					sb2 = obj_skinVerticesB[ face.b ];
					sb3 = obj_skinVerticesB[ face.c ];

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

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

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

					offset_skin += 12;
1063

A
alteredq 已提交
1064
				}
1065

1066 1067 1068
				if ( dirtyColors && vertexColorType ) {

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

1070 1071 1072 1073 1074
						c1 = vertexColors[ 0 ];
						c2 = vertexColors[ 1 ];
						c3 = vertexColors[ 2 ];

					} else {
1075

1076 1077 1078 1079 1080
						c1 = faceColor;
						c2 = faceColor;
						c3 = faceColor;

					}
1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092

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

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

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

1094 1095 1096 1097
					offset_color += 9;

				}

1098
				if ( dirtyTangents && geometry.hasTangents ) {
1099

1100 1101 1102
					t1 = vertexTangents[ 0 ];
					t2 = vertexTangents[ 1 ];
					t3 = vertexTangents[ 2 ];
1103

1104 1105 1106 1107
					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 已提交
1108

1109 1110 1111 1112
					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 已提交
1113

1114 1115 1116 1117
					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 已提交
1118

1119
					offset_tangent += 12;
M
Mr.doob 已提交
1120

1121 1122
				}

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

1125 1126 1127
					if ( vertexNormals.length == 3 && needsSmoothNormals ) {

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

1129
							vn = vertexNormals[ i ];
M
Mr.doob 已提交
1130

1131 1132 1133
							normalArray[ offset_normal ]     = vn.x;
							normalArray[ offset_normal + 1 ] = vn.y;
							normalArray[ offset_normal + 2 ] = vn.z;
M
Mr.doob 已提交
1134

1135
							offset_normal += 3;
M
Mr.doob 已提交
1136

1137
						}
M
Mr.doob 已提交
1138

1139
					} else {
1140

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

1143 1144 1145
							normalArray[ offset_normal ]     = faceNormal.x;
							normalArray[ offset_normal + 1 ] = faceNormal.y;
							normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
1146

1147
							offset_normal += 3;
M
Mr.doob 已提交
1148

1149
						}
M
Mr.doob 已提交
1150 1151

					}
M
Mr.doob 已提交
1152

1153 1154
				}

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

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

1159
						uvi = uv[ i ];
M
Mr.doob 已提交
1160

1161 1162
						uvArray[ offset_uv ]     = uvi.u;
						uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
1163

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

M
Mr.doob 已提交
1166
					}
1167 1168 1169

				}

A
alteredq 已提交
1170
				if ( dirtyUvs && uv2 !== undefined && uvType ) {
1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184

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

						uv2i = uv2[ i ];

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

						offset_uv2 += 2;

					}

				}

1185
				if ( dirtyElements ) {
M
Mr.doob 已提交
1186

1187 1188 1189
					faceArray[ offset_face ] = vertexIndex;
					faceArray[ offset_face + 1 ] = vertexIndex + 1;
					faceArray[ offset_face + 2 ] = vertexIndex + 2;
M
Mr.doob 已提交
1190

1191
					offset_face += 3;
M
Mr.doob 已提交
1192

1193 1194
					lineArray[ offset_line ]     = vertexIndex;
					lineArray[ offset_line + 1 ] = vertexIndex + 1;
M
Mr.doob 已提交
1195

1196 1197
					lineArray[ offset_line + 2 ] = vertexIndex;
					lineArray[ offset_line + 3 ] = vertexIndex + 2;
M
Mr.doob 已提交
1198

1199 1200
					lineArray[ offset_line + 4 ] = vertexIndex + 1;
					lineArray[ offset_line + 5 ] = vertexIndex + 2;
M
Mr.doob 已提交
1201

1202
					offset_line += 6;
1203

1204
					vertexIndex += 3;
M
Mr.doob 已提交
1205

1206
				}
M
Mr.doob 已提交
1207

1208 1209 1210

			} else if ( face instanceof THREE.Face4 ) {

1211
				if ( dirtyVertices ) {
M
Mr.doob 已提交
1212

1213 1214 1215 1216
					v1 = vertices[ face.a ].position;
					v2 = vertices[ face.b ].position;
					v3 = vertices[ face.c ].position;
					v4 = vertices[ face.d ].position;
M
Mr.doob 已提交
1217

1218 1219 1220
					vertexArray[ offset ]     = v1.x;
					vertexArray[ offset + 1 ] = v1.y;
					vertexArray[ offset + 2 ] = v1.z;
M
Mr.doob 已提交
1221

1222 1223 1224
					vertexArray[ offset + 3 ] = v2.x;
					vertexArray[ offset + 4 ] = v2.y;
					vertexArray[ offset + 5 ] = v2.z;
1225

1226 1227 1228
					vertexArray[ offset + 6 ] = v3.x;
					vertexArray[ offset + 7 ] = v3.y;
					vertexArray[ offset + 8 ] = v3.z;
1229

1230
					vertexArray[ offset + 9 ]  = v4.x;
1231 1232
					vertexArray[ offset + 10 ] = v4.y;
					vertexArray[ offset + 11 ] = v4.z;
M
Mr.doob 已提交
1233

1234
					offset += 12;
M
Mr.doob 已提交
1235

1236
				}
1237

1238
				if ( customAttributes ) {
M
Mr.doob 已提交
1239

1240
					for ( a in customAttributes ) {
M
Mr.doob 已提交
1241

1242 1243
						customAttribute = customAttributes[ a ];

M
Mr.doob 已提交
1244
						if ( customAttribute.needsUpdate ) {
1245 1246

							offset_custom = customAttribute.offset;
1247
							offset_customSrc = customAttribute.offsetSrc;
M
Mr.doob 已提交
1248

1249
							if( customAttribute.size === 1 ) {
M
Mr.doob 已提交
1250

1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275
								if( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {
									
									customAttribute.array[ offset_custom + 0 ] = customAttribute.value[ face.a ];
									customAttribute.array[ offset_custom + 1 ] = customAttribute.value[ face.b ];
									customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ face.c ];
									customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ face.d ];
									
								} else if( customAttribute.boundTo === "faces" ) {
									
									customAttribute.array[ offset_custom + 0 ] = customAttribute.value[ offset_customSrc ];
									customAttribute.array[ offset_custom + 1 ] = customAttribute.value[ offset_customSrc ];
									customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ offset_customSrc ];
									customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ offset_customSrc ];

									customAttribute.offsetSrc++;
									
								} else if( customAttribute.boundTo === "faceVertices" ) {
									
									customAttribute.array[ offset_custom + 0 ] = customAttribute.value[ offset_customSrc + 0 ];
									customAttribute.array[ offset_custom + 1 ] = customAttribute.value[ offset_customSrc + 1 ];
									customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ offset_customSrc + 2 ];
									customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ offset_customSrc + 3 ];
									
									customAttribute.offsetSrc += 4;
								}
M
Mr.doob 已提交
1276

1277
								customAttribute.offset += 4;
M
Mr.doob 已提交
1278

1279
							} else {
M
Mr.doob 已提交
1280

1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306
								if( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {
									
									v1 = customAttribute.value[ face.a ];
									v2 = customAttribute.value[ face.b ];
									v3 = customAttribute.value[ face.c ];
									v4 = customAttribute.value[ face.d ];
									
								} else if( customAttribute.boundTo === "faces" ) {
									
									v1 = customAttribute.value[ offset_customSrc ];
									v2 = customAttribute.value[ offset_customSrc ];
									v3 = customAttribute.value[ offset_customSrc ];
									v4 = customAttribute.value[ offset_customSrc ];

									customAttribute.offsetSrc++;
									
								} else if( customAttribute.boundTo === "faceVertices" ) {
									
									v1 = customAttribute.value[ offset_customSrc + 0 ];
									v2 = customAttribute.value[ offset_customSrc + 1 ];
									v3 = customAttribute.value[ offset_customSrc + 2 ];
									v4 = customAttribute.value[ offset_customSrc + 3 ];
									
									customAttribute.offsetSrc += 4;
								}

M
Mr.doob 已提交
1307

1308
								if( customAttribute.size === 2 ) {
M
Mr.doob 已提交
1309 1310 1311

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

M
Mr.doob 已提交
1313 1314
									customAttribute.array[ offset_custom + 2 ] = v2.x;
									customAttribute.array[ offset_custom + 3 ] = v2.y;
1315

M
Mr.doob 已提交
1316
									customAttribute.array[ offset_custom + 4 ] = v3.x;
1317
									customAttribute.array[ offset_custom + 5 ] = v3.y;
1318

M
Mr.doob 已提交
1319
									customAttribute.array[ offset_custom + 6 ] = v4.x;
1320
									customAttribute.array[ offset_custom + 7 ] = v4.y;
M
Mr.doob 已提交
1321

1322
									customAttribute.offset += 8;
M
Mr.doob 已提交
1323

1324
								} else if( customAttribute.size === 3 ) {
M
Mr.doob 已提交
1325

1326 1327 1328 1329 1330
									if( customAttribute.type === "c" ) {
										
										customAttribute.array[ offset_custom + 0  ] = v1.r;
										customAttribute.array[ offset_custom + 1  ] = v1.g;
										customAttribute.array[ offset_custom + 2  ] = v1.b;
1331

1332 1333 1334
										customAttribute.array[ offset_custom + 3  ] = v2.r;
										customAttribute.array[ offset_custom + 4  ] = v2.g;
										customAttribute.array[ offset_custom + 5  ] = v2.b;
1335

1336 1337 1338
										customAttribute.array[ offset_custom + 6  ] = v3.r;
										customAttribute.array[ offset_custom + 7  ] = v3.g;
										customAttribute.array[ offset_custom + 8  ] = v3.b;
1339

1340 1341 1342 1343 1344 1345 1346 1347 1348
										customAttribute.array[ offset_custom + 9  ] = v4.r;
										customAttribute.array[ offset_custom + 10 ] = v4.g;
										customAttribute.array[ offset_custom + 11 ] = v4.b;

									} else {
										
										customAttribute.array[ offset_custom + 0  ] = v1.x;
										customAttribute.array[ offset_custom + 1  ] = v1.y;
										customAttribute.array[ offset_custom + 2  ] = v1.z;
1349

1350 1351 1352
										customAttribute.array[ offset_custom + 3  ] = v2.x;
										customAttribute.array[ offset_custom + 4  ] = v2.y;
										customAttribute.array[ offset_custom + 5  ] = v2.z;
1353

1354 1355 1356
										customAttribute.array[ offset_custom + 6  ] = v3.x;
										customAttribute.array[ offset_custom + 7  ] = v3.y;
										customAttribute.array[ offset_custom + 8  ] = v3.z;
1357

1358 1359 1360 1361 1362
										customAttribute.array[ offset_custom + 9  ] = v4.x;
										customAttribute.array[ offset_custom + 10 ] = v4.y;
										customAttribute.array[ offset_custom + 11 ] = v4.z;
										
									}
M
Mr.doob 已提交
1363

1364
									customAttribute.offset += 12;
M
Mr.doob 已提交
1365

1366
								} else {
M
Mr.doob 已提交
1367 1368 1369 1370 1371

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

M
Mr.doob 已提交
1373 1374 1375 1376
									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;
1377

M
Mr.doob 已提交
1378
									customAttribute.array[ offset_custom + 8  ] = v3.x;
1379 1380 1381
									customAttribute.array[ offset_custom + 9  ] = v3.y;
									customAttribute.array[ offset_custom + 10 ] = v3.z;
									customAttribute.array[ offset_custom + 11 ] = v3.w;
1382

M
Mr.doob 已提交
1383
									customAttribute.array[ offset_custom + 12 ] = v4.x;
1384 1385 1386
									customAttribute.array[ offset_custom + 13 ] = v4.y;
									customAttribute.array[ offset_custom + 14 ] = v4.z;
									customAttribute.array[ offset_custom + 15 ] = v4.w;
M
Mr.doob 已提交
1387

1388
									customAttribute.offset += 16;
M
Mr.doob 已提交
1389

1390
								}
M
Mr.doob 已提交
1391

1392
							}
M
Mr.doob 已提交
1393

1394
						}
M
Mr.doob 已提交
1395

1396
					}
M
Mr.doob 已提交
1397

1398 1399 1400
				}


1401
				if ( dirtyMorphTargets ) {
1402 1403 1404

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

1405 1406 1407 1408
						v1 = morphTargets[ vk ].vertices[ face.a ].position;
						v2 = morphTargets[ vk ].vertices[ face.b ].position;
						v3 = morphTargets[ vk ].vertices[ face.c ].position;
						v4 = morphTargets[ vk ].vertices[ face.d ].position;
1409

1410
						vka = morphTargetsArrays[ vk ];
1411

1412 1413 1414
						vka[ offset_morphTarget + 0 ] = v1.x;
						vka[ offset_morphTarget + 1 ] = v1.y;
						vka[ offset_morphTarget + 2 ] = v1.z;
1415

1416 1417 1418
						vka[ offset_morphTarget + 3 ] = v2.x;
						vka[ offset_morphTarget + 4 ] = v2.y;
						vka[ offset_morphTarget + 5 ] = v2.z;
1419

1420 1421 1422
						vka[ offset_morphTarget + 6 ] = v3.x;
						vka[ offset_morphTarget + 7 ] = v3.y;
						vka[ offset_morphTarget + 8 ] = v3.z;
1423

1424 1425 1426
						vka[ offset_morphTarget + 9 ] = v4.x;
						vka[ offset_morphTarget + 10 ] = v4.y;
						vka[ offset_morphTarget + 11 ] = v4.z;
1427 1428
					}

1429
					offset_morphTarget += 12;
1430

1431 1432
				}

A
alteredq 已提交
1433 1434 1435
				if ( obj_skinWeights.length ) {

					// weights
1436

A
alteredq 已提交
1437 1438 1439 1440
					sw1 = obj_skinWeights[ face.a ];
					sw2 = obj_skinWeights[ face.b ];
					sw3 = obj_skinWeights[ face.c ];
					sw4 = obj_skinWeights[ face.d ];
1441

A
alteredq 已提交
1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462
					skinWeightArray[ offset_skin ]     = sw1.x;
					skinWeightArray[ offset_skin + 1 ] = sw1.y;
					skinWeightArray[ offset_skin + 2 ] = sw1.z;
					skinWeightArray[ offset_skin + 3 ] = sw1.w;

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

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

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

					// indices
1463

A
alteredq 已提交
1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489
					si1 = obj_skinIndices[ face.a ];
					si2 = obj_skinIndices[ face.b ];
					si3 = obj_skinIndices[ face.c ];
					si4 = obj_skinIndices[ face.d ];

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

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

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

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

					// vertices A
1490

A
alteredq 已提交
1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516
					sa1 = obj_skinVerticesA[ face.a ];
					sa2 = obj_skinVerticesA[ face.b ];
					sa3 = obj_skinVerticesA[ face.c ];
					sa4 = obj_skinVerticesA[ face.d ];

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

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

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

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

					// vertices B
1517

A
alteredq 已提交
1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537
					sb1 = obj_skinVerticesB[ face.a ];
					sb2 = obj_skinVerticesB[ face.b ];
					sb3 = obj_skinVerticesB[ face.c ];
					sb4 = obj_skinVerticesB[ face.d ];

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

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

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

1538 1539
					skinVertexBArray[ offset_skin + 12 ] = sb4.x;
					skinVertexBArray[ offset_skin + 13 ] = sb4.y;
A
alteredq 已提交
1540 1541 1542
					skinVertexBArray[ offset_skin + 14 ] = sb4.z;
					skinVertexBArray[ offset_skin + 15 ] = 1;

1543 1544
					offset_skin += 16;

A
alteredq 已提交
1545
				}
1546

1547 1548 1549
				if ( dirtyColors && vertexColorType ) {

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

1551 1552 1553 1554 1555 1556
						c1 = vertexColors[ 0 ];
						c2 = vertexColors[ 1 ];
						c3 = vertexColors[ 2 ];
						c4 = vertexColors[ 3 ];

					} else {
1557

1558 1559 1560 1561 1562 1563
						c1 = faceColor;
						c2 = faceColor;
						c3 = faceColor;
						c4 = faceColor;

					}
1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575

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

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

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

1577 1578 1579
					colorArray[ offset_color + 9 ]  = c4.r;
					colorArray[ offset_color + 10 ] = c4.g;
					colorArray[ offset_color + 11 ] = c4.b;
1580

1581 1582
					offset_color += 12;

1583 1584
				}

1585
				if ( dirtyTangents && geometry.hasTangents ) {
1586

1587 1588 1589 1590
					t1 = vertexTangents[ 0 ];
					t2 = vertexTangents[ 1 ];
					t3 = vertexTangents[ 2 ];
					t4 = vertexTangents[ 3 ];
1591

1592 1593 1594 1595
					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 已提交
1596

1597 1598 1599 1600
					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 已提交
1601

1602 1603
					tangentArray[ offset_tangent + 8 ]  = t3.x;
					tangentArray[ offset_tangent + 9 ]  = t3.y;
1604 1605
					tangentArray[ offset_tangent + 10 ] = t3.z;
					tangentArray[ offset_tangent + 11 ] = t3.w;
M
Mr.doob 已提交
1606

1607 1608 1609 1610
					tangentArray[ offset_tangent + 12 ] = t4.x;
					tangentArray[ offset_tangent + 13 ] = t4.y;
					tangentArray[ offset_tangent + 14 ] = t4.z;
					tangentArray[ offset_tangent + 15 ] = t4.w;
M
Mr.doob 已提交
1611

1612
					offset_tangent += 16;
M
Mr.doob 已提交
1613

1614
				}
M
Mr.doob 已提交
1615

M
Mr.doob 已提交
1616
				if ( dirtyNormals && normalType ) {
M
Mr.doob 已提交
1617

1618
					if ( vertexNormals.length == 4 && needsSmoothNormals ) {
1619

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

1622
							vn = vertexNormals[ i ];
M
Mr.doob 已提交
1623

1624 1625 1626
							normalArray[ offset_normal ]     = vn.x;
							normalArray[ offset_normal + 1 ] = vn.y;
							normalArray[ offset_normal + 2 ] = vn.z;
M
Mr.doob 已提交
1627

1628
							offset_normal += 3;
M
Mr.doob 已提交
1629

1630
						}
M
Mr.doob 已提交
1631

1632
					} else {
1633

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

1636 1637 1638
							normalArray[ offset_normal ]     = faceNormal.x;
							normalArray[ offset_normal + 1 ] = faceNormal.y;
							normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
1639

1640
							offset_normal += 3;
M
Mr.doob 已提交
1641

1642
						}
M
Mr.doob 已提交
1643 1644

					}
M
Mr.doob 已提交
1645

1646 1647
				}

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

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

1652
						uvi = uv[ i ];
M
Mr.doob 已提交
1653

1654 1655
						uvArray[ offset_uv ]     = uvi.u;
						uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
1656

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

M
Mr.doob 已提交
1659
					}
1660 1661

				}
1662

A
alteredq 已提交
1663
				if ( dirtyUvs && uv2 !== undefined && uvType ) {
1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676

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

						uv2i = uv2[ i ];

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

						offset_uv2 += 2;

					}

				}
M
Mr.doob 已提交
1677

1678
				if ( dirtyElements ) {
M
Mr.doob 已提交
1679

1680
					faceArray[ offset_face ]     = vertexIndex;
1681 1682
					faceArray[ offset_face + 1 ] = vertexIndex + 1;
					faceArray[ offset_face + 2 ] = vertexIndex + 3;
M
Mr.doob 已提交
1683

1684 1685 1686
					faceArray[ offset_face + 3 ] = vertexIndex + 1;
					faceArray[ offset_face + 4 ] = vertexIndex + 2;
					faceArray[ offset_face + 5 ] = vertexIndex + 3;
M
Mr.doob 已提交
1687

1688
					offset_face += 6;
M
Mr.doob 已提交
1689

1690 1691
					lineArray[ offset_line ]     = vertexIndex;
					lineArray[ offset_line + 1 ] = vertexIndex + 1;
M
Mr.doob 已提交
1692

1693
					lineArray[ offset_line + 2 ] = vertexIndex;
1694
					lineArray[ offset_line + 3 ] = vertexIndex + 3;
M
Mr.doob 已提交
1695

1696 1697
					lineArray[ offset_line + 4 ] = vertexIndex + 1;
					lineArray[ offset_line + 5 ] = vertexIndex + 2;
M
Mr.doob 已提交
1698

1699 1700
					lineArray[ offset_line + 6 ] = vertexIndex + 2;
					lineArray[ offset_line + 7 ] = vertexIndex + 3;
M
Mr.doob 已提交
1701

1702
					offset_line += 8;
M
Mr.doob 已提交
1703

1704
					vertexIndex += 4;
M
Mr.doob 已提交
1705

1706
				}
M
Mr.doob 已提交
1707

1708
			}
M
Mr.doob 已提交
1709

1710 1711
		}

1712 1713 1714 1715
		if ( obj_edgeFaces ) {

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

M
Mikael Emtinger 已提交
1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726
				faceArray[ offset_face ]     = obj_edgeFaces[ f ].a;
				faceArray[ offset_face + 1 ] = obj_edgeFaces[ f ].b;
				faceArray[ offset_face + 2 ] = obj_edgeFaces[ f ].c;

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

				offset_face += 6;
			}

1727
		}
M
Mikael Emtinger 已提交
1728

1729
		if ( dirtyVertices ) {
M
Mr.doob 已提交
1730

1731
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
1732
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
M
Mr.doob 已提交
1733

1734
		}
M
Mr.doob 已提交
1735

1736
		if ( customAttributes ) {
M
Mr.doob 已提交
1737

1738
			for ( a in customAttributes ) {
M
Mr.doob 已提交
1739

1740 1741
				customAttribute = customAttributes[ a ];

M
Mr.doob 已提交
1742
				if ( customAttribute.needsUpdate ) {
1743 1744 1745 1746

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

M
Mr.doob 已提交
1747
					customAttribute.needsUpdate = false;
1748

1749 1750 1751 1752 1753 1754
				}

			}

		}

1755
		if ( dirtyMorphTargets ) {
1756 1757 1758 1759

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

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

1762 1763 1764
			}
		}

1765
		if ( dirtyColors && offset_color > 0 ) {
1766

1767
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
1768 1769 1770
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}
1771

1772
		if ( dirtyNormals ) {
M
Mr.doob 已提交
1773

1774
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
1775
			_gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
M
Mr.doob 已提交
1776

1777 1778
		}

1779
		if ( dirtyTangents && geometry.hasTangents ) {
1780

1781
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
1782
			_gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint );
M
Mr.doob 已提交
1783

1784
		}
1785

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

1788
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
1789
			_gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
M
Mr.doob 已提交
1790

1791
		}
M
Mr.doob 已提交
1792

1793 1794
		if ( dirtyUvs && offset_uv2 > 0 ) {

1795
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
1796 1797 1798 1799
			_gl.bufferData( _gl.ARRAY_BUFFER, uv2Array, hint );

		}

1800
		if ( dirtyElements ) {
M
Mr.doob 已提交
1801

1802
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
1803
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint );
1804

1805
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
1806
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
M
Mr.doob 已提交
1807

1808
		}
1809

1810
		if ( offset_skin > 0 ) {
1811

1812
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
A
alteredq 已提交
1813 1814
			_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexAArray, hint );

1815
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
A
alteredq 已提交
1816 1817
			_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexBArray, hint );

1818
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
A
alteredq 已提交
1819 1820
			_gl.bufferData( _gl.ARRAY_BUFFER, skinIndexArray, hint );

1821
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
A
alteredq 已提交
1822
			_gl.bufferData( _gl.ARRAY_BUFFER, skinWeightArray, hint );
1823

A
alteredq 已提交
1824
		}
1825 1826

	};
1827

1828
	function setLineBuffers ( geometry, hint ) {
M
Mr.doob 已提交
1829

1830
		var v, c, vertex, offset,
1831 1832 1833 1834
		vertices = geometry.vertices,
		colors = geometry.colors,
		vl = vertices.length,
		cl = colors.length,
M
Mr.doob 已提交
1835

1836 1837
		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,
1838

1839 1840
		dirtyVertices = geometry.__dirtyVertices,
		dirtyColors = geometry.__dirtyColors;
M
Mr.doob 已提交
1841

1842
		if ( dirtyVertices ) {
M
Mr.doob 已提交
1843

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

1846
				vertex = vertices[ v ].position;
M
Mr.doob 已提交
1847

1848
				offset = v * 3;
M
Mr.doob 已提交
1849

1850 1851 1852
				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;
M
Mr.doob 已提交
1853

1854 1855
			}

1856
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
A
alteredq 已提交
1857 1858
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );

1859
		}
M
Mr.doob 已提交
1860

1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874
		if ( dirtyColors ) {

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

				color = colors[ c ];

				offset = c * 3;

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

			}

1875
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
1876 1877 1878 1879
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}

1880
	};
M
Mr.doob 已提交
1881

1882
	function setRibbonBuffers ( geometry, hint ) {
A
alteredq 已提交
1883 1884

		var v, c, vertex, offset,
1885 1886 1887 1888
		vertices = geometry.vertices,
		colors = geometry.colors,
		vl = vertices.length,
		cl = colors.length,
A
alteredq 已提交
1889

1890 1891
		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,
1892

1893 1894
		dirtyVertices = geometry.__dirtyVertices,
		dirtyColors = geometry.__dirtyColors;
A
alteredq 已提交
1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909

		if ( dirtyVertices ) {

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

				vertex = vertices[ v ].position;

				offset = v * 3;

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

			}

1910
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
A
alteredq 已提交
1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );

		}

		if ( dirtyColors ) {

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

				color = colors[ c ];

				offset = c * 3;

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

			}

1929
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
A
alteredq 已提交
1930 1931 1932 1933 1934
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}

	};
1935

1936
	function setParticleBuffers ( geometry, hint, object ) {
1937

A
alteredq 已提交
1938
		var v, c, vertex, offset,
1939 1940
		vertices = geometry.vertices,
		vl = vertices.length,
1941

1942 1943
		colors = geometry.colors,
		cl = colors.length,
1944

1945 1946
		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,
1947

1948
		sortArray = geometry.__sortArray,
1949

1950 1951 1952
		dirtyVertices = geometry.__dirtyVertices,
		dirtyElements = geometry.__dirtyElements,
		dirtyColors = geometry.__dirtyColors;
1953

1954
		if ( object.sortParticles ) {
1955

1956
			_projScreenMatrix.multiplySelf( object.matrixWorld );
1957

1958 1959 1960
			for ( v = 0; v < vl; v++ ) {

				vertex = vertices[ v ].position;
1961

1962 1963
				_vector3.copy( vertex );
				_projScreenMatrix.multiplyVector3( _vector3 );
1964

1965
				sortArray[ v ] = [ _vector3.z, v ];
1966

1967
			}
1968

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

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

1973
				vertex = vertices[ sortArray[v][1] ].position;
1974

1975
				offset = v * 3;
1976

1977 1978 1979
				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;
1980

1981
			}
1982

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

A
alteredq 已提交
1985
				offset = c * 3;
1986

A
alteredq 已提交
1987 1988 1989 1990 1991
				color = colors[ sortArray[c][1] ];

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

1993
			}
1994 1995


1996
		} else {
1997

1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010
			if ( dirtyVertices ) {

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

					vertex = vertices[ v ].position;

					offset = v * 3;

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

				}
2011 2012

			}
2013

A
alteredq 已提交
2014
			if ( dirtyColors ) {
2015

A
alteredq 已提交
2016 2017 2018 2019 2020 2021 2022 2023 2024 2025
				for ( c = 0; c < cl; c++ ) {

					color = colors[ c ];

					offset = c * 3;

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

2026
				}
2027

A
alteredq 已提交
2028
			}
2029 2030

		}
2031

A
alteredq 已提交
2032
		if ( dirtyVertices || object.sortParticles ) {
2033

2034
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
A
alteredq 已提交
2035
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
2036

A
alteredq 已提交
2037
		}
2038

A
alteredq 已提交
2039
		if ( dirtyColors || object.sortParticles ) {
2040

2041
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
A
alteredq 已提交
2042
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
2043

A
alteredq 已提交
2044
		}
2045

2046
	};
M
Mr.doob 已提交
2047

2048
	function setMaterialShaders( material, shaders ) {
2049

2050
		material.uniforms = Uniforms.clone( shaders.uniforms );
2051 2052
		material.vertexShader = shaders.vertexShader;
		material.fragmentShader = shaders.fragmentShader;
2053

M
Mr.doob 已提交
2054
	};
2055

2056
	function refreshUniformsCommon( uniforms, material ) {
M
Mr.doob 已提交
2057

2058
		uniforms.diffuse.value.setRGB( material.color.r, material.color.g, material.color.b );
A
alteredq 已提交
2059 2060
		uniforms.opacity.value = material.opacity;
		uniforms.map.texture = material.map;
2061

2062
		uniforms.lightMap.texture = material.lightMap;
2063

2064
		uniforms.envMap.texture = material.envMap;
A
alteredq 已提交
2065
		uniforms.reflectivity.value = material.reflectivity;
2066
		uniforms.refractionRatio.value = material.refractionRatio;
A
alteredq 已提交
2067
		uniforms.combine.value = material.combine;
2068
		uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
2069

2070
	};
2071

2072
	function refreshUniformsLine( uniforms, material ) {
2073

2074
		uniforms.diffuse.value.setRGB( material.color.r, material.color.g, material.color.b );
A
alteredq 已提交
2075
		uniforms.opacity.value = material.opacity;
2076 2077

	};
M
Mr.doob 已提交
2078

2079
	function refreshUniformsParticle( uniforms, material ) {
2080

2081
		uniforms.psColor.value.setRGB( material.color.r, material.color.g, material.color.b );
A
alteredq 已提交
2082 2083
		uniforms.opacity.value = material.opacity;
		uniforms.size.value = material.size;
M
Mr.doob 已提交
2084
		uniforms.scale.value = _canvas.height / 2.0; // TODO: Cache this.
A
alteredq 已提交
2085
		uniforms.map.texture = material.map;
2086

A
alteredq 已提交
2087
	};
2088

2089
	function refreshUniformsFog( uniforms, fog ) {
2090

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

A
alteredq 已提交
2093
		if ( fog instanceof THREE.Fog ) {
2094

A
alteredq 已提交
2095 2096
			uniforms.fogNear.value = fog.near;
			uniforms.fogFar.value = fog.far;
2097

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

A
alteredq 已提交
2100
			uniforms.fogDensity.value = fog.density;
2101 2102

		}
2103

2104 2105
	};

2106
	function refreshUniformsPhong( uniforms, material ) {
M
Mr.doob 已提交
2107

A
alteredq 已提交
2108 2109 2110 2111 2112
		//uniforms.ambient.value.setHex( material.ambient.hex );
		//uniforms.specular.value.setHex( material.specular.hex );
		uniforms.ambient.value.setRGB( material.ambient.r, material.ambient.g, material.ambient.b );
		uniforms.specular.value.setRGB( material.specular.r, material.specular.g, material.specular.b );
		uniforms.shininess.value = material.shininess;
M
Mr.doob 已提交
2113

2114
	};
M
Mr.doob 已提交
2115 2116


2117
	function refreshUniformsLights( uniforms, lights ) {
M
Mr.doob 已提交
2118

A
alteredq 已提交
2119 2120 2121 2122 2123 2124
		uniforms.enableLighting.value = lights.directional.length + lights.point.length;
		uniforms.ambientLightColor.value = lights.ambient;
		uniforms.directionalLightColor.value = lights.directional.colors;
		uniforms.directionalLightDirection.value = lights.directional.positions;
		uniforms.pointLightColor.value = lights.point.colors;
		uniforms.pointLightPosition.value = lights.point.positions;
2125
		uniforms.pointLightDistance.value = lights.point.distances;
M
Mr.doob 已提交
2126

A
alteredq 已提交
2127
	};
M
Mr.doob 已提交
2128

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

2131
		var u, a, identifiers, i, parameters, maxLightCount, maxBones, shaderID;
2132

A
alteredq 已提交
2133
		if ( material instanceof THREE.MeshDepthMaterial ) {
2134

2135
			shaderID = 'depth';
2136

M
Mikael Emtinger 已提交
2137 2138
		} else if ( material instanceof THREE.ShadowVolumeDynamicMaterial ) {

2139
			shaderID = 'shadowVolumeDynamic';
M
Mikael Emtinger 已提交
2140

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

2143
			shaderID = 'normal';
2144

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

2147
			shaderID = 'basic';
2148

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

2151
			shaderID = 'lambert';
M
Mr.doob 已提交
2152

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

2155
			shaderID = 'phong';
M
Mr.doob 已提交
2156

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

2159
			shaderID = 'basic';
2160

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

2163 2164 2165 2166 2167 2168 2169
			shaderID = 'particle_basic';

		}

		if ( shaderID ) {

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

A
alteredq 已提交
2171
		}
2172

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

2176
		maxLightCount = allocateLights( lights, 4 );
2177

2178
		maxBones = allocateBones( object );
M
Mr.doob 已提交
2179

2180
		parameters = {
2181 2182
			map: !!material.map, envMap: !!material.envMap, lightMap: !!material.lightMap, 
			vertexColors: material.vertexColors,
2183 2184 2185
			fog: fog, sizeAttenuation: material.sizeAttenuation,
			skinning: material.skinning,
			morphTargets: material.morphTargets,
2186
			maxMorphTargets: this.maxMorphTargets,
2187 2188 2189
			maxDirLights: maxLightCount.directional, maxPointLights: maxLightCount.point,
			maxBones: maxBones
		};
M
Mikael Emtinger 已提交
2190

2191
		material.program = buildProgram( shaderID, material.fragmentShader, material.vertexShader, material.uniforms, material.attributes, parameters );
2192

2193
		var attributes = material.program.attributes;
2194

2195
		_gl.enableVertexAttribArray( attributes.position );
2196

2197 2198 2199
		if ( attributes.color >= 0 ) _gl.enableVertexAttribArray( attributes.color );
		if ( attributes.normal >= 0 ) _gl.enableVertexAttribArray( attributes.normal );
		if ( attributes.tangent >= 0 ) _gl.enableVertexAttribArray( attributes.tangent );
2200

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

2205 2206 2207 2208
			_gl.enableVertexAttribArray( attributes.skinVertexA );
			_gl.enableVertexAttribArray( attributes.skinVertexB );
			_gl.enableVertexAttribArray( attributes.skinIndex );
			_gl.enableVertexAttribArray( attributes.skinWeight );
2209

2210
		}
2211

2212
		for ( a in material.attributes ) {
2213

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

2216
		}
2217 2218


2219
		if ( material.morphTargets ) {
2220

2221
			material.numSupportedMorphTargets = 0;
2222

2223

2224
			if ( attributes.morphTarget0 >= 0 ) {
2225

2226 2227
				_gl.enableVertexAttribArray( attributes.morphTarget0 );
				material.numSupportedMorphTargets ++;
2228

2229
			}
2230

2231
			if ( attributes.morphTarget1 >= 0 ) {
2232

2233 2234
				_gl.enableVertexAttribArray( attributes.morphTarget1 );
				material.numSupportedMorphTargets ++;
2235

2236
			}
2237

2238
			if ( attributes.morphTarget2 >= 0 ) {
2239

2240 2241
				_gl.enableVertexAttribArray( attributes.morphTarget2 );
				material.numSupportedMorphTargets ++;
2242

2243
			}
2244

2245
			if ( attributes.morphTarget3 >= 0 ) {
2246

2247 2248
				_gl.enableVertexAttribArray( attributes.morphTarget3 );
				material.numSupportedMorphTargets ++;
2249

2250
			}
2251

2252
			if ( attributes.morphTarget4 >= 0 ) {
2253

2254 2255
				_gl.enableVertexAttribArray( attributes.morphTarget4 );
				material.numSupportedMorphTargets ++;
2256

2257
			}
2258

2259
			if ( attributes.morphTarget5 >= 0 ) {
2260

2261 2262
				_gl.enableVertexAttribArray( attributes.morphTarget5 );
				material.numSupportedMorphTargets ++;
2263

2264
			}
2265

2266
			if ( attributes.morphTarget6 >= 0 ) {
2267

2268 2269
				_gl.enableVertexAttribArray( attributes.morphTarget6 );
				material.numSupportedMorphTargets ++;
2270

2271
			}
2272

2273
			if ( attributes.morphTarget7 >= 0 ) {
2274

2275 2276
				_gl.enableVertexAttribArray( attributes.morphTarget7 );
				material.numSupportedMorphTargets ++;
2277

2278
			}
2279

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

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

2284
				object.__webglMorphTargetInfluences[ i ] = 0;
2285 2286 2287

			}

2288
		}
M
Mr.doob 已提交
2289

2290
	};
2291

2292
	function setProgram( camera, lights, fog, material, object ) {
2293

2294
		if ( ! material.program ) {
2295 2296 2297 2298

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

		}
M
Mr.doob 已提交
2299

2300
		var program = material.program,
A
alteredq 已提交
2301 2302
			p_uniforms = program.uniforms,
			m_uniforms = material.uniforms;
2303

2304
		if ( program != _currentProgram ) {
M
Mr.doob 已提交
2305

M
Mr.doob 已提交
2306
			_gl.useProgram( program );
2307
			_currentProgram = program;
2308

M
Mr.doob 已提交
2309
		}
2310

2311 2312
		_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, _projectionMatrixArray );

A
alteredq 已提交
2313
		// refresh uniforms common to several materials
2314 2315

		if ( fog && (
A
alteredq 已提交
2316 2317
			 material instanceof THREE.MeshBasicMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
2318
			 material instanceof THREE.MeshPhongMaterial ||
A
alteredq 已提交
2319
			 material instanceof THREE.LineBasicMaterial ||
2320 2321
			 material instanceof THREE.ParticleBasicMaterial ||
			 material.fog )
A
alteredq 已提交
2322
			) {
2323

A
alteredq 已提交
2324
			refreshUniformsFog( m_uniforms, fog );
2325 2326

		}
M
Mr.doob 已提交
2327

M
Mr.doob 已提交
2328
		if ( material instanceof THREE.MeshPhongMaterial ||
2329 2330
			 material instanceof THREE.MeshLambertMaterial ||
			 material.lights ) {
2331

A
alteredq 已提交
2332
			setupLights( program, lights );
A
alteredq 已提交
2333
			refreshUniformsLights( m_uniforms, _lights );
M
Mr.doob 已提交
2334 2335 2336

		}

2337 2338 2339
		if ( material instanceof THREE.MeshBasicMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
			 material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
2340

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

A
alteredq 已提交
2343
		}
M
Mr.doob 已提交
2344

A
alteredq 已提交
2345
		// refresh single material specific uniforms
2346

2347
		if ( material instanceof THREE.LineBasicMaterial ) {
M
Mr.doob 已提交
2348

A
alteredq 已提交
2349
			refreshUniformsLine( m_uniforms, material );
2350

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

A
alteredq 已提交
2353
			refreshUniformsParticle( m_uniforms, material );
2354

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

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

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

2361 2362
			m_uniforms.mNear.value = camera.near;
			m_uniforms.mFar.value = camera.far;
A
alteredq 已提交
2363
			m_uniforms.opacity.value = material.opacity;
2364

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

A
alteredq 已提交
2367
			m_uniforms.opacity.value = material.opacity;
2368
		}
2369

A
alteredq 已提交
2370
		// load common uniforms
2371

A
alteredq 已提交
2372 2373
		loadUniformsGeneric( program, m_uniforms );
		loadUniformsMatrices( p_uniforms, object );
2374

A
alteredq 已提交
2375 2376
		// load material specific uniforms
		// (shader material also gets them for the sake of genericity)
2377

A
alteredq 已提交
2378 2379
		if ( material instanceof THREE.MeshShaderMaterial ||
			 material instanceof THREE.MeshPhongMaterial ||
2380
			 material.envMap ) {
2381

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

2384
		}
2385

A
alteredq 已提交
2386
		if ( material instanceof THREE.MeshShaderMaterial ||
2387
			 material.envMap ||
2388
			 material.skinning ) {
2389

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

A
alteredq 已提交
2392
		}
2393

A
alteredq 已提交
2394 2395
		if ( material instanceof THREE.MeshPhongMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
A
alteredq 已提交
2396
			 material instanceof THREE.MeshShaderMaterial ||
2397 2398
			 material.skinning ) {

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

A
alteredq 已提交
2401
		}
2402

2403 2404
		if ( material instanceof THREE.ShadowVolumeDynamicMaterial ) {

M
Mikael Emtinger 已提交
2405
			var dirLight = m_uniforms.directionalLightDirection.value;
2406

M
Mikael Emtinger 已提交
2407 2408 2409
			dirLight[ 0 ] = -lights.position.x;
			dirLight[ 1 ] = -lights.position.y;
			dirLight[ 2 ] = -lights.position.z;
2410

M
Mikael Emtinger 已提交
2411 2412 2413 2414 2415 2416
			_gl.uniform3fv( p_uniforms.directionalLightDirection, dirLight );
			_gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object._objectMatrixArray );
			_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, _viewMatrixArray );
		}


2417
		if ( material.skinning ) {
2418

2419
			loadUniformsSkinning( p_uniforms, object );
2420

A
alteredq 已提交
2421
		}
2422

A
alteredq 已提交
2423
		return program;
2424

A
alteredq 已提交
2425
	};
2426

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

2429 2430
		if ( material.opacity == 0 ) return;

2431
		var program, attributes, linewidth, primitives, a, attribute;
A
alteredq 已提交
2432

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

2435
		attributes = program.attributes;
M
Mr.doob 已提交
2436

2437
		// vertices
M
Mr.doob 已提交
2438

2439
		if ( !material.morphTargets ) {
2440 2441

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

2444
		} else {
2445

M
Mikael Emtinger 已提交
2446
			setupMorphTargets( material, geometryGroup, object );
2447

2448 2449
		}

2450 2451 2452 2453

		// custom attributes

		if ( geometryGroup.__webglCustomAttributes ) {
M
Mr.doob 已提交
2454

2455
			for( a in geometryGroup.__webglCustomAttributes ) {
M
Mr.doob 已提交
2456

2457
				if( attributes[ a ] >= 0 ) {
M
Mr.doob 已提交
2458

2459
					attribute = geometryGroup.__webglCustomAttributes[ a ];
M
Mr.doob 已提交
2460

2461 2462
					_gl.bindBuffer( _gl.ARRAY_BUFFER, attribute.buffer );
					_gl.vertexAttribPointer( attributes[ a ], attribute.size, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
2463

2464
				}
M
Mr.doob 已提交
2465

2466
			}
M
Mr.doob 已提交
2467

2468 2469 2470
		}


A
alteredq 已提交
2471 2472 2473 2474
		// colors

		if ( attributes.color >= 0 ) {

2475
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
2476
			_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
2477 2478 2479

		}

2480
		// normals
M
Mr.doob 已提交
2481

2482
		if ( attributes.normal >= 0 ) {
2483

2484
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
2485
			_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
2486

2487
		}
2488

2489 2490 2491
		// tangents

		if ( attributes.tangent >= 0 ) {
2492

2493
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
2494
			_gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
2495

2496
		}
2497

2498
		// uvs
M
Mr.doob 已提交
2499

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

2502
			if ( geometryGroup.__webglUVBuffer ) {
2503

2504
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
2505
				_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
2506

2507
				_gl.enableVertexAttribArray( attributes.uv );
2508

2509
			} else {
2510

2511
				_gl.disableVertexAttribArray( attributes.uv );
M
Mr.doob 已提交
2512

2513
			}
2514 2515 2516

		}

2517 2518
		if ( attributes.uv2 >= 0 ) {

2519
			if ( geometryGroup.__webglUV2Buffer ) {
2520

2521
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533
				_gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );

				_gl.enableVertexAttribArray( attributes.uv2 );

			} else {

				_gl.disableVertexAttribArray( attributes.uv2 );

			}

		}

2534
		if ( material.skinning &&
2535
			 attributes.skinVertexA >= 0 && attributes.skinVertexB >= 0 &&
A
alteredq 已提交
2536
			 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
2537

2538
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
A
alteredq 已提交
2539 2540
			_gl.vertexAttribPointer( attributes.skinVertexA, 4, _gl.FLOAT, false, 0, 0 );

2541
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
A
alteredq 已提交
2542 2543
			_gl.vertexAttribPointer( attributes.skinVertexB, 4, _gl.FLOAT, false, 0, 0 );

2544
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
A
alteredq 已提交
2545 2546
			_gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 );

2547
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
A
alteredq 已提交
2548
			_gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 );
2549

A
alteredq 已提交
2550
		}
2551

2552
		// render mesh
M
Mr.doob 已提交
2553

2554
		if ( object instanceof THREE.Mesh ) {
2555

2556
			// wireframe
2557

2558
			if ( material.wireframe ) {
M
Mr.doob 已提交
2559

2560
				_gl.lineWidth( material.wireframeLinewidth );
2561 2562
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
				_gl.drawElements( _gl.LINES, geometryGroup.__webglLineCount, _gl.UNSIGNED_SHORT, 0 );
2563

2564
			// triangles
2565

2566
			} else {
2567

2568 2569 2570
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
				_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );

2571
			}
2572

2573
		// render lines
2574

2575
		} else if ( object instanceof THREE.Line ) {
2576

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

2579
			_gl.lineWidth( material.linewidth );
2580
			_gl.drawArrays( primitives, 0, geometryGroup.__webglLineCount );
2581

2582
		// render particles
2583

2584
		} else if ( object instanceof THREE.ParticleSystem ) {
2585

2586
			_gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webglParticleCount );
2587

A
alteredq 已提交
2588
		// render ribbon
2589

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

2592
			_gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webglVertexCount );
2593

2594 2595 2596 2597
		}

	};

M
Mikael Emtinger 已提交
2598

M
Mikael Emtinger 已提交
2599
	function setupMorphTargets( material, geometryGroup, object ) {
2600

M
Mikael Emtinger 已提交
2601
		// set base
2602

M
Mikael Emtinger 已提交
2603
		var attributes = material.program.attributes;
2604

2605
		if (  object.morphTargetBase !== - 1 ) {
2606 2607

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

M
Mikael Emtinger 已提交
2610
		} else {
2611 2612

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

M
Mikael Emtinger 已提交
2615
		}
2616

2617
		if ( object.morphTargetForcedOrder.length ) {
M
Mikael Emtinger 已提交
2618 2619

			// set forced order
2620

M
Mikael Emtinger 已提交
2621 2622 2623
			var m = 0;
			var order = object.morphTargetForcedOrder;
			var influences = object.morphTargetInfluences;
2624 2625 2626 2627

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

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

2630 2631 2632 2633
				object.__webglMorphTargetInfluences[ m ] = influences[ order[ m ]];

				m ++;
			}
2634

M
Mikael Emtinger 已提交
2635
		} else {
2636

M
Mikael Emtinger 已提交
2637
			// find most influencing
2638

M
Mikael Emtinger 已提交
2639
			var used = [];
2640
			var candidateInfluence = - 1;
M
Mikael Emtinger 已提交
2641 2642 2643 2644
			var candidate = 0;
			var influences = object.morphTargetInfluences;
			var i, il = influences.length;
			var m = 0;
2645

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

M
Mikael Emtinger 已提交
2648
				used[ object.morphTargetBase ] = true;
2649

M
Mikael Emtinger 已提交
2650
			}
2651 2652 2653

			while ( m < material.numSupportedMorphTargets ) {

2654
				for ( i = 0; i < il; i ++ ) {
2655 2656 2657

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

M
Mikael Emtinger 已提交
2658 2659
						candidate = i;
						candidateInfluence = influences[ candidate ];
2660

M
Mikael Emtinger 已提交
2661 2662
					}
				}
2663 2664

				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ candidate ] );
M
Mikael Emtinger 已提交
2665
				_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
2666 2667 2668

				object.__webglMorphTargetInfluences[ m ] = candidateInfluence;

M
Mikael Emtinger 已提交
2669 2670
				used[ candidate ] = 1;
				candidateInfluence = -1;
2671
				m ++;
M
Mikael Emtinger 已提交
2672 2673 2674 2675
			}
		}

		// load updated influences uniform
2676

2677
		_gl.uniform1fv( material.program.uniforms.morphTargetInfluences, object.__webglMorphTargetInfluences );
M
Mikael Emtinger 已提交
2678 2679 2680
	}


2681
	function renderBufferImmediate( object, program, shading ) {
2682

2683 2684
		if ( ! object.__webglVertexBuffer ) object.__webglVertexBuffer = _gl.createBuffer();
		if ( ! object.__webglNormalBuffer ) object.__webglNormalBuffer = _gl.createBuffer();
2685

A
alteredq 已提交
2686
		if ( object.hasPos ) {
2687

2688 2689 2690 2691
			_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 );
2692

A
alteredq 已提交
2693
		}
2694

A
alteredq 已提交
2695
		if ( object.hasNormal ) {
2696

2697
			_gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglNormalBuffer );
2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741

			if ( shading == THREE.FlatShading ) {

				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;

					normalArray[ i ] 	 = nx; 
					normalArray[ i + 1 ] = ny;
					normalArray[ i + 2 ] = nz;

					normalArray[ i + 3 ] = nx; 
					normalArray[ i + 4 ] = ny;
					normalArray[ i + 5 ] = nz;

					normalArray[ i + 6 ] = nx; 
					normalArray[ i + 7 ] = ny;
					normalArray[ i + 8 ] = nz;

				}

			}

2742 2743 2744
			_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 );
2745

A
alteredq 已提交
2746
		}
2747

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

A
alteredq 已提交
2750
		object.count = 0;
2751

A
alteredq 已提交
2752
	};
2753

2754
	function setObjectFaces( object ) {
2755

2756
		if ( _oldDoubleSided != object.doubleSided ) {
2757

2758
			if( object.doubleSided ) {
2759

2760
				_gl.disable( _gl.CULL_FACE );
2761

2762
			} else {
2763

A
alteredq 已提交
2764
				_gl.enable( _gl.CULL_FACE );
2765

A
alteredq 已提交
2766
			}
2767

2768
			_oldDoubleSided = object.doubleSided;
2769

2770
		}
2771

2772
		if ( _oldFlipSided != object.flipSided ) {
2773

2774 2775 2776 2777
			if( object.flipSided ) {

				_gl.frontFace( _gl.CW );

2778
			} else {
2779 2780 2781 2782

				_gl.frontFace( _gl.CCW );

			}
2783

2784
			_oldFlipSided = object.flipSided;
2785 2786

		}
2787

2788
	};
2789

2790
	function setDepthTest( test ) {
2791

A
alteredq 已提交
2792 2793 2794
		if ( _oldDepth != test ) {

			if( test ) {
2795

A
alteredq 已提交
2796
				_gl.enable( _gl.DEPTH_TEST );
2797

A
alteredq 已提交
2798
			} else {
2799

A
alteredq 已提交
2800
				_gl.disable( _gl.DEPTH_TEST );
2801

A
alteredq 已提交
2802
			}
2803

A
alteredq 已提交
2804 2805 2806
			_oldDepth = test;

		}
2807

A
alteredq 已提交
2808
	};
2809

2810
	function computeFrustum( m ) {
2811 2812 2813 2814 2815 2816 2817 2818 2819

		_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;
2820

A
alteredq 已提交
2821
		for ( i = 0; i < 6; i ++ ) {
2822 2823 2824 2825 2826 2827 2828

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

		}

	};
2829

2830
	function isInFrustum( object ) {
2831

2832
		var distance, matrix = object.matrixWorld,
2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844
		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;

	};
2845

2846
	function addToFixedArray( where, what ) {
2847

2848 2849
		where.list[ where.count ] = what;
		where.count += 1;
2850

2851
	};
2852

2853
	function unrollImmediateBufferMaterials( globject ) {
2854

2855 2856 2857 2858 2859 2860 2861
		var i, l, m, ml, material,
			object = globject.object,
			opaque = globject.opaque,
			transparent = globject.transparent;

		transparent.count = 0;
		opaque.count = 0;
2862

2863 2864 2865
		for ( m = 0, ml = object.materials.length; m < ml; m++ ) {

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

2868
		}
2869

2870
	};
2871

2872
	function unrollBufferMaterials( globject ) {
2873

2874 2875 2876 2877 2878 2879 2880 2881
		var i, l, m, ml, material, meshMaterial,
			object = globject.object,
			buffer = globject.buffer,
			opaque = globject.opaque,
			transparent = globject.transparent;

		transparent.count = 0;
		opaque.count = 0;
2882

2883 2884 2885 2886 2887 2888 2889 2890 2891
		for ( m = 0, ml = object.materials.length; m < ml; m++ ) {

			meshMaterial = object.materials[ m ];

			if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {

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

					material = buffer.materials[ i ];
2892
					if ( material ) material.transparent ? addToFixedArray( transparent, material ) : addToFixedArray( opaque, material );
2893 2894 2895 2896 2897 2898

				}

			} else {

				material = meshMaterial;
2899
				if ( material ) material.transparent ? addToFixedArray( transparent, material ) : addToFixedArray( opaque, material );
2900

2901 2902 2903
			}

		}
2904

2905
	};
2906 2907


2908
	function painterSort( a, b ) {
2909

2910
		return b.z - a.z;
2911 2912

	};
2913

2914
	this.render = function( scene, camera, renderTarget, forceClear ) {
2915

A
alteredq 已提交
2916
		var i, program, opaque, transparent, material,
2917
			o, ol, oil, webglObject, object, buffer,
A
alteredq 已提交
2918
			lights = scene.lights,
N
Nicholas Kinsey 已提交
2919
			fog = scene.fog;
2920

M
Mr.doob 已提交
2921
		camera.matrixAutoUpdate && camera.updateMatrix();
2922

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

M
Mr.doob 已提交
2925
		camera.matrixWorldInverse.flattenToArray( _viewMatrixArray );
2926
		camera.projectionMatrix.flattenToArray( _projectionMatrixArray );
M
Mr.doob 已提交
2927

M
Mr.doob 已提交
2928
		_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
2929
		computeFrustum( _projScreenMatrix );
2930

A
alteredq 已提交
2931
		this.initWebGLObjects( scene );
M
Mr.doob 已提交
2932

A
alteredq 已提交
2933
		setRenderTarget( renderTarget );
M
Mr.doob 已提交
2934

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

2937
			this.clear();
M
Mr.doob 已提交
2938

2939 2940
		}

2941
		// set matrices
2942

2943
		ol = scene.__webglObjects.length;
2944

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

2947 2948
			webglObject = scene.__webglObjects[ o ];
			object = webglObject.object;
M
Mr.doob 已提交
2949

2950
			if ( object.visible ) {
2951 2952

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

2954
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
2955

2956
					setupMatrices( object, camera );
2957

2958
					unrollBufferMaterials( webglObject );
2959

2960
					webglObject.render = true;
2961

2962
					if ( this.sortObjects ) {
2963

2964 2965 2966
						_vector3.copy( object.position );
						_projScreenMatrix.multiplyVector3( _vector3 );

2967
						webglObject.z = _vector3.z;
2968

2969
					}
2970

2971
				} else {
2972

2973
					webglObject.render = false;
2974

2975
				}
2976

2977
			} else {
2978

2979
				webglObject.render = false;
2980

2981
			}
2982

2983
		}
2984

2985
		if ( this.sortObjects ) {
2986

2987
			scene.__webglObjects.sort( painterSort );
2988

2989
		}
2990

2991
		oil = scene.__webglObjectsImmediate.length;
2992

2993
		for ( o = 0; o < oil; o++ ) {
2994

2995 2996
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
2997

2998
			if ( object.visible ) {
2999 3000 3001

				if( object.matrixAutoUpdate ) {

3002
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
3003

A
alteredq 已提交
3004
				}
3005

3006
				setupMatrices( object, camera );
3007

3008
				unrollImmediateBufferMaterials( webglObject );
3009

3010
			}
3011

3012
		}
A
alteredq 已提交
3013

3014 3015
		// opaque pass

3016
		setBlending( THREE.NormalBlending );
3017

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

3020
			webglObject = scene.__webglObjects[ o ];
3021

3022
			if ( webglObject.render ) {
3023

3024 3025 3026
				object = webglObject.object;
				buffer = webglObject.buffer;
				opaque = webglObject.opaque;
3027

3028
				setObjectFaces( object );
3029

3030
				for ( i = 0; i < opaque.count; i ++ ) {
3031

3032
					material = opaque.list[ i ];
3033

3034
					setDepthTest( material.depthTest );
A
alteredq 已提交
3035
					renderBuffer( camera, lights, fog, material, buffer, object );
3036

3037
				}
3038 3039 3040 3041 3042

			}

		}

A
alteredq 已提交
3043
		// opaque pass (immediate simulator)
3044

3045
		for ( o = 0; o < oil; o++ ) {
3046

3047 3048
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
3049

A
alteredq 已提交
3050
			if ( object.visible ) {
3051

3052
				opaque = webglObject.opaque;
3053

3054
				setObjectFaces( object );
3055

3056
				for( i = 0; i < opaque.count; i++ ) {
3057

3058
					material = opaque.list[ i ];
3059

3060
					setDepthTest( material.depthTest );
3061

A
alteredq 已提交
3062
					program = setProgram( camera, lights, fog, material, object );
3063
					object.render( function( object ) { renderBufferImmediate( object, program, material.shading ); } );
3064

3065
				}
3066

A
alteredq 已提交
3067
			}
3068

A
alteredq 已提交
3069 3070
		}

3071 3072
		// transparent pass

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

3075
			webglObject = scene.__webglObjects[ o ];
3076

3077
			if ( webglObject.render ) {
3078

3079 3080 3081
				object = webglObject.object;
				buffer = webglObject.buffer;
				transparent = webglObject.transparent;
3082

3083
				setObjectFaces( object );
3084

3085
				for ( i = 0; i < transparent.count; i ++ ) {
3086

3087
					material = transparent.list[ i ];
3088

3089
					setBlending( material.blending );
3090
					setDepthTest( material.depthTest );
3091

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

3094
				}
3095

3096
			}
M
Mr.doob 已提交
3097

M
Mr.doob 已提交
3098
		}
M
Mr.doob 已提交
3099

3100
		// transparent pass (immediate simulator)
3101

3102
		for ( o = 0; o < oil; o++ ) {
3103

3104 3105
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
3106

3107
			if ( object.visible ) {
3108

3109
				transparent = webglObject.transparent;
3110

3111
				setObjectFaces( object );
3112

3113
				for ( i = 0; i < transparent.count; i ++ ) {
3114

3115
					material = transparent.list[ i ];
3116

3117
					setBlending( material.blending );
3118
					setDepthTest( material.depthTest );
3119

A
alteredq 已提交
3120
					program = setProgram( camera, lights, fog, material, object );
3121
					object.render( function( object ) { renderBufferImmediate( object, program, material.shading ); } );
3122

3123
				}
3124

3125
			}
3126

3127
		}
3128

M
Mikael Emtinger 已提交
3129 3130 3131 3132 3133 3134 3135 3136
		// render 2d
		
		if ( scene.__webglSprites.length ) {
			
			renderSprites( scene );
			
		}

M
Mikael Emtinger 已提交
3137
		// render stencil shadows
M
Mikael Emtinger 已提交
3138

3139
		if ( stencil && scene.__webglShadowVolumes.length && scene.lights.length ) {
M
Mikael Emtinger 已提交
3140 3141

			renderStencilShadows( scene );
3142

M
Mikael Emtinger 已提交
3143 3144
		}

3145
		// render lens flares
3146 3147 3148

		if ( scene.__webglLensFlares.length ) {

3149
			renderLensFlares( scene, camera );
3150

3151 3152
		}

M
Mikael Emtinger 已提交
3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175

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

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

			updateRenderTargetMipmap( renderTarget );

		}

	};



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

	function renderStencilShadows( scene ) {
3176

M
Mikael Emtinger 已提交
3177 3178 3179 3180 3181
		// setup stencil

		_gl.enable( _gl.POLYGON_OFFSET_FILL );
		_gl.polygonOffset( 0.1, 1.0 );
		_gl.enable( _gl.STENCIL_TEST );
3182
		_gl.enable( _gl.DEPTH_TEST );
M
Mikael Emtinger 已提交
3183 3184
		_gl.depthMask( false );
		_gl.colorMask( false, false, false, false );
3185

M
Mikael Emtinger 已提交
3186 3187 3188 3189
		_gl.stencilFunc( _gl.ALWAYS, 1, 0xFF );
		_gl.stencilOpSeparate( _gl.BACK,  _gl.KEEP, _gl.INCR, _gl.KEEP );
		_gl.stencilOpSeparate( _gl.FRONT, _gl.KEEP, _gl.DECR, _gl.KEEP );

3190

M
Mikael Emtinger 已提交
3191
		// loop through all directional lights
3192

M
Mikael Emtinger 已提交
3193 3194
		var l, ll = scene.lights.length;
		var p;
M
Mikael Emtinger 已提交
3195
		var light, lights = scene.lights;
3196
		var dirLight = [];
M
Mikael Emtinger 已提交
3197
		var object, geometryGroup, material;
3198
		var program;
M
Mikael Emtinger 已提交
3199
		var p_uniforms;
3200 3201
		var m_uniforms;
		var attributes;
M
Mikael Emtinger 已提交
3202
		var o, ol = scene.__webglShadowVolumes.length;
3203 3204 3205

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

M
Mikael Emtinger 已提交
3206
			light = scene.lights[ l ];
3207 3208

			if ( light instanceof THREE.DirectionalLight ) {
M
Mikael Emtinger 已提交
3209 3210 3211 3212 3213 3214

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

				// render all volumes
3215 3216 3217

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

M
Mikael Emtinger 已提交
3218 3219 3220
					object        = scene.__webglShadowVolumes[ o ].object;
					geometryGroup = scene.__webglShadowVolumes[ o ].buffer;
					material      = object.materials[ 0 ];
3221

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

M
Mikael Emtinger 已提交
3224 3225
					program = material.program,
		  			p_uniforms = program.uniforms,
3226 3227
					m_uniforms = material.uniforms,
					attributes = program.attributes;
3228

3229
					if ( _currentProgram !== program ) {
3230

M
Mikael Emtinger 已提交
3231
						_gl.useProgram( program );
M
Mikael Emtinger 已提交
3232
						_currentProgram = program;
3233

M
Mikael Emtinger 已提交
3234 3235 3236 3237
						_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, _projectionMatrixArray );
						_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, _viewMatrixArray );
						_gl.uniform3fv( p_uniforms.directionalLightDirection, dirLight );
					}
3238 3239


M
Mikael Emtinger 已提交
3240 3241
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
					_gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object._objectMatrixArray );
3242 3243


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

M
Mikael Emtinger 已提交
3247
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
M
Mikael Emtinger 已提交
3248
					_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
3249

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

M
Mikael Emtinger 已提交
3252
					_gl.cullFace( _gl.FRONT );
M
Mikael Emtinger 已提交
3253
					_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );
3254

M
Mikael Emtinger 已提交
3255
					_gl.cullFace( _gl.BACK );
M
Mikael Emtinger 已提交
3256
					_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );
3257

M
Mikael Emtinger 已提交
3258
				}
M
Mikael Emtinger 已提交
3259

M
Mikael Emtinger 已提交
3260
			}
M
Mikael Emtinger 已提交
3261

M
Mikael Emtinger 已提交
3262 3263
		}

3264

M
Mikael Emtinger 已提交
3265
		// setup color+stencil
M
Mikael Emtinger 已提交
3266

M
Mikael Emtinger 已提交
3267 3268 3269 3270
		_gl.disable( _gl.POLYGON_OFFSET_FILL );
		_gl.colorMask( true, true, true, true );
		_gl.stencilFunc( _gl.NOTEQUAL, 0, 0xFF );
		_gl.stencilOp( _gl.KEEP, _gl.KEEP, _gl.KEEP );
3271
		_gl.disable( _gl.DEPTH_TEST );
M
Mikael Emtinger 已提交
3272 3273


3274
		// draw darkening polygon
M
Mr.doob 已提交
3275

M
Mikael Emtinger 已提交
3276
		_oldBlending = "";
M
Mikael Emtinger 已提交
3277
		_currentProgram = _stencilShadow.program;
M
Mr.doob 已提交
3278

M
Mikael Emtinger 已提交
3279 3280 3281
		_gl.useProgram( _stencilShadow.program );
		_gl.uniformMatrix4fv( _stencilShadow.projectionLocation, false, _projectionMatrixArray );
		_gl.uniform1f( _stencilShadow.darknessLocation, _stencilShadow.darkness );
3282

M
Mikael Emtinger 已提交
3283 3284 3285
		_gl.bindBuffer( _gl.ARRAY_BUFFER, _stencilShadow.vertexBuffer );
		_gl.vertexAttribPointer( _stencilShadow.vertexLocation, 3, _gl.FLOAT, false, 0, 0 );
		_gl.enableVertexAttribArray( _stencilShadow.vertexLocation );
M
Mr.doob 已提交
3286

M
Mikael Emtinger 已提交
3287 3288
		_gl.blendFunc( _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
		_gl.blendEquation( _gl.FUNC_ADD );
3289

M
Mikael Emtinger 已提交
3290
		_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _stencilShadow.elementBuffer );
M
Mikael Emtinger 已提交
3291 3292 3293 3294 3295
		_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );


		// disable stencil

3296 3297 3298 3299
		_gl.disable( _gl.STENCIL_TEST );
		_gl.enable( _gl.DEPTH_TEST );
		_gl.depthMask( _currentDepthMask );

M
Mikael Emtinger 已提交
3300
	}
3301

3302

3303 3304 3305 3306 3307 3308 3309 3310 3311 3312
	/*
	 * Render lens flares
	 * Method: renders 16x16 0xff00ff-colored points scattered over the light source area, 
	 *         reads these back and calculates occlusion.  
	 *         Then LensFlare.updateLensFlares() is called to re-position and 
	 *         update transparency of flares. Then they are rendered.
	 * 
	 */

	function renderLensFlares( scene, camera ) {
3313

3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335
		var object, objectZ, geometryGroup, material;
		var o, ol = scene.__webglLensFlares.length;
		var f, fl, flare;
		var tempPosition = new THREE.Vector3();
		var invAspect = _viewportHeight / _viewportWidth;
		var halfViewportWidth = _viewportWidth * 0.5;
		var halfViewportHeight = _viewportHeight * 0.5;
		var size = 16 / _viewportHeight;
		var scale = [ size * invAspect, size ];
		var screenPosition = [ 1, 1, 0 ];
		var screenPositionPixels = [ 1, 1 ];
		var sampleX, sampleY, readBackPixels = _lensFlare.readBackPixels;
		var sampleMidX = 7 * 4;
		var sampleMidY = 7 * 16 * 4;
		var sampleIndex, visibility;
		var uniforms = _lensFlare.uniforms;
		var attributes = _lensFlare.attributes;


		// set lensflare program and reset blending

		_gl.useProgram( _lensFlare.program );
M
Mikael Emtinger 已提交
3336
		_currentProgram = _lensFlare.program;
3337 3338 3339 3340 3341 3342
		_oldBlending = "";


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

3343 3344
		_gl.uniform1i( uniforms.occlusionMap, 0 );
		_gl.uniform1i( uniforms.map, 1 );
3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355

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


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

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

3356 3357 3358 3359
		_gl.activeTexture( _gl.TEXTURE0 );
		_gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.occlusionTexture );

		_gl.activeTexture( _gl.TEXTURE1 );
3360

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

3363
			// calc object screen position
3364

3365
			object = scene.__webglLensFlares[ o ].object;
3366

3367
			tempPosition.set( object.matrixWorld.n14, object.matrixWorld.n24, object.matrixWorld.n34 );
3368

3369 3370 3371
			camera.matrixWorldInverse.multiplyVector3( tempPosition );
			objectZ = tempPosition.z;
			camera.projectionMatrix.multiplyVector3( tempPosition );
3372 3373


3374
			// setup arrays for gl programs
3375

3376 3377 3378
			screenPosition[ 0 ] = tempPosition.x;
			screenPosition[ 1 ] = tempPosition.y;
			screenPosition[ 2 ] = tempPosition.z;
3379

3380 3381
			screenPositionPixels[ 0 ] = screenPosition[ 0 ] * halfViewportWidth + halfViewportWidth;
			screenPositionPixels[ 1 ] = screenPosition[ 1 ] * halfViewportHeight + halfViewportHeight;
3382

3383

M
Mikael Emtinger 已提交
3384
			// screen cull 
3385
			
M
Mikael Emtinger 已提交
3386
			if(	screenPositionPixels[ 0 ] > 0 &&
3387 3388
				screenPositionPixels[ 0 ] < _viewportWidth &&
				screenPositionPixels[ 1 ] > 0 &&
M
Mikael Emtinger 已提交
3389
				screenPositionPixels[ 1 ] < _viewportHeight ) {
3390 3391


3392 3393 3394 3395
				// save current RGB to temp texture
	
				_gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.tempTexture );
				_gl.copyTexSubImage2D( _gl.TEXTURE_2D, 0, 0, 0, screenPositionPixels[ 0 ] - 8, screenPositionPixels[ 1 ] - 8, 16, 16 );
M
Mikael Emtinger 已提交
3396 3397
				_gl.finish();

3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408
	
				// render pink quad
	
				_gl.uniform1i( uniforms.renderType, 0 );
				_gl.uniform2fv( uniforms.scale, scale );
				_gl.uniform3fv( uniforms.screenPosition, screenPosition );
	
				_gl.disable( _gl.BLEND );
				_gl.enable( _gl.DEPTH_TEST );
	
				_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
M
Mikael Emtinger 已提交
3409
				_gl.finish();
3410 3411 3412 3413 3414 3415
	
	
				// copy result to occlusionMap
	
				_gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.occlusionTexture );
				_gl.copyTexSubImage2D( _gl.TEXTURE_2D, 0, 0, 0, screenPositionPixels[ 0 ] - 8, screenPositionPixels[ 1 ] - 8, 16, 16 );
M
Mikael Emtinger 已提交
3416
				_gl.finish();
3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440
	
	
				// restore graphics
	
				_gl.uniform1i( uniforms.renderType, 1 );
				_gl.disable( _gl.DEPTH_TEST );
				_gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.tempTexture );
				_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
	
	
				// update object positions
	
				object.positionScreen.x = screenPosition[ 0 ];
				object.positionScreen.y = screenPosition[ 1 ];
				object.positionScreen.z = screenPosition[ 2 ];
	
				if ( object.customUpdateCallback ) {
	
					object.customUpdateCallback( object );
	
				} else {
	
					object.updateLensFlares();
	
3441
				}
3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476
	
	
				// render flares
	
				_gl.uniform1i( uniforms.renderType, 2 );
				_gl.enable( _gl.BLEND );
				
				for ( f = 0, fl = object.lensFlares.length; f < fl; f ++ ) {
	
					flare = object.lensFlares[ f ];
	
					if ( flare.opacity > 0.001 && flare.scale > 0.001 ) {
	
						screenPosition[ 0 ] = flare.x;
						screenPosition[ 1 ] = flare.y;
						screenPosition[ 2 ] = flare.z;
	
						size = flare.size * flare.scale / _viewportHeight;
						scale[ 0 ] = size * invAspect;
						scale[ 1 ] = size;
	
						_gl.uniform3fv( uniforms.screenPosition, screenPosition );
						_gl.uniform2fv( uniforms.scale, scale );
						_gl.uniform1f( uniforms.rotation, flare.rotation );
						_gl.uniform1f( uniforms.opacity, flare.opacity );
	
						setBlending( flare.blending );
						setTexture( flare.texture, 1 );
	
						_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
	
					}
	
				}
			
3477
			}
M
Mr.doob 已提交
3478

3479 3480 3481
		}

		// restore gl
3482

3483 3484
		_gl.enable( _gl.CULL_FACE );
		_gl.enable( _gl.DEPTH_TEST );
3485
		_gl.depthMask( _currentDepthMask );
3486

3487
	}
3488

M
Mr.doob 已提交
3489

3490 3491


3492
	function setupMatrices( object, camera ) {
3493

3494 3495
		object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
		THREE.Matrix4.makeInvert3x3( object._modelViewMatrix ).transposeIntoArray( object._normalMatrixArray );
3496

3497
	}
3498

A
alteredq 已提交
3499
	this.initWebGLObjects = function ( scene ) {
3500

3501
		if ( !scene.__webglObjects ) {
3502

3503 3504
			scene.__webglObjects = [];
			scene.__webglObjectsImmediate = [];
M
Mikael Emtinger 已提交
3505
			scene.__webglShadowVolumes = [];
M
Mikael Emtinger 已提交
3506
			scene.__webglLensFlares = [];
M
Mikael Emtinger 已提交
3507
			scene.__webglSprites = [];
3508 3509
		}

M
Mr.doob 已提交
3510
		while ( scene.__objectsAdded.length ) {
3511

M
Mr.doob 已提交
3512 3513
			addObject( scene.__objectsAdded[ 0 ], scene );
			scene.__objectsAdded.splice( 0, 1 );
3514 3515 3516

		}

M
Mr.doob 已提交
3517
		while ( scene.__objectsRemoved.length ) {
3518

M
Mr.doob 已提交
3519 3520
			removeObject( scene.__objectsRemoved[ 0 ], scene );
			scene.__objectsRemoved.splice( 0, 1 );
3521 3522

		}
3523

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

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

M
Mr.doob 已提交
3528
			updateObject( scene.__webglObjects[ o ].object, scene );
A
alteredq 已提交
3529 3530

		}
3531

M
Mikael Emtinger 已提交
3532 3533 3534 3535 3536
		for ( var o = 0, ol = scene.__webglShadowVolumes.length; o < ol; o ++ ) {

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

		}
3537

M
Mikael Emtinger 已提交
3538 3539 3540 3541 3542
		for ( var o = 0, ol = scene.__webglLensFlares.length; o < ol; o ++ ) {

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

		}
A
alteredq 已提交
3543

M
Mikael Emtinger 已提交
3544 3545 3546 3547 3548 3549
		for ( var o = 0, ol = scene.__webglSprites.length; o < ol; o ++ ) {

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

		}

3550
	};
3551

3552
	function addObject( object, scene ) {
3553

3554
		var g, geometry, geometryGroup;
M
Mr.doob 已提交
3555

3556
		if ( object._modelViewMatrix == undefined ) {
3557

3558
			object._modelViewMatrix = new THREE.Matrix4();
3559

3560 3561 3562
			object._normalMatrixArray = new Float32Array( 9 );
			object._modelViewMatrixArray = new Float32Array( 16 );
			object._objectMatrixArray = new Float32Array( 16 );
3563

3564
			object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
3565

3566
		}
A
alteredq 已提交
3567

3568
		if ( object instanceof THREE.Mesh ) {
A
alteredq 已提交
3569

3570 3571 3572 3573 3574 3575 3576 3577
			geometry = object.geometry;

			if ( geometry.geometryGroups == undefined ) {

				sortFacesByMaterial( geometry );

			}

3578
			// create separate VBOs per geometry chunk
A
alteredq 已提交
3579

3580
			for ( g in geometry.geometryGroups ) {
A
alteredq 已提交
3581

3582
				geometryGroup = geometry.geometryGroups[ g ];
M
Mr.doob 已提交
3583

3584
				// initialise VBO on the first access
M
Mr.doob 已提交
3585

3586
				if ( ! geometryGroup.__webglVertexBuffer ) {
M
Mr.doob 已提交
3587

3588 3589
					createMeshBuffers( geometryGroup );
					initMeshBuffers( geometryGroup, object );
A
alteredq 已提交
3590

3591
					geometry.__dirtyVertices = true;
3592
					geometry.__dirtyMorphTargets = true;
3593 3594 3595 3596 3597
					geometry.__dirtyElements = true;
					geometry.__dirtyUvs = true;
					geometry.__dirtyNormals = true;
					geometry.__dirtyTangents = true;
					geometry.__dirtyColors = true;
M
Mr.doob 已提交
3598

3599
				}
3600

3601
				// create separate wrapper per each use of VBO
3602

3603 3604
				if ( object instanceof THREE.ShadowVolume ) {

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

M
Mikael Emtinger 已提交
3607
				} else {
3608

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

M
Mikael Emtinger 已提交
3611
				}
3612

3613
			}
M
Mr.doob 已提交
3614

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

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

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

3621 3622
			geometry = object.geometry;

3623
			if( ! geometry.__webglVertexBuffer ) {
A
alteredq 已提交
3624 3625 3626 3627 3628 3629 3630 3631 3632

				createRibbonBuffers( geometry );
				initRibbonBuffers( geometry );

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

			}

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

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

3637 3638
			geometry = object.geometry;

3639
			if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
3640

3641 3642
				createLineBuffers( geometry );
				initLineBuffers( geometry );
M
Mr.doob 已提交
3643

3644 3645
				geometry.__dirtyVertices = true;
				geometry.__dirtyColors = true;
M
Mr.doob 已提交
3646

3647
			}
M
Mr.doob 已提交
3648

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

A
alteredq 已提交
3651 3652 3653 3654
		} else if ( object instanceof THREE.ParticleSystem ) {

			geometry = object.geometry;

3655
			if ( ! geometry.__webglVertexBuffer ) {
A
alteredq 已提交
3656 3657 3658 3659 3660 3661

				createParticleBuffers( geometry );
				initParticleBuffers( geometry );

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

3663
			}
3664

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

A
alteredq 已提交
3667 3668 3669 3670 3671 3672 3673 3674 3675 3676
		} else if ( THREE.MarchingCubes !== undefined && object instanceof THREE.MarchingCubes ) {

			addBufferImmediate( scene.__webglObjectsImmediate, object );

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

		}*/

	};

3677
	function updateObject( object, scene ) {
A
alteredq 已提交
3678

3679
		var g, geometry, geometryGroup, a, customAttributeDirty;
A
alteredq 已提交
3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690

		if ( object instanceof THREE.Mesh ) {

			geometry = object.geometry;

			// check all geometry groups

			for ( g in geometry.geometryGroups ) {

				geometryGroup = geometry.geometryGroups[ g ];

3691 3692
				customAttributeDirty = false;

M
Mr.doob 已提交
3693 3694 3695 3696
				for ( a in geometryGroup.__webglCustomAttributes ) {

					if( geometryGroup.__webglCustomAttributes[ a ].needsUpdate ) {

3697 3698 3699
						customAttributeDirty = true;
						break;
					}
M
Mr.doob 已提交
3700

3701 3702
				}

3703
				if ( geometry.__dirtyVertices || geometry.__dirtyMorphTargets || geometry.__dirtyElements ||
A
alteredq 已提交
3704
					geometry.__dirtyUvs || geometry.__dirtyNormals ||
3705
					geometry.__dirtyColors || geometry.__dirtyTangents || customAttributeDirty ) {
A
alteredq 已提交
3706 3707 3708 3709 3710 3711 3712

					setMeshBuffers( geometryGroup, object, _gl.DYNAMIC_DRAW );

				}

			}

3713
			geometry.__dirtyVertices = false;
3714
			geometry.__dirtyMorphTargets = false;
A
alteredq 已提交
3715 3716 3717 3718
			geometry.__dirtyElements = false;
			geometry.__dirtyUvs = false;
			geometry.__dirtyNormals = false;
			geometry.__dirtyTangents = false;
3719
			geometry.__dirtyColors = false;
M
Mr.doob 已提交
3720

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

3723 3724
			geometry = object.geometry;

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

A
alteredq 已提交
3727
				setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
3728

A
alteredq 已提交
3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740
			}

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

		} else if ( object instanceof THREE.Line ) {

			geometry = object.geometry;

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

				setLineBuffers( geometry, _gl.DYNAMIC_DRAW );
3741

3742
			}
3743

A
alteredq 已提交
3744 3745 3746 3747 3748 3749 3750
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;

		} else if ( object instanceof THREE.ParticleSystem ) {

			geometry = object.geometry;

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

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

3755
			}
M
Mr.doob 已提交
3756

3757 3758
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
M
Mr.doob 已提交
3759

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

A
alteredq 已提交
3762
			// it updates itself in render callback
3763 3764

		} else if ( object instanceof THREE.Particle ) {
3765 3766

		}*/
3767

3768
	};
3769

3770
	function removeObject( object, scene ) {
M
Mr.doob 已提交
3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787

		var o, ol, zobject;

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

			zobject = scene.__webglObjects[ o ].object;

			if ( object == zobject ) {

				scene.__webglObjects.splice( o, 1 );

			}

		}

	};

3788
	function sortFacesByMaterial( geometry ) {
3789 3790 3791 3792 3793 3794 3795

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

		var i, l, f, fl, face, material, materials, vertices, mhash, ghash, hash_map = {};
3796
		var numMorphTargets = geometry.morphTargets !== undefined ? geometry.morphTargets.length : 0;
3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838

		geometry.geometryGroups = {};

		function materialHash( material ) {

			var hash_array = [];

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

				if ( material[ i ] == undefined ) {

					hash_array.push( "undefined" );

				} else {

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

				}

			}

			return hash_array.join( '_' );

		}

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

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

			mhash = materialHash( materials );

			if ( hash_map[ mhash ] == undefined ) {

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

			}

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

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

3839
				geometry.geometryGroups[ ghash ] = { 'faces': [], 'materials': materials, 'vertices': 0, 'numMorphTargets': numMorphTargets };
3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851

			}

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

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

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

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

3852
					geometry.geometryGroups[ ghash ] = { 'faces': [], 'materials': materials, 'vertices': 0, 'numMorphTargets': numMorphTargets };
3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864

				}

			}

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

		}

	};

3865
	function addBuffer( objlist, buffer, object ) {
3866

3867 3868 3869 3870 3871
		objlist.push( {
			buffer: buffer, object: object,
			opaque: { list: [], count: 0 },
			transparent: { list: [], count: 0 }
		} );
M
Mr.doob 已提交
3872

3873
	};
3874

3875
	function addBufferImmediate( objlist, object ) {
3876

3877 3878 3879 3880 3881
		objlist.push( {
			object: object,
			opaque: { list: [], count: 0 },
			transparent: { list: [], count: 0 }
		} );
3882

3883
	};
3884

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

3887
		if ( cullFace ) {
M
Mr.doob 已提交
3888

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

3891
				_gl.frontFace( _gl.CCW );
M
Mr.doob 已提交
3892

3893
			} else {
M
Mr.doob 已提交
3894

3895
				_gl.frontFace( _gl.CW );
M
Mr.doob 已提交
3896

3897
			}
M
Mr.doob 已提交
3898

3899
			if( cullFace == "back" ) {
M
Mr.doob 已提交
3900

3901
				_gl.cullFace( _gl.BACK );
M
Mr.doob 已提交
3902

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

3905
				_gl.cullFace( _gl.FRONT );
M
Mr.doob 已提交
3906

3907
			} else {
M
Mr.doob 已提交
3908

3909
				_gl.cullFace( _gl.FRONT_AND_BACK );
M
Mr.doob 已提交
3910

3911
			}
M
Mr.doob 已提交
3912

3913
			_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
3914

3915
		} else {
M
Mr.doob 已提交
3916

3917
			_gl.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
3918

3919 3920 3921
		}

	};
N
Nicolas Garcia Belmonte 已提交
3922

3923
	this.supportsVertexTextures = function () {
3924

3925
		return maxVertexTextures() > 0;
3926

3927
	};
3928

3929
	function maxVertexTextures() {
3930

3931 3932 3933
		return _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );

	};
3934

3935
	function initGL( antialias, clearColor, clearAlpha, stencil ) {
N
Nicolas Garcia Belmonte 已提交
3936 3937 3938

		try {

M
Mikael Emtinger 已提交
3939
			if ( ! ( _gl = _canvas.getContext( 'experimental-webgl', { antialias: antialias, stencil: stencil } ) ) ) {
N
Nicolas Garcia Belmonte 已提交
3940

3941
				throw 'Error creating WebGL context.';
N
Nicolas Garcia Belmonte 已提交
3942

3943 3944 3945
			}

		} catch ( e ) {
N
Nicolas Garcia Belmonte 已提交
3946

3947
			console.error( e );
N
Nicolas Garcia Belmonte 已提交
3948 3949 3950 3951 3952 3953 3954 3955 3956

		}

		_gl.clearColor( 0, 0, 0, 1 );
		_gl.clearDepth( 1 );

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

3957 3958
		_gl.frontFace( _gl.CCW );
		_gl.cullFace( _gl.BACK );
3959
		_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
3960

N
Nicolas Garcia Belmonte 已提交
3961
		_gl.enable( _gl.BLEND );
3962 3963 3964
		_gl.blendEquation( _gl.FUNC_ADD );
		_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA );

3965
		_gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearAlpha );
3966

3967 3968
		// _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, true );

A
alteredq 已提交
3969
		_cullEnabled = true;
N
Nicolas Garcia Belmonte 已提交
3970

3971
	};
M
Mr.doob 已提交
3972

3973
	function buildProgram( shaderID, fragmentShader, vertexShader, uniforms, attributes, parameters ) {
3974

3975
		var p, pl, program, code;
3976
		var chunks = [];
3977 3978 3979

		// Generate code

3980 3981 3982 3983 3984 3985 3986 3987 3988 3989
		if ( shaderID ) {

			chunks.push( shaderID );

		} else {

			chunks.push( fragmentShader );
			chunks.push( vertexShader );

		}
3990 3991 3992

		for ( p in parameters ) {

3993 3994
			chunks.push( p );
			chunks.push( parameters[ p ] );
3995 3996 3997

		}

3998 3999
		code = chunks.join();

4000 4001 4002 4003 4004 4005 4006
		// Check if code has been already compiled

		for ( p = 0, pl = _programs.length; p < pl; p ++ ) {

			if ( _programs[ p ].code == code ) {

				// console.log( "Code already compiled." /*: \n\n" + code*/ );
4007

4008 4009 4010 4011 4012
				return _programs[ p ].program;

			}

		}
4013 4014
		
		//console.log( "building new program " );
4015 4016 4017 4018

		//

		program = _gl.createProgram(),
M
Mr.doob 已提交
4019

M
Mr.doob 已提交
4020 4021 4022 4023
		prefix_fragment = [
			"#ifdef GL_ES",
			"precision highp float;",
			"#endif",
M
Mr.doob 已提交
4024

4025 4026
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
A
alteredq 已提交
4027

4028 4029
			parameters.fog ? "#define USE_FOG" : "",
			parameters.fog instanceof THREE.FogExp2 ? "#define FOG_EXP2" : "",
4030

4031
			parameters.map ? "#define USE_MAP" : "",
4032 4033 4034
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
4035

4036
			"uniform mat4 viewMatrix;",
4037
			"uniform vec3 cameraPosition;",
M
Mr.doob 已提交
4038 4039
			""
		].join("\n"),
4040

M
Mr.doob 已提交
4041
		prefix_vertex = [
4042
			maxVertexTextures() > 0 ? "#define VERTEX_TEXTURES" : "",
4043

4044 4045 4046
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

4047 4048
			"#define MAX_BONES " + parameters.maxBones,

4049
			parameters.map ? "#define USE_MAP" : "",
4050 4051 4052
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
4053
			parameters.skinning ? "#define USE_SKINNING" : "",
4054
			parameters.morphTargets ? "#define USE_MORPHTARGETS" : "",
4055

4056

4057 4058
			parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",

M
Mr.doob 已提交
4059 4060 4061
			"uniform mat4 objectMatrix;",
			"uniform mat4 modelViewMatrix;",
			"uniform mat4 projectionMatrix;",
4062 4063
			"uniform mat4 viewMatrix;",
			"uniform mat3 normalMatrix;",
M
Mr.doob 已提交
4064
			"uniform vec3 cameraPosition;",
A
alteredq 已提交
4065 4066 4067

			"uniform mat4 cameraInverseMatrix;",

M
Mr.doob 已提交
4068 4069 4070
			"attribute vec3 position;",
			"attribute vec3 normal;",
			"attribute vec2 uv;",
4071
			"attribute vec2 uv2;",
4072

4073
			"#ifdef USE_COLOR",
4074

4075
				"attribute vec3 color;",
4076

4077 4078
			"#endif",

4079
			"#ifdef USE_MORPHTARGETS",
4080

4081 4082 4083 4084 4085 4086 4087 4088
				"attribute vec3 morphTarget0;",
				"attribute vec3 morphTarget1;",
				"attribute vec3 morphTarget2;",
				"attribute vec3 morphTarget3;",
				"attribute vec3 morphTarget4;",
				"attribute vec3 morphTarget5;",
				"attribute vec3 morphTarget6;",
				"attribute vec3 morphTarget7;",
4089

4090 4091 4092
			"#endif",

			"#ifdef USE_SKINNING",
4093

4094 4095 4096 4097
				"attribute vec4 skinVertexA;",
				"attribute vec4 skinVertexB;",
				"attribute vec4 skinIndex;",
				"attribute vec4 skinWeight;",
4098

4099
			"#endif",
4100

M
Mr.doob 已提交
4101 4102
			""
		].join("\n");
4103

4104 4105
		_gl.attachShader( program, getShader( "fragment", prefix_fragment + fragmentShader ) );
		_gl.attachShader( program, getShader( "vertex", prefix_vertex + vertexShader ) );
M
Mr.doob 已提交
4106

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

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

4111
			console.error( "Could not initialise shader\n" + "VALIDATE_STATUS: " + _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) + ", gl error [" + _gl.getError() + "]" );
M
Mr.doob 已提交
4112

N
Nicolas Garcia Belmonte 已提交
4113
		}
4114

4115 4116
		//console.log( prefix_fragment + fragmentShader );
		//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
4117

M
Mr.doob 已提交
4118
		program.uniforms = {};
4119
		program.attributes = {};
M
Mr.doob 已提交
4120

4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162
		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 );
		
		// cache attributes locations

		identifiers = [

			"position", "normal", "uv", "uv2", "tangent", "color",
			"skinVertexA", "skinVertexB", "skinIndex", "skinWeight"

		];

		for ( i = 0; i < parameters.maxMorphTargets; i++ ) {

			identifiers.push( "morphTarget" + i );

		}

		for ( a in attributes ) {

			identifiers.push( a );

		}

		cacheAttributeLocations( program, identifiers );

4163 4164
		_programs.push( { program: program, code: code } );

M
Mr.doob 已提交
4165
		return program;
M
Mr.doob 已提交
4166

M
Mr.doob 已提交
4167
	};
M
Mr.doob 已提交
4168

4169
	function loadUniformsSkinning( uniforms, object ) {
4170

M
Mr.doob 已提交
4171
		_gl.uniformMatrix4fv( uniforms.cameraInverseMatrix, false, _viewMatrixArray );
A
alteredq 已提交
4172
		_gl.uniformMatrix4fv( uniforms.boneGlobalMatrices, false, object.boneMatrices );
4173

4174
	};
4175

4176

4177
	function loadUniformsMatrices( uniforms, object ) {
4178

A
alteredq 已提交
4179 4180 4181 4182
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray );
		_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrixArray );

	};
4183

4184
	function loadUniformsGeneric( program, uniforms ) {
M
Mr.doob 已提交
4185

4186
		var u, uniform, value, type, location, texture;
M
Mr.doob 已提交
4187

M
Mr.doob 已提交
4188
		for( u in uniforms ) {
M
Mr.doob 已提交
4189

4190 4191
			location = program.uniforms[u];
			if ( !location ) continue;
M
Mr.doob 已提交
4192

4193
			uniform = uniforms[u];
M
Mr.doob 已提交
4194

4195 4196
			type = uniform.type;
			value = uniform.value;
M
Mr.doob 已提交
4197

M
Mr.doob 已提交
4198
			if( type == "i" ) {
M
Mr.doob 已提交
4199

M
Mr.doob 已提交
4200
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
4201

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

M
Mr.doob 已提交
4204
				_gl.uniform1f( location, value );
4205

A
alteredq 已提交
4206 4207 4208
			} else if( type == "fv1" ) {

				_gl.uniform1fv( location, value );
M
Mr.doob 已提交
4209

4210 4211 4212 4213
			} else if( type == "fv" ) {

				_gl.uniform3fv( location, value );

4214 4215 4216 4217
			} else if( type == "v2" ) {

				_gl.uniform2f( location, value.x, value.y );

4218 4219 4220
			} else if( type == "v3" ) {

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

4222 4223 4224 4225
			} else if( type == "v4" ) {

				_gl.uniform4f( location, value.x, value.y, value.z, value.w );

4226 4227 4228
			} else if( type == "c" ) {

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

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

M
Mr.doob 已提交
4232
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
4233

4234
				texture = uniform.texture;
M
Mr.doob 已提交
4235

4236
				if ( !texture ) continue;
M
Mr.doob 已提交
4237

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

4240
					setCubeTexture( texture, value );
M
Mr.doob 已提交
4241

4242
				} else {
M
Mr.doob 已提交
4243

4244
					setTexture( texture, value );
M
Mr.doob 已提交
4245

4246
				}
M
Mr.doob 已提交
4247

4248
			}
M
Mr.doob 已提交
4249

4250
		}
M
Mr.doob 已提交
4251

4252
	};
M
Mr.doob 已提交
4253

4254
	function setBlending( blending ) {
A
alteredq 已提交
4255 4256

		if ( blending != _oldBlending ) {
4257

A
alteredq 已提交
4258 4259 4260 4261 4262
			switch ( blending ) {

				case THREE.AdditiveBlending:

					_gl.blendEquation( _gl.FUNC_ADD );
4263
					_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE );
A
alteredq 已提交
4264 4265 4266 4267 4268

					break;

				case THREE.SubtractiveBlending:

4269 4270 4271 4272
					// TODO: Find blendFuncSeparate() combination

					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.ZERO, _gl.ONE_MINUS_SRC_COLOR );
A
alteredq 已提交
4273 4274 4275

					break;

4276 4277 4278
				case THREE.MultiplyBlending:

					// TODO: Find blendFuncSeparate() combination
A
alteredq 已提交
4279 4280

					_gl.blendEquation( _gl.FUNC_ADD );
4281
					_gl.blendFunc( _gl.ZERO, _gl.SRC_COLOR );
A
alteredq 已提交
4282 4283 4284 4285 4286

					break;

				default:

4287 4288
					_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 已提交
4289 4290

					break;
4291

A
alteredq 已提交
4292
			}
4293

A
alteredq 已提交
4294
			_oldBlending = blending;
4295

A
alteredq 已提交
4296 4297 4298
		}

	};
4299

4300
	function setTextureParameters( textureType, texture, image ) {
4301

4302
		if ( isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ) ) {
M
Mr.doob 已提交
4303

4304 4305
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
M
Mr.doob 已提交
4306

4307 4308
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
M
Mr.doob 已提交
4309

4310
			_gl.generateMipmap( textureType );
M
Mr.doob 已提交
4311

4312
		} else {
M
Mr.doob 已提交
4313

4314 4315
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
4316

4317 4318
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
M
Mr.doob 已提交
4319

4320
		}
M
Mr.doob 已提交
4321

4322
	};
4323

4324
	function setTexture( texture, slot ) {
4325

4326
		if ( texture.needsUpdate ) {
A
alteredq 已提交
4327

4328
			if ( !texture.__webglInit ) {
M
Mr.doob 已提交
4329

4330
				texture.__webglTexture = _gl.createTexture();
A
alteredq 已提交
4331

4332
				_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
4333
				_gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image );
M
Mr.doob 已提交
4334

4335
				texture.__webglInit = true;
M
Mr.doob 已提交
4336

A
alteredq 已提交
4337
			} else {
M
Mr.doob 已提交
4338

4339
				_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
A
alteredq 已提交
4340
				_gl.texSubImage2D( _gl.TEXTURE_2D, 0, 0, 0, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image );
M
Mr.doob 已提交
4341 4342 4343

			}

4344 4345
			setTextureParameters( _gl.TEXTURE_2D, texture, texture.image );
			_gl.bindTexture( _gl.TEXTURE_2D, null );
4346

A
alteredq 已提交
4347
			texture.needsUpdate = false;
4348 4349 4350 4351

		}

		_gl.activeTexture( _gl.TEXTURE0 + slot );
4352
		_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
M
Mr.doob 已提交
4353

4354
	};
M
Mr.doob 已提交
4355

4356
	function setCubeTexture( texture, slot ) {
4357 4358 4359 4360 4361

		if ( texture.image.length == 6 ) {

			if ( texture.needsUpdate ) {

4362 4363 4364
				if ( !texture.__webglInit ) {

					texture.image.__webglTextureCube = _gl.createTexture();
4365

4366
					_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
4367

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

4370
						_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image[ i ] );
4371

4372
					}
4373 4374

					texture.__webglInit = true;
4375 4376 4377

				} else {

4378
					_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
4379

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

4382
						_gl.texSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image[ i ] );
4383

4384
					}
4385 4386 4387

				}

4388
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, texture.image[0] );
4389 4390 4391
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );

				texture.needsUpdate = false;
4392

4393 4394 4395
			}

			_gl.activeTexture( _gl.TEXTURE0 + slot );
4396
			_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
4397 4398 4399 4400 4401

		}

	};

4402
	function setRenderTarget( renderTexture ) {
4403

4404
		if ( renderTexture && !renderTexture.__webglFramebuffer ) {
M
Mr.doob 已提交
4405

M
Mikael Emtinger 已提交
4406 4407 4408
			if( renderTexture.depthBuffer === undefined ) renderTexture.depthBuffer = true;
			if( renderTexture.stencilBuffer === undefined ) renderTexture.stencilBuffer = true;

4409 4410 4411
			renderTexture.__webglFramebuffer = _gl.createFramebuffer();
			renderTexture.__webglRenderbuffer = _gl.createRenderbuffer();
			renderTexture.__webglTexture = _gl.createTexture();
4412 4413 4414


			// Setup texture
M
Mr.doob 已提交
4415

4416
			_gl.bindTexture( _gl.TEXTURE_2D, renderTexture.__webglTexture );
4417 4418 4419 4420
			_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, paramThreeToGL( renderTexture.wrapS ) );
			_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, paramThreeToGL( renderTexture.wrapT ) );
			_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( renderTexture.magFilter ) );
			_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( renderTexture.minFilter ) );
4421
			_gl.texImage2D( _gl.TEXTURE_2D, 0, paramThreeToGL( renderTexture.format ), renderTexture.width, renderTexture.height, 0, paramThreeToGL( renderTexture.format ), paramThreeToGL( renderTexture.type ), null );
4422

M
Mikael Emtinger 已提交
4423
			// Setup render and frame buffer
M
Mr.doob 已提交
4424

M
Mikael Emtinger 已提交
4425
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderTexture.__webglRenderbuffer );
4426
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTexture.__webglFramebuffer );
M
Mikael Emtinger 已提交
4427

4428
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, renderTexture.__webglTexture, 0 );
M
Mikael Emtinger 已提交
4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451
			
			if( renderTexture.depthBuffer && !renderTexture.stencilBuffer ) {
				
				_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTexture.width, renderTexture.height );
				_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderTexture.__webglRenderbuffer );
		
		/* For some reason this is not working. Defaulting to RGBA4.	
			} else if( !renderTexture.depthBuffer && renderTexture.stencilBuffer ) {
			
				_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.STENCIL_INDEX8, renderTexture.width, renderTexture.height );
				_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderTexture.__webglRenderbuffer );
			*/
			} else if( renderTexture.depthBuffer && renderTexture.stencilBuffer ) {
				
				_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTexture.width, renderTexture.height );
				_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderTexture.__webglRenderbuffer );
				
			} else {
				
				_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTexture.width, renderTexture.height );
				
			}
			
4452 4453

			// Release everything
M
Mr.doob 已提交
4454

4455 4456 4457
			_gl.bindTexture( _gl.TEXTURE_2D, null );
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
M
Mr.doob 已提交
4458

4459 4460
		}

4461
		var framebuffer, width, height;
M
Mr.doob 已提交
4462

4463
		if ( renderTexture ) {
M
Mr.doob 已提交
4464

4465
			framebuffer = renderTexture.__webglFramebuffer;
4466 4467
			width = renderTexture.width;
			height = renderTexture.height;
M
Mr.doob 已提交
4468

4469
		} else {
M
Mr.doob 已提交
4470

4471
			framebuffer = null;
4472 4473
			width = _viewportWidth;
			height = _viewportHeight;
M
Mr.doob 已提交
4474

4475
		}
M
Mr.doob 已提交
4476

4477
		if ( framebuffer != _currentFramebuffer ) {
M
Mr.doob 已提交
4478

4479
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
4480
			_gl.viewport( _viewportX, _viewportY, width, height );
M
Mr.doob 已提交
4481

4482
			_currentFramebuffer = framebuffer;
M
Mr.doob 已提交
4483

4484
		}
4485

4486
	};
M
Mr.doob 已提交
4487

4488
	function updateRenderTargetMipmap( renderTarget ) {
M
Mr.doob 已提交
4489

4490
		_gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
4491 4492
		_gl.generateMipmap( _gl.TEXTURE_2D );
		_gl.bindTexture( _gl.TEXTURE_2D, null );
M
Mr.doob 已提交
4493 4494

	};
4495

4496
	function cacheUniformLocations( program, identifiers ) {
M
Mr.doob 已提交
4497

M
Mr.doob 已提交
4498
		var i, l, id;
M
Mr.doob 已提交
4499

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

4502 4503
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
4504

M
Mr.doob 已提交
4505
		}
M
Mr.doob 已提交
4506

M
Mr.doob 已提交
4507
	};
M
Mr.doob 已提交
4508

4509
	function cacheAttributeLocations( program, identifiers ) {
4510

4511
		var i, l, id;
M
Mr.doob 已提交
4512

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

4515 4516
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
M
Mr.doob 已提交
4517

4518
		}
M
Mr.doob 已提交
4519

M
Mr.doob 已提交
4520
	};
M
Mr.doob 已提交
4521

4522
	function getShader( type, string ) {
N
Nicolas Garcia Belmonte 已提交
4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540

		var shader;

		if ( type == "fragment" ) {

			shader = _gl.createShader( _gl.FRAGMENT_SHADER );

		} else if ( type == "vertex" ) {

			shader = _gl.createShader( _gl.VERTEX_SHADER );

		}

		_gl.shaderSource( shader, string );
		_gl.compileShader( shader );

		if ( !_gl.getShaderParameter( shader, _gl.COMPILE_STATUS ) ) {

4541
			console.error( _gl.getShaderInfoLog( shader ) );
4542
			console.error( string );
N
Nicolas Garcia Belmonte 已提交
4543 4544 4545 4546 4547
			return null;

		}

		return shader;
M
Mr.doob 已提交
4548

4549
	};
N
Nicolas Garcia Belmonte 已提交
4550

4551
	// fallback filters for non-power-of-2 textures
4552

4553
	function filterFallback( f ) {
4554

4555 4556 4557 4558 4559 4560 4561 4562
		switch ( f ) {

			case THREE.NearestFilter:
			case THREE.NearestMipMapNearestFilter:
			case THREE.NearestMipMapLinearFilter: return _gl.NEAREST; break;

			case THREE.LinearFilter:
			case THREE.LinearMipMapNearestFilter:
M
Mikael Emtinger 已提交
4563 4564
			case THREE.LinearMipMapLinearFilter: 
			default:
4565

M
Mikael Emtinger 已提交
4566
				return _gl.LINEAR; break;
4567 4568

		}
4569

4570
	};
4571 4572

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

4574
		switch ( p ) {
M
Mr.doob 已提交
4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587

			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;

4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601
			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;

4602
		}
M
Mr.doob 已提交
4603

4604
		return 0;
M
Mr.doob 已提交
4605

4606 4607
	};

4608
	function isPowerOfTwo( value ) {
4609 4610 4611 4612 4613

		return ( value & ( value - 1 ) ) == 0;

	};

4614
	function materialNeedsSmoothNormals( material ) {
4615 4616 4617

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

4618
	};
M
Mr.doob 已提交
4619

4620
	function bufferNeedsSmoothNormals( geometryGroup, object ) {
M
Mr.doob 已提交
4621

4622
		var m, ml, i, l, meshMaterial, needsSmoothNormals = false;
M
Mr.doob 已提交
4623

M
Mr.doob 已提交
4624
		for ( m = 0, ml = object.materials.length; m < ml; m++ ) {
4625

M
Mr.doob 已提交
4626
			meshMaterial = object.materials[ m ];
4627 4628 4629

			if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {

4630
				for ( i = 0, l = geometryGroup.materials.length; i < l; i++ ) {
4631

4632
					if ( materialNeedsSmoothNormals( geometryGroup.materials[ i ] ) ) {
4633

4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654
						needsSmoothNormals = true;
						break;

					}

				}

			} else {

				if ( materialNeedsSmoothNormals( meshMaterial ) ) {

					needsSmoothNormals = true;
					break;

				}

			}

			if ( needsSmoothNormals ) break;

		}
M
Mr.doob 已提交
4655

4656
		return needsSmoothNormals;
M
Mr.doob 已提交
4657

4658
	};
M
Mr.doob 已提交
4659

4660
	function unrollGroupMaterials( geometryGroup, object ) {
4661

4662 4663 4664
		var m, ml, i, il,
			material, meshMaterial,
			materials = [];
4665

4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676
		for ( m = 0, ml = object.materials.length; m < ml; m++ ) {

			meshMaterial = object.materials[ m ];

			if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {

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

					material = geometryGroup.materials[ i ];

					if ( material ) {
4677

4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696
						materials.push( material );

					}

				}

			} else {

				material = meshMaterial;

				if ( material ) {

					materials.push( material );

				}

			}

		}
4697

4698 4699 4700
		return materials;

	};
4701

4702
	function bufferGuessVertexColorType( materials, geometryGroup, object ) {
4703

4704
		var i, m, ml = materials.length;
4705

4706
		// use vertexColor type from the first material in unrolled materials
4707

4708
		for ( i = 0; i < ml; i++ ) {
4709

4710
			m = materials[ i ];
4711

4712
			if ( m.vertexColors ) {
4713

4714 4715 4716
				return m.vertexColors;

			}
4717

4718
		}
4719

4720
		return false;
4721

4722 4723
	};

4724
	function bufferGuessNormalType( materials, geometryGroup, object ) {
4725

4726
		var i, m, ml = materials.length;
4727

4728
		// only MeshBasicMaterial and MeshDepthMaterial don't need normals
4729

4730
		for ( i = 0; i < ml; i++ ) {
4731

4732
			m = materials[ i ];
4733

A
alteredq 已提交
4734
			if ( ( m instanceof THREE.MeshBasicMaterial && !m.envMap ) || m instanceof THREE.MeshDepthMaterial ) continue;
4735

4736
			if ( materialNeedsSmoothNormals( m ) ) {
4737

4738 4739 4740 4741 4742 4743 4744 4745 4746
				return THREE.SmoothShading;

			} else {

				return THREE.FlatShading;

			}

		}
4747

4748
		return false;
4749

4750 4751
	};

4752
	function bufferGuessUVType( materials, geometryGroup, object ) {
4753

4754
		var i, m, ml = materials.length;
4755

4756
		// material must use some texture to require uvs
4757

4758
		for ( i = 0; i < ml; i++ ) {
4759

4760
			m = materials[ i ];
4761

A
alteredq 已提交
4762
			if ( m.map || m.lightMap || m instanceof THREE.MeshShaderMaterial ) {
4763

4764
				return true;
4765

4766
			}
4767

4768
		}
4769

4770
		return false;
4771

4772
	};
4773

4774
	function allocateBones( object ) {
4775

4776 4777 4778 4779 4780 4781 4782
		// 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)
4783

4784
		var maxBones = 50;
4785

4786
		if ( object !== undefined && object instanceof THREE.SkinnedMesh ) {
4787

4788 4789 4790 4791 4792
			maxBones = object.bones.length;

		}

		return maxBones;
4793

4794
	};
4795

4796
	function allocateLights( lights, maxLights ) {
4797

4798 4799
		var l, ll, light, dirLights, pointLights, maxDirLights, maxPointLights;
		dirLights = pointLights = maxDirLights = maxPointLights = 0;
4800

4801
		for ( l = 0, ll = lights.length; l < ll; l++ ) {
4802

4803
			light = lights[ l ];
4804

4805 4806
			if ( light instanceof THREE.DirectionalLight ) dirLights++;
			if ( light instanceof THREE.PointLight ) pointLights++;
4807

4808
		}
4809

4810
		if ( ( pointLights + dirLights ) <= maxLights ) {
4811

4812 4813
			maxDirLights = dirLights;
			maxPointLights = pointLights;
4814

4815
		} else {
4816

4817 4818
			maxDirLights = Math.ceil( maxLights * dirLights / ( pointLights + dirLights ) );
			maxPointLights = maxLights - maxDirLights;
4819 4820 4821

		}

4822
		return { 'directional' : maxDirLights, 'point' : maxPointLights };
4823 4824

	};
M
Mr.doob 已提交
4825

A
alteredq 已提交
4826
	/* DEBUG
4827
	function getGLParams() {
M
Mr.doob 已提交
4828

4829
		var params  = {
M
Mr.doob 已提交
4830

4831 4832
			'MAX_VARYING_VECTORS': _gl.getParameter( _gl.MAX_VARYING_VECTORS ),
			'MAX_VERTEX_ATTRIBS': _gl.getParameter( _gl.MAX_VERTEX_ATTRIBS ),
M
Mr.doob 已提交
4833

4834 4835 4836
			'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 已提交
4837

4838 4839 4840
			'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 已提交
4841

4842 4843
		return params;
	};
M
Mr.doob 已提交
4844

4845
	function dumpObject( obj ) {
M
Mr.doob 已提交
4846

4847 4848
		var p, str = "";
		for ( p in obj ) {
M
Mr.doob 已提交
4849

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

4852
		}
M
Mr.doob 已提交
4853

4854 4855
		return str;
	}
A
alteredq 已提交
4856
	*/
4857
};
4858