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

	},

M
Mr.doob 已提交
72

73
	// parameters
74

75
	parameters = parameters || {};
M
Mr.doob 已提交
76

77 78 79 80
	stencil = parameters.stencil !== undefined ? parameters.stencil : true;
	antialias = parameters.antialias !== undefined ? parameters.antialias : false;
	clearColor = parameters.clearColor !== undefined ? new THREE.Color( parameters.clearColor ) : new THREE.Color( 0x000000 );
	clearAlpha = parameters.clearAlpha !== undefined ? parameters.clearAlpha : 0;
M
Mr.doob 已提交
81 82


83
	this.maxMorphTargets = 8;
N
Nicolas Garcia Belmonte 已提交
84 85
	this.domElement = _canvas;
	this.autoClear = true;
86
	this.sortObjects = true;
N
Nicolas Garcia Belmonte 已提交
87

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

90 91
	this.context = _gl;

M
Mikael Emtinger 已提交
92

M
Mikael Emtinger 已提交
93
	// prepare stencil shadow polygon
M
Mikael Emtinger 已提交
94

M
Mr.doob 已提交
95 96
	if ( stencil ) {

M
Mikael Emtinger 已提交
97
		var _stencilShadow      = {};
M
Mr.doob 已提交
98

M
Mikael Emtinger 已提交
99 100 101
		_stencilShadow.vertices = new Float32Array( 12 );
		_stencilShadow.faces    = new Uint16Array( 6 );
		_stencilShadow.darkness = 0.5;
M
Mr.doob 已提交
102

103 104 105 106
		_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 已提交
107

M
Mikael Emtinger 已提交
108 109
		_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 已提交
110

M
Mikael Emtinger 已提交
111 112
		_stencilShadow.vertexBuffer  = _gl.createBuffer();
		_stencilShadow.elementBuffer = _gl.createBuffer();
M
Mr.doob 已提交
113

M
Mikael Emtinger 已提交
114 115
		_gl.bindBuffer( _gl.ARRAY_BUFFER, _stencilShadow.vertexBuffer );
		_gl.bufferData( _gl.ARRAY_BUFFER,  _stencilShadow.vertices, _gl.STATIC_DRAW );
M
Mr.doob 已提交
116

M
Mikael Emtinger 已提交
117 118
		_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _stencilShadow.elementBuffer );
		_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, _stencilShadow.faces, _gl.STATIC_DRAW );
M
Mr.doob 已提交
119

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

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

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

M
Mikael Emtinger 已提交
127 128 129 130
		_stencilShadow.vertexLocation     = _gl.getAttribLocation ( _stencilShadow.program, "position"         );
		_stencilShadow.projectionLocation = _gl.getUniformLocation( _stencilShadow.program, "projectionMatrix" );
		_stencilShadow.darknessLocation   = _gl.getUniformLocation( _stencilShadow.program, "darkness"         );
	}
M
Mr.doob 已提交
131 132


M
Mikael Emtinger 已提交
133
	// prepare lens flare
M
Mr.doob 已提交
134

M
Mikael Emtinger 已提交
135 136
	var _lensFlare = {};
	var i;
M
Mr.doob 已提交
137

M
Mikael Emtinger 已提交
138 139
	_lensFlare.vertices     = new Float32Array( 8 + 8 );
	_lensFlare.faces        = new Uint16Array( 6 );
M
Mr.doob 已提交
140

M
Mikael Emtinger 已提交
141 142 143 144 145 146 147 148 149 150 151 152 153 154
	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;

155 156 157 158
	_lensFlare.vertexBuffer     = _gl.createBuffer();
	_lensFlare.elementBuffer    = _gl.createBuffer();
	_lensFlare.tempTexture      = _gl.createTexture();
	_lensFlare.occlusionTexture = _gl.createTexture();
M
Mr.doob 已提交
159

M
Mikael Emtinger 已提交
160 161
	_gl.bindBuffer( _gl.ARRAY_BUFFER, _lensFlare.vertexBuffer );
	_gl.bufferData( _gl.ARRAY_BUFFER,  _lensFlare.vertices, _gl.STATIC_DRAW );
M
Mikael Emtinger 已提交
162

M
Mikael Emtinger 已提交
163 164 165 166 167 168 169 170 171 172
	_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 );

173 174 175 176 177 178 179 180
	_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 ) {
181

182 183 184 185 186 187 188
		_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 );

189

190 191 192
	} else {

		_lensFlare.hasVertexTexture = true;
193

194 195 196 197
		_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 );
198

199
	}
M
Mikael Emtinger 已提交
200 201 202 203 204

	_lensFlare.attributes = {};
	_lensFlare.uniforms = {};
	_lensFlare.attributes.vertex       = _gl.getAttribLocation ( _lensFlare.program, "position" );
	_lensFlare.attributes.uv           = _gl.getAttribLocation ( _lensFlare.program, "UV" );
205
	_lensFlare.uniforms.renderType     = _gl.getUniformLocation( _lensFlare.program, "renderType" );
M
Mikael Emtinger 已提交
206
	_lensFlare.uniforms.map            = _gl.getUniformLocation( _lensFlare.program, "map" );
207
	_lensFlare.uniforms.occlusionMap   = _gl.getUniformLocation( _lensFlare.program, "occlusionMap" );
M
Mikael Emtinger 已提交
208 209 210 211 212
	_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
Mr.doob 已提交
213 214
	//_gl.enableVertexAttribArray( _lensFlare.attributes.vertex );
	//_gl.enableVertexAttribArray( _lensFlare.attributes.uv );
215

M
Mr.doob 已提交
216
	var _lensFlareAttributesEnabled = false;
M
Mikael Emtinger 已提交
217

M
Mikael Emtinger 已提交
218 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
	// 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 = {};
256 257 258 259 260 261 262 263 264 265 266 267 268 269
	_sprite.attributes.position           = _gl.getAttribLocation ( _sprite.program, "position" );
	_sprite.attributes.uv                 = _gl.getAttribLocation ( _sprite.program, "uv" );
	_sprite.uniforms.uvOffset             = _gl.getUniformLocation( _sprite.program, "uvOffset" );
	_sprite.uniforms.uvScale              = _gl.getUniformLocation( _sprite.program, "uvScale" );
	_sprite.uniforms.rotation             = _gl.getUniformLocation( _sprite.program, "rotation" );
	_sprite.uniforms.scale                = _gl.getUniformLocation( _sprite.program, "scale" );
	_sprite.uniforms.alignment            = _gl.getUniformLocation( _sprite.program, "alignment" );
	_sprite.uniforms.map                  = _gl.getUniformLocation( _sprite.program, "map" );
	_sprite.uniforms.opacity              = _gl.getUniformLocation( _sprite.program, "opacity" );
	_sprite.uniforms.useScreenCoordinates = _gl.getUniformLocation( _sprite.program, "useScreenCoordinates" );
	_sprite.uniforms.affectedByDistance   = _gl.getUniformLocation( _sprite.program, "affectedByDistance" );
	_sprite.uniforms.screenPosition    	  = _gl.getUniformLocation( _sprite.program, "screenPosition" );
	_sprite.uniforms.modelViewMatrix      = _gl.getUniformLocation( _sprite.program, "modelViewMatrix" );
	_sprite.uniforms.projectionMatrix     = _gl.getUniformLocation( _sprite.program, "projectionMatrix" );
M
Mikael Emtinger 已提交
270

M
Mr.doob 已提交
271 272
	//_gl.enableVertexAttribArray( _sprite.attributes.position );
	//_gl.enableVertexAttribArray( _sprite.attributes.uv );
M
Mikael Emtinger 已提交
273

M
Mr.doob 已提交
274
	var _spriteAttributesEnabled = false;
M
Mikael Emtinger 已提交
275

N
Nicolas Garcia Belmonte 已提交
276 277 278 279
	this.setSize = function ( width, height ) {

		_canvas.width = width;
		_canvas.height = height;
280

281 282 283
		this.setViewport( 0, 0, _canvas.width, _canvas.height );

	};
N
Nicolas Garcia Belmonte 已提交
284

285
	this.setViewport = function ( x, y, width, height ) {
286

287 288
		_viewportX = x;
		_viewportY = y;
289

290 291
		_viewportWidth = width;
		_viewportHeight = height;
292

293
		_gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight );
294

N
Nicolas Garcia Belmonte 已提交
295
	};
296

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

299
		_gl.scissor( x, y, width, height );
300

301
	};
302

303
	this.enableScissorTest = function ( enable ) {
304

305 306 307 308
		if ( enable )
			_gl.enable( _gl.SCISSOR_TEST );
		else
			_gl.disable( _gl.SCISSOR_TEST );
309

310
	};
311

312
	this.enableDepthBufferWrite = function ( enable ) {
313

314
		_currentDepthMask = enable;
315 316 317
		_gl.depthMask( enable );

	};
318

319
	this.setClearColorHex = function ( hex, alpha ) {
320

321 322
		var color = new THREE.Color( hex );
		_gl.clearColor( color.r, color.g, color.b, alpha );
323

324
	};
A
alteredq 已提交
325

326
	this.setClearColor = function ( color, alpha ) {
A
alteredq 已提交
327 328 329 330

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

	};
331

N
Nicolas Garcia Belmonte 已提交
332 333
	this.clear = function () {

M
Mikael Emtinger 已提交
334
		_gl.clear( _gl.COLOR_BUFFER_BIT | _gl.DEPTH_BUFFER_BIT | _gl.STENCIL_BUFFER_BIT );
N
Nicolas Garcia Belmonte 已提交
335 336 337

	};

M
Mikael Emtinger 已提交
338 339 340 341 342
	this.setStencilShadowDarkness = function( value ) {
		
		_stencilShadow.darkness = value;
	};

M
Mr.doob 已提交
343

A
alteredq 已提交
344
	function setupLights ( program, lights ) {
345

346
		var l, ll, light, r = 0, g = 0, b = 0,
347
		color, position, intensity, distance,
M
Mr.doob 已提交
348

349
		zlights = _lights,
M
Mr.doob 已提交
350

351
		dcolors = zlights.directional.colors,
352
		dpositions = zlights.directional.positions,
353

354
		pcolors = zlights.point.colors,
355
		ppositions = zlights.point.positions,
356
		pdistances = zlights.point.distances,
357

358 359
		dlength = 0,
		plength = 0,
360

361 362
		doffset = 0,
		poffset = 0;
M
Mr.doob 已提交
363

364
		for ( l = 0, ll = lights.length; l < ll; l++ ) {
365

366
			light = lights[ l ];
367
			color = light.color;
368

369 370
			position = light.position;
			intensity = light.intensity;
371
			distance = light.distance;
372 373 374

			if ( light instanceof THREE.AmbientLight ) {

375 376 377
				r += color.r;
				g += color.g;
				b += color.b;
M
Mr.doob 已提交
378

379
			} else if ( light instanceof THREE.DirectionalLight ) {
380

381
				doffset = dlength * 3;
382

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

387
				dpositions[ doffset ] = position.x;
388 389
				dpositions[ doffset + 1 ] = position.y;
				dpositions[ doffset + 2 ] = position.z;
390

391
				dlength += 1;
M
Mr.doob 已提交
392

393 394
			} else if( light instanceof THREE.PointLight ) {

395
				poffset = plength * 3;
396

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

401
				ppositions[ poffset ] = position.x;
402 403
				ppositions[ poffset + 1 ] = position.y;
				ppositions[ poffset + 2 ] = position.z;
M
Mr.doob 已提交
404

405 406
				pdistances[ plength ] = distance;

407
				plength += 1;
M
Mr.doob 已提交
408

409 410 411
			}

		}
412

413 414
		// null eventual remains from removed lights
		// (this is to avoid if in shader)
415

416 417
		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 已提交
418

419 420
		zlights.point.length = plength;
		zlights.directional.length = dlength;
M
Mr.doob 已提交
421

422 423 424
		zlights.ambient[ 0 ] = r;
		zlights.ambient[ 1 ] = g;
		zlights.ambient[ 2 ] = b;
M
Mr.doob 已提交
425

426
	};
M
Mr.doob 已提交
427

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

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

433
	};
M
Mr.doob 已提交
434

435
	function createLineBuffers( geometry ) {
M
Mr.doob 已提交
436

437 438
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
M
Mr.doob 已提交
439

440
	};
441

442
	function createRibbonBuffers( geometry ) {
A
alteredq 已提交
443

444 445
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
A
alteredq 已提交
446 447 448

	};

449
	function createMeshBuffers( geometryGroup ) {
M
Mr.doob 已提交
450

451 452 453 454 455 456
		geometryGroup.__webglVertexBuffer = _gl.createBuffer();
		geometryGroup.__webglNormalBuffer = _gl.createBuffer();
		geometryGroup.__webglTangentBuffer = _gl.createBuffer();
		geometryGroup.__webglColorBuffer = _gl.createBuffer();
		geometryGroup.__webglUVBuffer = _gl.createBuffer();
		geometryGroup.__webglUV2Buffer = _gl.createBuffer();
457

458 459 460 461 462 463 464 465 466
		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 ) {
467

468
			var m, ml;
469 470 471 472 473 474
			geometryGroup.__webglMorphTargetsBuffers = []; 

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

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

475 476 477
			}

		}
M
Mr.doob 已提交
478

479
	};
480

481
	function initLineBuffers ( geometry ) {
M
Mr.doob 已提交
482

483 484 485
		var nvertices = geometry.vertices.length;

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

488
		geometry.__webglLineCount = nvertices;
M
Mr.doob 已提交
489

490
	};
M
Mr.doob 已提交
491

492
	function initRibbonBuffers ( geometry ) {
A
alteredq 已提交
493 494 495 496 497 498

		var nvertices = geometry.vertices.length;

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

499
		geometry.__webglVertexCount = nvertices;
A
alteredq 已提交
500 501

	};
502

503
	function initParticleBuffers ( geometry ) {
504 505 506 507

		var nvertices = geometry.vertices.length;

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

510
		geometry.__sortArray = [];
511

512
		geometry.__webglParticleCount = nvertices;
513 514 515

	};

516
	function initMeshBuffers ( geometryGroup, object ) {
M
Mr.doob 已提交
517

M
Mikael Emtinger 已提交
518
		var f, fl, fi, face,
519
		m, ml, size,
520 521 522 523 524 525
		nvertices = 0, ntris = 0, nlines = 0,

		uvType,
		vertexColorType,
		normalType,
		materials,
526
		attribute,
527 528 529 530

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

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

534 535
			fi = chunk_faces[ f ];
			face = obj_faces[ fi ];
M
Mr.doob 已提交
536

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

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

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

545 546
				nvertices += 4;
				ntris += 2;
547
				nlines += 4;
M
Mr.doob 已提交
548

549
			}
M
Mr.doob 已提交
550

551
		}
552 553 554

		materials = unrollGroupMaterials( geometryGroup, object );

555 556
		uvType = bufferGuessUVType( materials, geometryGroup, object );
		normalType = bufferGuessNormalType( materials, geometryGroup, object );
A
alteredq 已提交
557 558
		vertexColorType = bufferGuessVertexColorType( materials, geometryGroup, object );

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

561
		geometryGroup.__vertexArray = new Float32Array( nvertices * 3 );
562

563
		if ( normalType ) {
M
Mr.doob 已提交
564

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

567
		}
568

569
		if ( geometry.hasTangents ) {
570

571
			geometryGroup.__tangentArray = new Float32Array( nvertices * 4 );
572

573
		}
574

575
		if ( vertexColorType ) {
576

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

579
		}
M
Mr.doob 已提交
580

581
		if ( uvType ) {
582

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

585 586 587 588 589
				geometryGroup.__uvArray = new Float32Array( nvertices * 2 );

			}

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

591 592 593 594 595 596 597 598 599 600 601 602 603 604 605
				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 已提交
606
		geometryGroup.__faceArray = new Uint16Array( ntris * 3 + ( object.geometry.edgeFaces ? object.geometry.edgeFaces.length * 2 * 3 : 0 ));
607
		geometryGroup.__lineArray = new Uint16Array( nlines * 2 );
M
Mr.doob 已提交
608

609 610
		if ( geometryGroup.numMorphTargets ) {

611
			geometryGroup.__morphTargetsArrays = []; 
612 613 614

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

615 616
				geometryGroup.__morphTargetsArrays.push( new Float32Array( nvertices * 3 ) );

617 618 619
			}

		}
620

621
		geometryGroup.__needsSmoothNormals = ( normalType == THREE.SmoothShading );
622

623 624 625 626
		geometryGroup.__uvType = uvType;
		geometryGroup.__vertexColorType = vertexColorType;
		geometryGroup.__normalType = normalType;

627 628
		geometryGroup.__webglFaceCount = ntris * 3 + ( object.geometry.edgeFaces ? object.geometry.edgeFaces.length * 2 * 3 : 0 );
		geometryGroup.__webglLineCount = nlines * 2;
629

M
Mr.doob 已提交
630

631
		// custom attributes
M
Mr.doob 已提交
632 633 634 635 636

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

			if ( materials[ m ].attributes ) {

637 638
				geometryGroup.__webglCustomAttributes = {};

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

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

643
					size = 1;		// "f" and "i"
M
Mr.doob 已提交
644 645

					if( attribute.type === "v2" ) size = 2;
646 647 648
					else if( attribute.type === "v3" ) size = 3;
					else if( attribute.type === "v4" ) size = 4;
					else if( attribute.type === "c"  ) size = 3;
M
Mr.doob 已提交
649

650
					attribute.size = size;
M
Mr.doob 已提交
651
					attribute.needsUpdate = true;
652 653 654 655 656 657 658 659
					attribute.array = new Float32Array( nvertices * size );
					attribute.buffer = _gl.createBuffer();

					geometryGroup.__webglCustomAttributes[ a ] = attribute;

				}

			}
M
Mr.doob 已提交
660

661
		}
662

663
	};
M
Mr.doob 已提交
664

665

666
	function setMeshBuffers ( geometryGroup, object, hint ) {
667

M
Mr.doob 已提交
668
		var f, fl, fi, face,
669 670 671 672 673 674 675 676 677 678 679 680 681
		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,
682
		a,
M
Mr.doob 已提交
683

684
		vertexIndex = 0,
685

686 687
		offset = 0,
		offset_uv = 0,
688
		offset_uv2 = 0,
689 690 691 692
		offset_face = 0,
		offset_normal = 0,
		offset_tangent = 0,
		offset_line = 0,
693
		offset_color = 0,
A
alteredq 已提交
694
		offset_skin = 0,
695
		offset_morphTarget = 0,
696
		offset_custom = 0,
697
		offset_customSrc = 0,
M
Mr.doob 已提交
698

699 700 701 702 703 704
		vertexArray = geometryGroup.__vertexArray,
		uvArray = geometryGroup.__uvArray,
		uv2Array = geometryGroup.__uv2Array,
		normalArray = geometryGroup.__normalArray,
		tangentArray = geometryGroup.__tangentArray,
		colorArray = geometryGroup.__colorArray,
705

706 707 708 709
		skinVertexAArray = geometryGroup.__skinVertexAArray,
		skinVertexBArray = geometryGroup.__skinVertexBArray,
		skinIndexArray = geometryGroup.__skinIndexArray,
		skinWeightArray = geometryGroup.__skinWeightArray,
M
Mr.doob 已提交
710

711 712
		morphTargetsArrays = geometryGroup.__morphTargetsArrays,

713 714
		customAttributes = geometryGroup.__webglCustomAttributes,
		customAttribute,
715

716 717
		faceArray = geometryGroup.__faceArray,
		lineArray = geometryGroup.__lineArray,
M
Mr.doob 已提交
718

719
		needsSmoothNormals = geometryGroup.__needsSmoothNormals,
720

721
		vertexColorType = geometryGroup.__vertexColorType,
A
alteredq 已提交
722 723
		uvType = geometryGroup.__uvType,
		normalType = geometryGroup.__normalType,
724

725
		geometry = object.geometry, // this is shared for all chunks
726

727
		dirtyVertices = geometry.__dirtyVertices,
728 729 730
		dirtyElements = geometry.__dirtyElements,
		dirtyUvs = geometry.__dirtyUvs,
		dirtyNormals = geometry.__dirtyNormals,
731
		dirtyTangents = geometry.__dirtyTangents,
732
		dirtyColors = geometry.__dirtyColors,
733
		dirtyMorphTargets = geometry.__dirtyMorphTargets,
M
Mr.doob 已提交
734

735
		vertices = geometry.vertices,
736
		chunk_faces = geometryGroup.faces,
737
		obj_faces = geometry.faces,
738

739 740
		obj_uvs  = geometry.faceVertexUvs[ 0 ],
		obj_uvs2 = geometry.faceVertexUvs[ 1 ],
741

A
alteredq 已提交
742
		obj_colors = geometry.colors,
743

A
alteredq 已提交
744 745 746
		obj_skinVerticesA = geometry.skinVerticesA,
		obj_skinVerticesB = geometry.skinVerticesB,
		obj_skinIndices = geometry.skinIndices,
747
		obj_skinWeights = geometry.skinWeights,
748
		obj_edgeFaces = object instanceof THREE.ShadowVolume ? geometry.edgeFaces : undefined;
749 750

		morphTargets = geometry.morphTargets;
751

752
		if ( customAttributes ) {
M
Mr.doob 已提交
753

754
			for ( a in customAttributes ) {
M
Mr.doob 已提交
755

756
				customAttributes[ a ].offset = 0;
757
				customAttributes[ a ].offsetSrc = 0;
M
Mr.doob 已提交
758

759 760
			}

M
Mr.doob 已提交
761
		}
762 763


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

766 767
			fi = chunk_faces[ f ];
			face = obj_faces[ fi ];
768 769

			if ( obj_uvs ) {
A
alteredq 已提交
770 771 772 773

				uv = obj_uvs[ fi ];

			}
774 775 776

			if ( obj_uvs2 ) {

A
alteredq 已提交
777 778 779
				uv2 = obj_uvs2[ fi ];

			}
M
Mr.doob 已提交
780

781
			vertexNormals = face.vertexNormals;
782
			faceNormal = face.normal;
783

784 785
			vertexColors = face.vertexColors;
			faceColor = face.color;
786

787
			vertexTangents = face.vertexTangents;
788 789 790

			if ( face instanceof THREE.Face3 ) {

791
				if ( dirtyVertices ) {
M
Mr.doob 已提交
792

793 794 795
					v1 = vertices[ face.a ].position;
					v2 = vertices[ face.b ].position;
					v3 = vertices[ face.c ].position;
M
Mr.doob 已提交
796

797 798 799
					vertexArray[ offset ]     = v1.x;
					vertexArray[ offset + 1 ] = v1.y;
					vertexArray[ offset + 2 ] = v1.z;
M
Mr.doob 已提交
800

801 802 803
					vertexArray[ offset + 3 ] = v2.x;
					vertexArray[ offset + 4 ] = v2.y;
					vertexArray[ offset + 5 ] = v2.z;
804

805 806 807
					vertexArray[ offset + 6 ] = v3.x;
					vertexArray[ offset + 7 ] = v3.y;
					vertexArray[ offset + 8 ] = v3.z;
M
Mr.doob 已提交
808

809
					offset += 9;
M
Mr.doob 已提交
810

811
				}
812

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

815
					for ( a in customAttributes ) {
M
Mr.doob 已提交
816

817 818
						customAttribute = customAttributes[ a ];

M
Mr.doob 已提交
819 820
						if ( customAttribute.needsUpdate ) {

821
							offset_custom = customAttribute.offset;
822
							offset_customSrc = customAttribute.offsetSrc;
M
Mr.doob 已提交
823

824
							if( customAttribute.size === 1 ) {
M
Mr.doob 已提交
825

826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848
								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 已提交
849

850
								customAttribute.offset += 3;
M
Mr.doob 已提交
851

852
							} else {
M
Mr.doob 已提交
853

854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876
								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 已提交
877

878
								if( customAttribute.size === 2 ) {
M
Mr.doob 已提交
879 880 881

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

M
Mr.doob 已提交
883 884
									customAttribute.array[ offset_custom + 2 ] = v2.x;
									customAttribute.array[ offset_custom + 3 ] = v2.y;
885

M
Mr.doob 已提交
886
									customAttribute.array[ offset_custom + 4 ] = v3.x;
887
									customAttribute.array[ offset_custom + 5 ] = v3.y;
M
Mr.doob 已提交
888

889
									customAttribute.offset += 6;
M
Mr.doob 已提交
890

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

893 894 895 896 897
									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;
898

899 900 901
										customAttribute.array[ offset_custom + 3 ] = v2.r;
										customAttribute.array[ offset_custom + 4 ] = v2.g;
										customAttribute.array[ offset_custom + 5 ] = v2.b;
902

903 904 905 906 907 908 909 910 911
										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;
912

913 914 915
										customAttribute.array[ offset_custom + 3 ] = v2.x;
										customAttribute.array[ offset_custom + 4 ] = v2.y;
										customAttribute.array[ offset_custom + 5 ] = v2.z;
916

917 918 919 920 921
										customAttribute.array[ offset_custom + 6 ] = v3.x;
										customAttribute.array[ offset_custom + 7 ] = v3.y;
										customAttribute.array[ offset_custom + 8 ] = v3.z;
										
									}
M
Mr.doob 已提交
922

923
									customAttribute.offset += 9;
M
Mr.doob 已提交
924

925
								} else {
M
Mr.doob 已提交
926 927 928 929 930

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

M
Mr.doob 已提交
932 933 934 935
									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;
936

M
Mr.doob 已提交
937
									customAttribute.array[ offset_custom + 8  ] = v3.x;
938 939 940
									customAttribute.array[ offset_custom + 9  ] = v3.y;
									customAttribute.array[ offset_custom + 10 ] = v3.z;
									customAttribute.array[ offset_custom + 11 ] = v3.w;
M
Mr.doob 已提交
941

942
									customAttribute.offset += 12;
M
Mr.doob 已提交
943

944
								}
M
Mr.doob 已提交
945

946
							}
M
Mr.doob 已提交
947

948
						}
M
Mr.doob 已提交
949

950
					}
M
Mr.doob 已提交
951

952 953 954
				}


955
				if ( dirtyMorphTargets ) {
956 957 958

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

959 960 961
						v1 = morphTargets[ vk ].vertices[ face.a ].position;
						v2 = morphTargets[ vk ].vertices[ face.b ].position;
						v3 = morphTargets[ vk ].vertices[ face.c ].position;
962

963
						vka = morphTargetsArrays[ vk ];
964

965 966 967
						vka[ offset_morphTarget + 0 ] = v1.x;
						vka[ offset_morphTarget + 1 ] = v1.y;
						vka[ offset_morphTarget + 2 ] = v1.z;
968

969 970 971
						vka[ offset_morphTarget + 3 ] = v2.x;
						vka[ offset_morphTarget + 4 ] = v2.y;
						vka[ offset_morphTarget + 5 ] = v2.z;
972

973 974 975
						vka[ offset_morphTarget + 6 ] = v3.x;
						vka[ offset_morphTarget + 7 ] = v3.y;
						vka[ offset_morphTarget + 8 ] = v3.z;
976 977
					}

978
					offset_morphTarget += 9;
979

980 981
				}

A
alteredq 已提交
982 983 984
				if ( obj_skinWeights.length ) {

					// weights
985

A
alteredq 已提交
986 987 988
					sw1 = obj_skinWeights[ face.a ];
					sw2 = obj_skinWeights[ face.b ];
					sw3 = obj_skinWeights[ face.c ];
989

A
alteredq 已提交
990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005
					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
1006

A
alteredq 已提交
1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026
					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
1027

A
alteredq 已提交
1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047
					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
1048

A
alteredq 已提交
1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068
					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;
1069

A
alteredq 已提交
1070
				}
1071

1072 1073 1074
				if ( dirtyColors && vertexColorType ) {

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

1076 1077 1078 1079 1080
						c1 = vertexColors[ 0 ];
						c2 = vertexColors[ 1 ];
						c3 = vertexColors[ 2 ];

					} else {
1081

1082 1083 1084 1085 1086
						c1 = faceColor;
						c2 = faceColor;
						c3 = faceColor;

					}
1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098

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

1100 1101 1102 1103
					offset_color += 9;

				}

1104
				if ( dirtyTangents && geometry.hasTangents ) {
1105

1106 1107 1108
					t1 = vertexTangents[ 0 ];
					t2 = vertexTangents[ 1 ];
					t3 = vertexTangents[ 2 ];
1109

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

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

1120 1121 1122 1123
					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 已提交
1124

1125
					offset_tangent += 12;
M
Mr.doob 已提交
1126

1127 1128
				}

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

1131 1132 1133
					if ( vertexNormals.length == 3 && needsSmoothNormals ) {

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

1135
							vn = vertexNormals[ i ];
M
Mr.doob 已提交
1136

1137 1138 1139
							normalArray[ offset_normal ]     = vn.x;
							normalArray[ offset_normal + 1 ] = vn.y;
							normalArray[ offset_normal + 2 ] = vn.z;
M
Mr.doob 已提交
1140

1141
							offset_normal += 3;
M
Mr.doob 已提交
1142

1143
						}
M
Mr.doob 已提交
1144

1145
					} else {
1146

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

1149 1150 1151
							normalArray[ offset_normal ]     = faceNormal.x;
							normalArray[ offset_normal + 1 ] = faceNormal.y;
							normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
1152

1153
							offset_normal += 3;
M
Mr.doob 已提交
1154

1155
						}
M
Mr.doob 已提交
1156 1157

					}
M
Mr.doob 已提交
1158

1159 1160
				}

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

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

1165
						uvi = uv[ i ];
M
Mr.doob 已提交
1166

1167 1168
						uvArray[ offset_uv ]     = uvi.u;
						uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
1169

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

M
Mr.doob 已提交
1172
					}
1173 1174 1175

				}

A
alteredq 已提交
1176
				if ( dirtyUvs && uv2 !== undefined && uvType ) {
1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190

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

						uv2i = uv2[ i ];

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

						offset_uv2 += 2;

					}

				}

1191
				if ( dirtyElements ) {
M
Mr.doob 已提交
1192

1193 1194 1195
					faceArray[ offset_face ] = vertexIndex;
					faceArray[ offset_face + 1 ] = vertexIndex + 1;
					faceArray[ offset_face + 2 ] = vertexIndex + 2;
M
Mr.doob 已提交
1196

1197
					offset_face += 3;
M
Mr.doob 已提交
1198

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

1202 1203
					lineArray[ offset_line + 2 ] = vertexIndex;
					lineArray[ offset_line + 3 ] = vertexIndex + 2;
M
Mr.doob 已提交
1204

1205 1206
					lineArray[ offset_line + 4 ] = vertexIndex + 1;
					lineArray[ offset_line + 5 ] = vertexIndex + 2;
M
Mr.doob 已提交
1207

1208
					offset_line += 6;
1209

1210
					vertexIndex += 3;
M
Mr.doob 已提交
1211

1212
				}
M
Mr.doob 已提交
1213

1214 1215 1216

			} else if ( face instanceof THREE.Face4 ) {

1217
				if ( dirtyVertices ) {
M
Mr.doob 已提交
1218

1219 1220 1221 1222
					v1 = vertices[ face.a ].position;
					v2 = vertices[ face.b ].position;
					v3 = vertices[ face.c ].position;
					v4 = vertices[ face.d ].position;
M
Mr.doob 已提交
1223

1224 1225 1226
					vertexArray[ offset ]     = v1.x;
					vertexArray[ offset + 1 ] = v1.y;
					vertexArray[ offset + 2 ] = v1.z;
M
Mr.doob 已提交
1227

1228 1229 1230
					vertexArray[ offset + 3 ] = v2.x;
					vertexArray[ offset + 4 ] = v2.y;
					vertexArray[ offset + 5 ] = v2.z;
1231

1232 1233 1234
					vertexArray[ offset + 6 ] = v3.x;
					vertexArray[ offset + 7 ] = v3.y;
					vertexArray[ offset + 8 ] = v3.z;
1235

1236
					vertexArray[ offset + 9 ]  = v4.x;
1237 1238
					vertexArray[ offset + 10 ] = v4.y;
					vertexArray[ offset + 11 ] = v4.z;
M
Mr.doob 已提交
1239

1240
					offset += 12;
M
Mr.doob 已提交
1241

1242
				}
1243

1244
				if ( customAttributes ) {
M
Mr.doob 已提交
1245

1246
					for ( a in customAttributes ) {
M
Mr.doob 已提交
1247

1248 1249
						customAttribute = customAttributes[ a ];

M
Mr.doob 已提交
1250
						if ( customAttribute.needsUpdate ) {
1251 1252

							offset_custom = customAttribute.offset;
1253
							offset_customSrc = customAttribute.offsetSrc;
M
Mr.doob 已提交
1254

1255
							if( customAttribute.size === 1 ) {
M
Mr.doob 已提交
1256

1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281
								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 已提交
1282

1283
								customAttribute.offset += 4;
M
Mr.doob 已提交
1284

1285
							} else {
M
Mr.doob 已提交
1286

1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312
								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 已提交
1313

1314
								if( customAttribute.size === 2 ) {
M
Mr.doob 已提交
1315 1316 1317

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

M
Mr.doob 已提交
1319 1320
									customAttribute.array[ offset_custom + 2 ] = v2.x;
									customAttribute.array[ offset_custom + 3 ] = v2.y;
1321

M
Mr.doob 已提交
1322
									customAttribute.array[ offset_custom + 4 ] = v3.x;
1323
									customAttribute.array[ offset_custom + 5 ] = v3.y;
1324

M
Mr.doob 已提交
1325
									customAttribute.array[ offset_custom + 6 ] = v4.x;
1326
									customAttribute.array[ offset_custom + 7 ] = v4.y;
M
Mr.doob 已提交
1327

1328
									customAttribute.offset += 8;
M
Mr.doob 已提交
1329

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

1332 1333 1334 1335 1336
									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;
1337

1338 1339 1340
										customAttribute.array[ offset_custom + 3  ] = v2.r;
										customAttribute.array[ offset_custom + 4  ] = v2.g;
										customAttribute.array[ offset_custom + 5  ] = v2.b;
1341

1342 1343 1344
										customAttribute.array[ offset_custom + 6  ] = v3.r;
										customAttribute.array[ offset_custom + 7  ] = v3.g;
										customAttribute.array[ offset_custom + 8  ] = v3.b;
1345

1346 1347 1348 1349 1350 1351 1352 1353 1354
										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;
1355

1356 1357 1358
										customAttribute.array[ offset_custom + 3  ] = v2.x;
										customAttribute.array[ offset_custom + 4  ] = v2.y;
										customAttribute.array[ offset_custom + 5  ] = v2.z;
1359

1360 1361 1362
										customAttribute.array[ offset_custom + 6  ] = v3.x;
										customAttribute.array[ offset_custom + 7  ] = v3.y;
										customAttribute.array[ offset_custom + 8  ] = v3.z;
1363

1364 1365 1366 1367 1368
										customAttribute.array[ offset_custom + 9  ] = v4.x;
										customAttribute.array[ offset_custom + 10 ] = v4.y;
										customAttribute.array[ offset_custom + 11 ] = v4.z;
										
									}
M
Mr.doob 已提交
1369

1370
									customAttribute.offset += 12;
M
Mr.doob 已提交
1371

1372
								} else {
M
Mr.doob 已提交
1373 1374 1375 1376 1377

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

M
Mr.doob 已提交
1379 1380 1381 1382
									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;
1383

M
Mr.doob 已提交
1384
									customAttribute.array[ offset_custom + 8  ] = v3.x;
1385 1386 1387
									customAttribute.array[ offset_custom + 9  ] = v3.y;
									customAttribute.array[ offset_custom + 10 ] = v3.z;
									customAttribute.array[ offset_custom + 11 ] = v3.w;
1388

M
Mr.doob 已提交
1389
									customAttribute.array[ offset_custom + 12 ] = v4.x;
1390 1391 1392
									customAttribute.array[ offset_custom + 13 ] = v4.y;
									customAttribute.array[ offset_custom + 14 ] = v4.z;
									customAttribute.array[ offset_custom + 15 ] = v4.w;
M
Mr.doob 已提交
1393

1394
									customAttribute.offset += 16;
M
Mr.doob 已提交
1395

1396
								}
M
Mr.doob 已提交
1397

1398
							}
M
Mr.doob 已提交
1399

1400
						}
M
Mr.doob 已提交
1401

1402
					}
M
Mr.doob 已提交
1403

1404 1405 1406
				}


1407
				if ( dirtyMorphTargets ) {
1408 1409 1410

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

1411 1412 1413 1414
						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;
1415

1416
						vka = morphTargetsArrays[ vk ];
1417

1418 1419 1420
						vka[ offset_morphTarget + 0 ] = v1.x;
						vka[ offset_morphTarget + 1 ] = v1.y;
						vka[ offset_morphTarget + 2 ] = v1.z;
1421

1422 1423 1424
						vka[ offset_morphTarget + 3 ] = v2.x;
						vka[ offset_morphTarget + 4 ] = v2.y;
						vka[ offset_morphTarget + 5 ] = v2.z;
1425

1426 1427 1428
						vka[ offset_morphTarget + 6 ] = v3.x;
						vka[ offset_morphTarget + 7 ] = v3.y;
						vka[ offset_morphTarget + 8 ] = v3.z;
1429

1430 1431 1432
						vka[ offset_morphTarget + 9 ] = v4.x;
						vka[ offset_morphTarget + 10 ] = v4.y;
						vka[ offset_morphTarget + 11 ] = v4.z;
1433 1434
					}

1435
					offset_morphTarget += 12;
1436

1437 1438
				}

A
alteredq 已提交
1439 1440 1441
				if ( obj_skinWeights.length ) {

					// weights
1442

A
alteredq 已提交
1443 1444 1445 1446
					sw1 = obj_skinWeights[ face.a ];
					sw2 = obj_skinWeights[ face.b ];
					sw3 = obj_skinWeights[ face.c ];
					sw4 = obj_skinWeights[ face.d ];
1447

A
alteredq 已提交
1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468
					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
1469

A
alteredq 已提交
1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495
					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
1496

A
alteredq 已提交
1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522
					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
1523

A
alteredq 已提交
1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543
					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;

1544 1545
					skinVertexBArray[ offset_skin + 12 ] = sb4.x;
					skinVertexBArray[ offset_skin + 13 ] = sb4.y;
A
alteredq 已提交
1546 1547 1548
					skinVertexBArray[ offset_skin + 14 ] = sb4.z;
					skinVertexBArray[ offset_skin + 15 ] = 1;

1549 1550
					offset_skin += 16;

A
alteredq 已提交
1551
				}
1552

1553 1554 1555
				if ( dirtyColors && vertexColorType ) {

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

1557 1558 1559 1560 1561 1562
						c1 = vertexColors[ 0 ];
						c2 = vertexColors[ 1 ];
						c3 = vertexColors[ 2 ];
						c4 = vertexColors[ 3 ];

					} else {
1563

1564 1565 1566 1567 1568 1569
						c1 = faceColor;
						c2 = faceColor;
						c3 = faceColor;
						c4 = faceColor;

					}
1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581

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

1583 1584 1585
					colorArray[ offset_color + 9 ]  = c4.r;
					colorArray[ offset_color + 10 ] = c4.g;
					colorArray[ offset_color + 11 ] = c4.b;
1586

1587 1588
					offset_color += 12;

1589 1590
				}

1591
				if ( dirtyTangents && geometry.hasTangents ) {
1592

1593 1594 1595 1596
					t1 = vertexTangents[ 0 ];
					t2 = vertexTangents[ 1 ];
					t3 = vertexTangents[ 2 ];
					t4 = vertexTangents[ 3 ];
1597

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

1603 1604 1605 1606
					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 已提交
1607

1608 1609
					tangentArray[ offset_tangent + 8 ]  = t3.x;
					tangentArray[ offset_tangent + 9 ]  = t3.y;
1610 1611
					tangentArray[ offset_tangent + 10 ] = t3.z;
					tangentArray[ offset_tangent + 11 ] = t3.w;
M
Mr.doob 已提交
1612

1613 1614 1615 1616
					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 已提交
1617

1618
					offset_tangent += 16;
M
Mr.doob 已提交
1619

1620
				}
M
Mr.doob 已提交
1621

M
Mr.doob 已提交
1622
				if ( dirtyNormals && normalType ) {
M
Mr.doob 已提交
1623

1624
					if ( vertexNormals.length == 4 && needsSmoothNormals ) {
1625

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

1628
							vn = vertexNormals[ i ];
M
Mr.doob 已提交
1629

1630 1631 1632
							normalArray[ offset_normal ]     = vn.x;
							normalArray[ offset_normal + 1 ] = vn.y;
							normalArray[ offset_normal + 2 ] = vn.z;
M
Mr.doob 已提交
1633

1634
							offset_normal += 3;
M
Mr.doob 已提交
1635

1636
						}
M
Mr.doob 已提交
1637

1638
					} else {
1639

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

1642 1643 1644
							normalArray[ offset_normal ]     = faceNormal.x;
							normalArray[ offset_normal + 1 ] = faceNormal.y;
							normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
1645

1646
							offset_normal += 3;
M
Mr.doob 已提交
1647

1648
						}
M
Mr.doob 已提交
1649 1650

					}
M
Mr.doob 已提交
1651

1652 1653
				}

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

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

1658
						uvi = uv[ i ];
M
Mr.doob 已提交
1659

1660 1661
						uvArray[ offset_uv ]     = uvi.u;
						uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
1662

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

M
Mr.doob 已提交
1665
					}
1666 1667

				}
1668

A
alteredq 已提交
1669
				if ( dirtyUvs && uv2 !== undefined && uvType ) {
1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682

					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 已提交
1683

1684
				if ( dirtyElements ) {
M
Mr.doob 已提交
1685

1686
					faceArray[ offset_face ]     = vertexIndex;
1687 1688
					faceArray[ offset_face + 1 ] = vertexIndex + 1;
					faceArray[ offset_face + 2 ] = vertexIndex + 3;
M
Mr.doob 已提交
1689

1690 1691 1692
					faceArray[ offset_face + 3 ] = vertexIndex + 1;
					faceArray[ offset_face + 4 ] = vertexIndex + 2;
					faceArray[ offset_face + 5 ] = vertexIndex + 3;
M
Mr.doob 已提交
1693

1694
					offset_face += 6;
M
Mr.doob 已提交
1695

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

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

1702 1703
					lineArray[ offset_line + 4 ] = vertexIndex + 1;
					lineArray[ offset_line + 5 ] = vertexIndex + 2;
M
Mr.doob 已提交
1704

1705 1706
					lineArray[ offset_line + 6 ] = vertexIndex + 2;
					lineArray[ offset_line + 7 ] = vertexIndex + 3;
M
Mr.doob 已提交
1707

1708
					offset_line += 8;
M
Mr.doob 已提交
1709

1710
					vertexIndex += 4;
M
Mr.doob 已提交
1711

1712
				}
M
Mr.doob 已提交
1713

1714
			}
M
Mr.doob 已提交
1715

1716 1717
		}

1718 1719 1720 1721
		if ( obj_edgeFaces ) {

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

M
Mikael Emtinger 已提交
1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732
				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;
			}

1733
		}
M
Mikael Emtinger 已提交
1734

1735
		if ( dirtyVertices ) {
M
Mr.doob 已提交
1736

1737
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
1738
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
M
Mr.doob 已提交
1739

1740
		}
M
Mr.doob 已提交
1741

1742
		if ( customAttributes ) {
M
Mr.doob 已提交
1743

1744
			for ( a in customAttributes ) {
M
Mr.doob 已提交
1745

1746 1747
				customAttribute = customAttributes[ a ];

M
Mr.doob 已提交
1748
				if ( customAttribute.needsUpdate ) {
1749 1750 1751 1752

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

M
Mr.doob 已提交
1753
					customAttribute.needsUpdate = false;
1754

1755 1756 1757 1758 1759 1760
				}

			}

		}

1761
		if ( dirtyMorphTargets ) {
1762 1763 1764 1765

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

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

1768 1769 1770
			}
		}

1771
		if ( dirtyColors && offset_color > 0 ) {
1772

1773
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
1774 1775 1776
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}
1777

1778
		if ( dirtyNormals ) {
M
Mr.doob 已提交
1779

1780
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
1781
			_gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
M
Mr.doob 已提交
1782

1783 1784
		}

1785
		if ( dirtyTangents && geometry.hasTangents ) {
1786

1787
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
1788
			_gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint );
M
Mr.doob 已提交
1789

1790
		}
1791

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

1794
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
1795
			_gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
M
Mr.doob 已提交
1796

1797
		}
M
Mr.doob 已提交
1798

1799 1800
		if ( dirtyUvs && offset_uv2 > 0 ) {

1801
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
1802 1803 1804 1805
			_gl.bufferData( _gl.ARRAY_BUFFER, uv2Array, hint );

		}

1806
		if ( dirtyElements ) {
M
Mr.doob 已提交
1807

1808
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
1809
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint );
1810

1811
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
1812
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
M
Mr.doob 已提交
1813

1814
		}
1815

1816
		if ( offset_skin > 0 ) {
1817

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

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

1824
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
A
alteredq 已提交
1825 1826
			_gl.bufferData( _gl.ARRAY_BUFFER, skinIndexArray, hint );

1827
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
A
alteredq 已提交
1828
			_gl.bufferData( _gl.ARRAY_BUFFER, skinWeightArray, hint );
1829

A
alteredq 已提交
1830
		}
1831 1832

	};
1833

1834
	function setLineBuffers ( geometry, hint ) {
M
Mr.doob 已提交
1835

1836
		var v, c, vertex, offset,
1837 1838 1839 1840
		vertices = geometry.vertices,
		colors = geometry.colors,
		vl = vertices.length,
		cl = colors.length,
M
Mr.doob 已提交
1841

1842 1843
		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,
1844

1845 1846
		dirtyVertices = geometry.__dirtyVertices,
		dirtyColors = geometry.__dirtyColors;
M
Mr.doob 已提交
1847

1848
		if ( dirtyVertices ) {
M
Mr.doob 已提交
1849

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

1852
				vertex = vertices[ v ].position;
M
Mr.doob 已提交
1853

1854
				offset = v * 3;
M
Mr.doob 已提交
1855

1856 1857 1858
				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;
M
Mr.doob 已提交
1859

1860 1861
			}

1862
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
A
alteredq 已提交
1863 1864
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );

1865
		}
M
Mr.doob 已提交
1866

1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880
		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;

			}

1881
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
1882 1883 1884 1885
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}

1886
	};
M
Mr.doob 已提交
1887

1888
	function setRibbonBuffers ( geometry, hint ) {
A
alteredq 已提交
1889 1890

		var v, c, vertex, offset,
1891 1892 1893 1894
		vertices = geometry.vertices,
		colors = geometry.colors,
		vl = vertices.length,
		cl = colors.length,
A
alteredq 已提交
1895

1896 1897
		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,
1898

1899 1900
		dirtyVertices = geometry.__dirtyVertices,
		dirtyColors = geometry.__dirtyColors;
A
alteredq 已提交
1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915

		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;

			}

1916
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
A
alteredq 已提交
1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934
			_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;

			}

1935
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
A
alteredq 已提交
1936 1937 1938 1939 1940
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}

	};
1941

1942
	function setParticleBuffers ( geometry, hint, object ) {
1943

A
alteredq 已提交
1944
		var v, c, vertex, offset,
1945 1946
		vertices = geometry.vertices,
		vl = vertices.length,
1947

1948 1949
		colors = geometry.colors,
		cl = colors.length,
1950

1951 1952
		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,
1953

1954
		sortArray = geometry.__sortArray,
1955

1956 1957 1958
		dirtyVertices = geometry.__dirtyVertices,
		dirtyElements = geometry.__dirtyElements,
		dirtyColors = geometry.__dirtyColors;
1959

1960
		if ( object.sortParticles ) {
1961

1962
			_projScreenMatrix.multiplySelf( object.matrixWorld );
1963

1964 1965 1966
			for ( v = 0; v < vl; v++ ) {

				vertex = vertices[ v ].position;
1967

1968 1969
				_vector3.copy( vertex );
				_projScreenMatrix.multiplyVector3( _vector3 );
1970

1971
				sortArray[ v ] = [ _vector3.z, v ];
1972

1973
			}
1974

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

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

1979
				vertex = vertices[ sortArray[v][1] ].position;
1980

1981
				offset = v * 3;
1982

1983 1984 1985
				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;
1986

1987
			}
1988

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

A
alteredq 已提交
1991
				offset = c * 3;
1992

A
alteredq 已提交
1993 1994 1995 1996 1997
				color = colors[ sortArray[c][1] ];

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

1999
			}
2000 2001


2002
		} else {
2003

2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016
			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;

				}
2017 2018

			}
2019

A
alteredq 已提交
2020
			if ( dirtyColors ) {
2021

A
alteredq 已提交
2022 2023 2024 2025 2026 2027 2028 2029 2030 2031
				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;

2032
				}
2033

A
alteredq 已提交
2034
			}
2035 2036

		}
2037

A
alteredq 已提交
2038
		if ( dirtyVertices || object.sortParticles ) {
2039

2040
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
A
alteredq 已提交
2041
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
2042

A
alteredq 已提交
2043
		}
2044

A
alteredq 已提交
2045
		if ( dirtyColors || object.sortParticles ) {
2046

2047
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
A
alteredq 已提交
2048
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
2049

A
alteredq 已提交
2050
		}
2051

2052
	};
M
Mr.doob 已提交
2053

2054
	function setMaterialShaders( material, shaders ) {
2055

2056
		material.uniforms = THREE.UniformsUtils.clone( shaders.uniforms );
2057 2058
		material.vertexShader = shaders.vertexShader;
		material.fragmentShader = shaders.fragmentShader;
2059

M
Mr.doob 已提交
2060
	};
2061

2062
	function refreshUniformsCommon( uniforms, material ) {
M
Mr.doob 已提交
2063

M
Mr.doob 已提交
2064
		uniforms.diffuse.value = material.color;
A
alteredq 已提交
2065 2066
		uniforms.opacity.value = material.opacity;
		uniforms.map.texture = material.map;
2067

2068
		uniforms.lightMap.texture = material.lightMap;
2069

2070
		uniforms.envMap.texture = material.envMap;
A
alteredq 已提交
2071
		uniforms.reflectivity.value = material.reflectivity;
2072
		uniforms.refractionRatio.value = material.refractionRatio;
A
alteredq 已提交
2073
		uniforms.combine.value = material.combine;
2074
		uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
2075

2076
	};
2077

2078
	function refreshUniformsLine( uniforms, material ) {
2079

M
Mr.doob 已提交
2080
		uniforms.diffuse.value = material.color;
A
alteredq 已提交
2081
		uniforms.opacity.value = material.opacity;
2082 2083

	};
M
Mr.doob 已提交
2084

2085
	function refreshUniformsParticle( uniforms, material ) {
2086

M
Mr.doob 已提交
2087
		uniforms.psColor.value = material.color;
A
alteredq 已提交
2088 2089
		uniforms.opacity.value = material.opacity;
		uniforms.size.value = material.size;
M
Mr.doob 已提交
2090
		uniforms.scale.value = _canvas.height / 2.0; // TODO: Cache this.
A
alteredq 已提交
2091
		uniforms.map.texture = material.map;
2092

A
alteredq 已提交
2093
	};
2094

2095
	function refreshUniformsFog( uniforms, fog ) {
2096

M
Mr.doob 已提交
2097
		uniforms.fogColor.value = fog.color;
2098

A
alteredq 已提交
2099
		if ( fog instanceof THREE.Fog ) {
2100

A
alteredq 已提交
2101 2102
			uniforms.fogNear.value = fog.near;
			uniforms.fogFar.value = fog.far;
2103

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

A
alteredq 已提交
2106
			uniforms.fogDensity.value = fog.density;
2107 2108

		}
2109

2110 2111
	};

2112
	function refreshUniformsPhong( uniforms, material ) {
M
Mr.doob 已提交
2113

M
Mr.doob 已提交
2114 2115
		uniforms.ambient.value = material.ambient;
		uniforms.specular.value = material.specular;
A
alteredq 已提交
2116
		uniforms.shininess.value = material.shininess;
M
Mr.doob 已提交
2117

2118
	};
M
Mr.doob 已提交
2119 2120


2121
	function refreshUniformsLights( uniforms, lights ) {
M
Mr.doob 已提交
2122

A
alteredq 已提交
2123 2124
		uniforms.enableLighting.value = lights.directional.length + lights.point.length;
		uniforms.ambientLightColor.value = lights.ambient;
2125

A
alteredq 已提交
2126 2127
		uniforms.directionalLightColor.value = lights.directional.colors;
		uniforms.directionalLightDirection.value = lights.directional.positions;
2128

A
alteredq 已提交
2129 2130
		uniforms.pointLightColor.value = lights.point.colors;
		uniforms.pointLightPosition.value = lights.point.positions;
2131
		uniforms.pointLightDistance.value = lights.point.distances;
M
Mr.doob 已提交
2132

A
alteredq 已提交
2133
	};
M
Mr.doob 已提交
2134

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

2137
		var u, a, identifiers, i, parameters, maxLightCount, maxBones, shaderID;
2138

A
alteredq 已提交
2139
		if ( material instanceof THREE.MeshDepthMaterial ) {
2140

2141
			shaderID = 'depth';
2142

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

2145
			shaderID = 'shadowVolumeDynamic';
M
Mikael Emtinger 已提交
2146

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

2149
			shaderID = 'normal';
2150

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

2153
			shaderID = 'basic';
2154

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

2157
			shaderID = 'lambert';
M
Mr.doob 已提交
2158

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

2161
			shaderID = 'phong';
M
Mr.doob 已提交
2162

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

2165
			shaderID = 'basic';
2166

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

2169 2170 2171 2172 2173 2174 2175
			shaderID = 'particle_basic';

		}

		if ( shaderID ) {

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

A
alteredq 已提交
2177
		}
2178

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

2182
		maxLightCount = allocateLights( lights, 4 );
2183

2184
		maxBones = allocateBones( object );
M
Mr.doob 已提交
2185

2186
		parameters = {
2187 2188
			map: !!material.map, envMap: !!material.envMap, lightMap: !!material.lightMap, 
			vertexColors: material.vertexColors,
2189 2190 2191
			fog: fog, sizeAttenuation: material.sizeAttenuation,
			skinning: material.skinning,
			morphTargets: material.morphTargets,
2192
			maxMorphTargets: this.maxMorphTargets,
2193 2194 2195
			maxDirLights: maxLightCount.directional, maxPointLights: maxLightCount.point,
			maxBones: maxBones
		};
M
Mikael Emtinger 已提交
2196

2197
		material.program = buildProgram( shaderID, material.fragmentShader, material.vertexShader, material.uniforms, material.attributes, parameters );
2198

2199
		var attributes = material.program.attributes;
2200

2201
		_gl.enableVertexAttribArray( attributes.position );
2202

2203 2204 2205
		if ( attributes.color >= 0 ) _gl.enableVertexAttribArray( attributes.color );
		if ( attributes.normal >= 0 ) _gl.enableVertexAttribArray( attributes.normal );
		if ( attributes.tangent >= 0 ) _gl.enableVertexAttribArray( attributes.tangent );
2206

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

2211 2212 2213 2214
			_gl.enableVertexAttribArray( attributes.skinVertexA );
			_gl.enableVertexAttribArray( attributes.skinVertexB );
			_gl.enableVertexAttribArray( attributes.skinIndex );
			_gl.enableVertexAttribArray( attributes.skinWeight );
2215

2216
		}
2217

2218
		for ( a in material.attributes ) {
2219

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

2222
		}
2223 2224


2225
		if ( material.morphTargets ) {
2226

2227
			material.numSupportedMorphTargets = 0;
2228

2229

2230
			if ( attributes.morphTarget0 >= 0 ) {
2231

2232 2233
				_gl.enableVertexAttribArray( attributes.morphTarget0 );
				material.numSupportedMorphTargets ++;
2234

2235
			}
2236

2237
			if ( attributes.morphTarget1 >= 0 ) {
2238

2239 2240
				_gl.enableVertexAttribArray( attributes.morphTarget1 );
				material.numSupportedMorphTargets ++;
2241

2242
			}
2243

2244
			if ( attributes.morphTarget2 >= 0 ) {
2245

2246 2247
				_gl.enableVertexAttribArray( attributes.morphTarget2 );
				material.numSupportedMorphTargets ++;
2248

2249
			}
2250

2251
			if ( attributes.morphTarget3 >= 0 ) {
2252

2253 2254
				_gl.enableVertexAttribArray( attributes.morphTarget3 );
				material.numSupportedMorphTargets ++;
2255

2256
			}
2257

2258
			if ( attributes.morphTarget4 >= 0 ) {
2259

2260 2261
				_gl.enableVertexAttribArray( attributes.morphTarget4 );
				material.numSupportedMorphTargets ++;
2262

2263
			}
2264

2265
			if ( attributes.morphTarget5 >= 0 ) {
2266

2267 2268
				_gl.enableVertexAttribArray( attributes.morphTarget5 );
				material.numSupportedMorphTargets ++;
2269

2270
			}
2271

2272
			if ( attributes.morphTarget6 >= 0 ) {
2273

2274 2275
				_gl.enableVertexAttribArray( attributes.morphTarget6 );
				material.numSupportedMorphTargets ++;
2276

2277
			}
2278

2279
			if ( attributes.morphTarget7 >= 0 ) {
2280

2281 2282
				_gl.enableVertexAttribArray( attributes.morphTarget7 );
				material.numSupportedMorphTargets ++;
2283

2284
			}
2285

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

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

2290
				object.__webglMorphTargetInfluences[ i ] = 0;
2291 2292 2293

			}

2294
		}
M
Mr.doob 已提交
2295

2296
	};
2297

2298
	function setProgram( camera, lights, fog, material, object ) {
2299

2300
		if ( ! material.program ) {
2301 2302 2303 2304

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

		}
M
Mr.doob 已提交
2305

2306
		var program = material.program,
A
alteredq 已提交
2307 2308
			p_uniforms = program.uniforms,
			m_uniforms = material.uniforms;
2309

2310
		if ( program != _currentProgram ) {
M
Mr.doob 已提交
2311

M
Mr.doob 已提交
2312
			_gl.useProgram( program );
2313
			_currentProgram = program;
2314

M
Mr.doob 已提交
2315
		}
2316

2317 2318
		_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, _projectionMatrixArray );

A
alteredq 已提交
2319
		// refresh uniforms common to several materials
2320 2321

		if ( fog && (
A
alteredq 已提交
2322 2323
			 material instanceof THREE.MeshBasicMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
2324
			 material instanceof THREE.MeshPhongMaterial ||
A
alteredq 已提交
2325
			 material instanceof THREE.LineBasicMaterial ||
2326 2327
			 material instanceof THREE.ParticleBasicMaterial ||
			 material.fog )
A
alteredq 已提交
2328
			) {
2329

A
alteredq 已提交
2330
			refreshUniformsFog( m_uniforms, fog );
2331 2332

		}
M
Mr.doob 已提交
2333

M
Mr.doob 已提交
2334
		if ( material instanceof THREE.MeshPhongMaterial ||
2335 2336
			 material instanceof THREE.MeshLambertMaterial ||
			 material.lights ) {
2337

A
alteredq 已提交
2338
			setupLights( program, lights );
A
alteredq 已提交
2339
			refreshUniformsLights( m_uniforms, _lights );
M
Mr.doob 已提交
2340 2341 2342

		}

2343 2344 2345
		if ( material instanceof THREE.MeshBasicMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
			 material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
2346

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

A
alteredq 已提交
2349
		}
M
Mr.doob 已提交
2350

A
alteredq 已提交
2351
		// refresh single material specific uniforms
2352

2353
		if ( material instanceof THREE.LineBasicMaterial ) {
M
Mr.doob 已提交
2354

A
alteredq 已提交
2355
			refreshUniformsLine( m_uniforms, material );
2356

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

A
alteredq 已提交
2359
			refreshUniformsParticle( m_uniforms, material );
2360

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

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

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

2367 2368
			m_uniforms.mNear.value = camera.near;
			m_uniforms.mFar.value = camera.far;
A
alteredq 已提交
2369
			m_uniforms.opacity.value = material.opacity;
2370

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

A
alteredq 已提交
2373
			m_uniforms.opacity.value = material.opacity;
2374
		}
2375

A
alteredq 已提交
2376
		// load common uniforms
2377

A
alteredq 已提交
2378 2379
		loadUniformsGeneric( program, m_uniforms );
		loadUniformsMatrices( p_uniforms, object );
2380

A
alteredq 已提交
2381 2382
		// load material specific uniforms
		// (shader material also gets them for the sake of genericity)
2383

A
alteredq 已提交
2384 2385
		if ( material instanceof THREE.MeshShaderMaterial ||
			 material instanceof THREE.MeshPhongMaterial ||
2386
			 material.envMap ) {
2387

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

2390
		}
2391

A
alteredq 已提交
2392
		if ( material instanceof THREE.MeshShaderMaterial ||
2393
			 material.envMap ||
2394
			 material.skinning ) {
2395

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

A
alteredq 已提交
2398
		}
2399

A
alteredq 已提交
2400 2401
		if ( material instanceof THREE.MeshPhongMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
A
alteredq 已提交
2402
			 material instanceof THREE.MeshShaderMaterial ||
2403 2404
			 material.skinning ) {

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

A
alteredq 已提交
2407
		}
2408

2409 2410
		if ( material instanceof THREE.ShadowVolumeDynamicMaterial ) {

M
Mikael Emtinger 已提交
2411
			var dirLight = m_uniforms.directionalLightDirection.value;
2412

2413 2414 2415
			dirLight[ 0 ] = -lights[ 1 ].position.x;
			dirLight[ 1 ] = -lights[ 1 ].position.y;
			dirLight[ 2 ] = -lights[ 1 ].position.z;
2416

M
Mikael Emtinger 已提交
2417 2418 2419 2420 2421 2422
			_gl.uniform3fv( p_uniforms.directionalLightDirection, dirLight );
			_gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object._objectMatrixArray );
			_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, _viewMatrixArray );
		}


2423
		if ( material.skinning ) {
2424

2425
			loadUniformsSkinning( p_uniforms, object );
2426

A
alteredq 已提交
2427
		}
2428

A
alteredq 已提交
2429
		return program;
2430

A
alteredq 已提交
2431
	};
2432

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

2435 2436
		if ( material.opacity == 0 ) return;

2437
		var program, attributes, linewidth, primitives, a, attribute;
A
alteredq 已提交
2438

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

2441
		attributes = program.attributes;
M
Mr.doob 已提交
2442

2443
		// vertices
M
Mr.doob 已提交
2444

2445
		if ( !material.morphTargets ) {
2446 2447

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

2450
		} else {
2451

M
Mikael Emtinger 已提交
2452
			setupMorphTargets( material, geometryGroup, object );
2453

2454 2455
		}

2456 2457 2458 2459

		// custom attributes

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

2461
			for( a in geometryGroup.__webglCustomAttributes ) {
M
Mr.doob 已提交
2462

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

2465
					attribute = geometryGroup.__webglCustomAttributes[ a ];
M
Mr.doob 已提交
2466

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

2470
				}
M
Mr.doob 已提交
2471

2472
			}
M
Mr.doob 已提交
2473

2474 2475 2476
		}


A
alteredq 已提交
2477 2478 2479 2480
		// colors

		if ( attributes.color >= 0 ) {

2481
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
2482
			_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
2483 2484 2485

		}

2486
		// normals
M
Mr.doob 已提交
2487

2488
		if ( attributes.normal >= 0 ) {
2489

2490
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
2491
			_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
2492

2493
		}
2494

2495 2496 2497
		// tangents

		if ( attributes.tangent >= 0 ) {
2498

2499
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
2500
			_gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
2501

2502
		}
2503

2504
		// uvs
M
Mr.doob 已提交
2505

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

2508
			if ( geometryGroup.__webglUVBuffer ) {
2509

2510
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
2511
				_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
2512

2513
				_gl.enableVertexAttribArray( attributes.uv );
2514

2515
			} else {
2516

2517
				_gl.disableVertexAttribArray( attributes.uv );
M
Mr.doob 已提交
2518

2519
			}
2520 2521 2522

		}

2523 2524
		if ( attributes.uv2 >= 0 ) {

2525
			if ( geometryGroup.__webglUV2Buffer ) {
2526

2527
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539
				_gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );

				_gl.enableVertexAttribArray( attributes.uv2 );

			} else {

				_gl.disableVertexAttribArray( attributes.uv2 );

			}

		}

2540
		if ( material.skinning &&
2541
			 attributes.skinVertexA >= 0 && attributes.skinVertexB >= 0 &&
A
alteredq 已提交
2542
			 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
2543

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

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

2550
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
A
alteredq 已提交
2551 2552
			_gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 );

2553
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
A
alteredq 已提交
2554
			_gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 );
2555

A
alteredq 已提交
2556
		}
2557

2558
		// render mesh
M
Mr.doob 已提交
2559

2560
		if ( object instanceof THREE.Mesh ) {
2561

2562
			// wireframe
2563

2564
			if ( material.wireframe ) {
M
Mr.doob 已提交
2565

2566
				_gl.lineWidth( material.wireframeLinewidth );
2567 2568
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
				_gl.drawElements( _gl.LINES, geometryGroup.__webglLineCount, _gl.UNSIGNED_SHORT, 0 );
2569

2570
			// triangles
2571

2572
			} else {
2573

2574 2575 2576
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
				_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );

2577
			}
2578

2579
		// render lines
2580

2581
		} else if ( object instanceof THREE.Line ) {
2582

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

2585
			_gl.lineWidth( material.linewidth );
2586
			_gl.drawArrays( primitives, 0, geometryGroup.__webglLineCount );
2587

2588
		// render particles
2589

2590
		} else if ( object instanceof THREE.ParticleSystem ) {
2591

2592
			_gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webglParticleCount );
2593

A
alteredq 已提交
2594
		// render ribbon
2595

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

2598
			_gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webglVertexCount );
2599

2600 2601 2602 2603
		}

	};

M
Mikael Emtinger 已提交
2604

M
Mikael Emtinger 已提交
2605
	function setupMorphTargets( material, geometryGroup, object ) {
2606

M
Mikael Emtinger 已提交
2607
		// set base
2608

M
Mikael Emtinger 已提交
2609
		var attributes = material.program.attributes;
2610

2611
		if (  object.morphTargetBase !== - 1 ) {
2612 2613

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

M
Mikael Emtinger 已提交
2616
		} else {
2617 2618

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

M
Mikael Emtinger 已提交
2621
		}
2622

2623
		if ( object.morphTargetForcedOrder.length ) {
M
Mikael Emtinger 已提交
2624 2625

			// set forced order
2626

M
Mikael Emtinger 已提交
2627 2628 2629
			var m = 0;
			var order = object.morphTargetForcedOrder;
			var influences = object.morphTargetInfluences;
2630 2631 2632 2633

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

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

2636 2637 2638 2639
				object.__webglMorphTargetInfluences[ m ] = influences[ order[ m ]];

				m ++;
			}
2640

M
Mikael Emtinger 已提交
2641
		} else {
2642

M
Mikael Emtinger 已提交
2643
			// find most influencing
2644

M
Mikael Emtinger 已提交
2645
			var used = [];
2646
			var candidateInfluence = - 1;
M
Mikael Emtinger 已提交
2647 2648 2649 2650
			var candidate = 0;
			var influences = object.morphTargetInfluences;
			var i, il = influences.length;
			var m = 0;
2651

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

M
Mikael Emtinger 已提交
2654
				used[ object.morphTargetBase ] = true;
2655

M
Mikael Emtinger 已提交
2656
			}
2657 2658 2659

			while ( m < material.numSupportedMorphTargets ) {

2660
				for ( i = 0; i < il; i ++ ) {
2661 2662 2663

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

M
Mikael Emtinger 已提交
2664 2665
						candidate = i;
						candidateInfluence = influences[ candidate ];
2666

M
Mikael Emtinger 已提交
2667 2668
					}
				}
2669 2670

				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ candidate ] );
M
Mikael Emtinger 已提交
2671
				_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
2672 2673 2674

				object.__webglMorphTargetInfluences[ m ] = candidateInfluence;

M
Mikael Emtinger 已提交
2675 2676
				used[ candidate ] = 1;
				candidateInfluence = -1;
2677
				m ++;
M
Mikael Emtinger 已提交
2678 2679 2680 2681
			}
		}

		// load updated influences uniform
2682

2683
		_gl.uniform1fv( material.program.uniforms.morphTargetInfluences, object.__webglMorphTargetInfluences );
M
Mikael Emtinger 已提交
2684 2685 2686
	}


2687
	function renderBufferImmediate( object, program, shading ) {
2688

2689 2690
		if ( ! object.__webglVertexBuffer ) object.__webglVertexBuffer = _gl.createBuffer();
		if ( ! object.__webglNormalBuffer ) object.__webglNormalBuffer = _gl.createBuffer();
2691

A
alteredq 已提交
2692
		if ( object.hasPos ) {
2693

2694 2695 2696 2697
			_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 );
2698

A
alteredq 已提交
2699
		}
2700

A
alteredq 已提交
2701
		if ( object.hasNormal ) {
2702

2703
			_gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglNormalBuffer );
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 2742 2743 2744 2745 2746 2747

			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;

				}

			}

2748 2749 2750
			_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 );
2751

A
alteredq 已提交
2752
		}
2753

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

A
alteredq 已提交
2756
		object.count = 0;
2757

A
alteredq 已提交
2758
	};
2759

2760
	function setObjectFaces( object ) {
2761

2762
		if ( _oldDoubleSided != object.doubleSided ) {
2763

2764
			if( object.doubleSided ) {
2765

2766
				_gl.disable( _gl.CULL_FACE );
2767

2768
			} else {
2769

A
alteredq 已提交
2770
				_gl.enable( _gl.CULL_FACE );
2771

A
alteredq 已提交
2772
			}
2773

2774
			_oldDoubleSided = object.doubleSided;
2775

2776
		}
2777

2778
		if ( _oldFlipSided != object.flipSided ) {
2779

2780 2781 2782 2783
			if( object.flipSided ) {

				_gl.frontFace( _gl.CW );

2784
			} else {
2785 2786 2787 2788

				_gl.frontFace( _gl.CCW );

			}
2789

2790
			_oldFlipSided = object.flipSided;
2791 2792

		}
2793

2794
	};
2795

2796
	function setDepthTest( test ) {
2797

A
alteredq 已提交
2798 2799 2800
		if ( _oldDepth != test ) {

			if( test ) {
2801

A
alteredq 已提交
2802
				_gl.enable( _gl.DEPTH_TEST );
2803

A
alteredq 已提交
2804
			} else {
2805

A
alteredq 已提交
2806
				_gl.disable( _gl.DEPTH_TEST );
2807

A
alteredq 已提交
2808
			}
2809

A
alteredq 已提交
2810 2811 2812
			_oldDepth = test;

		}
2813

A
alteredq 已提交
2814
	};
2815

2816
	function computeFrustum( m ) {
2817 2818 2819 2820 2821 2822 2823 2824 2825

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

A
alteredq 已提交
2827
		for ( i = 0; i < 6; i ++ ) {
2828 2829 2830 2831 2832 2833 2834

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

		}

	};
2835

2836
	function isInFrustum( object ) {
2837

2838
		var distance, matrix = object.matrixWorld,
2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850
		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;

	};
2851

2852
	function addToFixedArray( where, what ) {
2853

2854 2855
		where.list[ where.count ] = what;
		where.count += 1;
2856

2857
	};
2858

2859
	function unrollImmediateBufferMaterials( globject ) {
2860

2861 2862 2863 2864 2865 2866 2867
		var i, l, m, ml, material,
			object = globject.object,
			opaque = globject.opaque,
			transparent = globject.transparent;

		transparent.count = 0;
		opaque.count = 0;
2868

2869 2870 2871
		for ( m = 0, ml = object.materials.length; m < ml; m++ ) {

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

2874
		}
2875

2876
	};
2877

2878
	function unrollBufferMaterials( globject ) {
2879

2880 2881 2882 2883 2884 2885 2886 2887
		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;
2888

2889 2890 2891 2892 2893 2894 2895 2896 2897
		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 ];
2898
					if ( material ) material.transparent ? addToFixedArray( transparent, material ) : addToFixedArray( opaque, material );
2899 2900 2901 2902 2903 2904

				}

			} else {

				material = meshMaterial;
2905
				if ( material ) material.transparent ? addToFixedArray( transparent, material ) : addToFixedArray( opaque, material );
2906

2907 2908 2909
			}

		}
2910

2911
	};
2912 2913


2914
	function painterSort( a, b ) {
2915

2916
		return b.z - a.z;
2917 2918

	};
2919

2920
	this.render = function( scene, camera, renderTarget, forceClear ) {
2921

A
alteredq 已提交
2922
		var i, program, opaque, transparent, material,
2923
			o, ol, oil, webglObject, object, buffer,
A
alteredq 已提交
2924
			lights = scene.lights,
N
Nicholas Kinsey 已提交
2925
			fog = scene.fog;
2926

M
Mr.doob 已提交
2927
		camera.matrixAutoUpdate && camera.updateMatrix();
2928

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

M
Mr.doob 已提交
2931
		camera.matrixWorldInverse.flattenToArray( _viewMatrixArray );
2932
		camera.projectionMatrix.flattenToArray( _projectionMatrixArray );
M
Mr.doob 已提交
2933

M
Mr.doob 已提交
2934
		_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
2935
		computeFrustum( _projScreenMatrix );
2936

A
alteredq 已提交
2937
		this.initWebGLObjects( scene );
M
Mr.doob 已提交
2938

A
alteredq 已提交
2939
		setRenderTarget( renderTarget );
M
Mr.doob 已提交
2940

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

2943
			this.clear();
M
Mr.doob 已提交
2944

2945 2946
		}

2947
		// set matrices
2948

2949
		ol = scene.__webglObjects.length;
2950

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

2953 2954
			webglObject = scene.__webglObjects[ o ];
			object = webglObject.object;
M
Mr.doob 已提交
2955

2956
			if ( object.visible ) {
2957 2958

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

2960
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
2961

2962
					setupMatrices( object, camera );
2963

2964
					unrollBufferMaterials( webglObject );
2965

2966
					webglObject.render = true;
2967

2968
					if ( this.sortObjects ) {
2969

2970 2971 2972
						_vector3.copy( object.position );
						_projScreenMatrix.multiplyVector3( _vector3 );

2973
						webglObject.z = _vector3.z;
2974

2975
					}
2976

2977
				} else {
2978

2979
					webglObject.render = false;
2980

2981
				}
2982

2983
			} else {
2984

2985
				webglObject.render = false;
2986

2987
			}
2988

2989
		}
2990

2991
		if ( this.sortObjects ) {
2992

2993
			scene.__webglObjects.sort( painterSort );
2994

2995
		}
2996

2997
		oil = scene.__webglObjectsImmediate.length;
2998

2999
		for ( o = 0; o < oil; o++ ) {
3000

3001 3002
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
3003

3004
			if ( object.visible ) {
3005 3006 3007

				if( object.matrixAutoUpdate ) {

3008
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
3009

A
alteredq 已提交
3010
				}
3011

3012
				setupMatrices( object, camera );
3013

3014
				unrollImmediateBufferMaterials( webglObject );
3015

3016
			}
3017

3018
		}
A
alteredq 已提交
3019

3020 3021
		// opaque pass

3022
		setBlending( THREE.NormalBlending );
3023

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

3026
			webglObject = scene.__webglObjects[ o ];
3027

3028
			if ( webglObject.render ) {
3029

3030 3031 3032
				object = webglObject.object;
				buffer = webglObject.buffer;
				opaque = webglObject.opaque;
3033

3034
				setObjectFaces( object );
3035

3036
				for ( i = 0; i < opaque.count; i ++ ) {
3037

3038
					material = opaque.list[ i ];
3039

3040
					setDepthTest( material.depthTest );
A
alteredq 已提交
3041
					renderBuffer( camera, lights, fog, material, buffer, object );
3042

3043
				}
3044 3045 3046 3047 3048

			}

		}

A
alteredq 已提交
3049
		// opaque pass (immediate simulator)
3050

3051
		for ( o = 0; o < oil; o++ ) {
3052

3053 3054
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
3055

A
alteredq 已提交
3056
			if ( object.visible ) {
3057

3058
				opaque = webglObject.opaque;
3059

3060
				setObjectFaces( object );
3061

3062
				for( i = 0; i < opaque.count; i++ ) {
3063

3064
					material = opaque.list[ i ];
3065

3066
					setDepthTest( material.depthTest );
3067

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

3071
				}
3072

A
alteredq 已提交
3073
			}
3074

A
alteredq 已提交
3075 3076
		}

3077 3078
		// transparent pass

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

3081
			webglObject = scene.__webglObjects[ o ];
3082

3083
			if ( webglObject.render ) {
3084

3085 3086 3087
				object = webglObject.object;
				buffer = webglObject.buffer;
				transparent = webglObject.transparent;
3088

3089
				setObjectFaces( object );
3090

3091
				for ( i = 0; i < transparent.count; i ++ ) {
3092

3093
					material = transparent.list[ i ];
3094

3095
					setBlending( material.blending );
3096
					setDepthTest( material.depthTest );
3097

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

3100
				}
3101

3102
			}
M
Mr.doob 已提交
3103

M
Mr.doob 已提交
3104
		}
M
Mr.doob 已提交
3105

3106
		// transparent pass (immediate simulator)
3107

3108
		for ( o = 0; o < oil; o++ ) {
3109

3110 3111
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
3112

3113
			if ( object.visible ) {
3114

3115
				transparent = webglObject.transparent;
3116

3117
				setObjectFaces( object );
3118

3119
				for ( i = 0; i < transparent.count; i ++ ) {
3120

3121
					material = transparent.list[ i ];
3122

3123
					setBlending( material.blending );
3124
					setDepthTest( material.depthTest );
3125

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

3129
				}
3130

3131
			}
3132

3133
		}
3134

M
Mikael Emtinger 已提交
3135
		// render 2d
3136

M
Mikael Emtinger 已提交
3137
		if ( scene.__webglSprites.length ) {
3138

3139
			renderSprites( scene, camera );
3140

M
Mikael Emtinger 已提交
3141 3142
		}

M
Mikael Emtinger 已提交
3143
		// render stencil shadows
M
Mikael Emtinger 已提交
3144

3145
		if ( stencil && scene.__webglShadowVolumes.length && scene.lights.length ) {
M
Mikael Emtinger 已提交
3146 3147

			renderStencilShadows( scene );
3148

M
Mikael Emtinger 已提交
3149 3150
		}

3151

3152
		// render lens flares
3153 3154 3155

		if ( scene.__webglLensFlares.length ) {

3156
			renderLensFlares( scene, camera );
3157

3158 3159
		}

M
Mikael Emtinger 已提交
3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182

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

M
Mikael Emtinger 已提交
3184 3185 3186 3187 3188
		// setup stencil

		_gl.enable( _gl.POLYGON_OFFSET_FILL );
		_gl.polygonOffset( 0.1, 1.0 );
		_gl.enable( _gl.STENCIL_TEST );
3189
		_gl.enable( _gl.DEPTH_TEST );
M
Mikael Emtinger 已提交
3190 3191
		_gl.depthMask( false );
		_gl.colorMask( false, false, false, false );
3192

M
Mikael Emtinger 已提交
3193 3194 3195 3196
		_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 );

3197

M
Mikael Emtinger 已提交
3198
		// loop through all directional lights
3199

M
Mikael Emtinger 已提交
3200 3201
		var l, ll = scene.lights.length;
		var p;
M
Mikael Emtinger 已提交
3202
		var light, lights = scene.lights;
3203
		var dirLight = [];
M
Mikael Emtinger 已提交
3204
		var object, geometryGroup, material;
3205
		var program;
M
Mikael Emtinger 已提交
3206
		var p_uniforms;
3207 3208
		var m_uniforms;
		var attributes;
M
Mikael Emtinger 已提交
3209
		var o, ol = scene.__webglShadowVolumes.length;
3210 3211 3212

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

M
Mikael Emtinger 已提交
3213
			light = scene.lights[ l ];
3214 3215

			if ( light instanceof THREE.DirectionalLight ) {
M
Mikael Emtinger 已提交
3216 3217 3218 3219 3220 3221

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

				// render all volumes
3222 3223 3224

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

M
Mikael Emtinger 已提交
3225 3226 3227
					object        = scene.__webglShadowVolumes[ o ].object;
					geometryGroup = scene.__webglShadowVolumes[ o ].buffer;
					material      = object.materials[ 0 ];
3228

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

M
Mikael Emtinger 已提交
3231 3232
					program = material.program,
		  			p_uniforms = program.uniforms,
3233 3234
					m_uniforms = material.uniforms,
					attributes = program.attributes;
3235

3236
					if ( _currentProgram !== program ) {
3237

M
Mikael Emtinger 已提交
3238
						_gl.useProgram( program );
M
Mikael Emtinger 已提交
3239
						_currentProgram = program;
3240

M
Mikael Emtinger 已提交
3241 3242 3243 3244
						_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, _projectionMatrixArray );
						_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, _viewMatrixArray );
						_gl.uniform3fv( p_uniforms.directionalLightDirection, dirLight );
					}
3245 3246


M
Mikael Emtinger 已提交
3247 3248
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
					_gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object._objectMatrixArray );
3249 3250


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

M
Mikael Emtinger 已提交
3254
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
M
Mikael Emtinger 已提交
3255
					_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
3256

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

M
Mikael Emtinger 已提交
3259
					_gl.cullFace( _gl.FRONT );
M
Mikael Emtinger 已提交
3260
					_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );
3261

M
Mikael Emtinger 已提交
3262
					_gl.cullFace( _gl.BACK );
M
Mikael Emtinger 已提交
3263
					_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );
3264

M
Mikael Emtinger 已提交
3265
				}
M
Mikael Emtinger 已提交
3266

M
Mikael Emtinger 已提交
3267
			}
M
Mikael Emtinger 已提交
3268

M
Mikael Emtinger 已提交
3269 3270
		}

3271

M
Mikael Emtinger 已提交
3272
		// setup color+stencil
M
Mikael Emtinger 已提交
3273

M
Mikael Emtinger 已提交
3274 3275 3276 3277
		_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 );
3278
		_gl.disable( _gl.DEPTH_TEST );
M
Mikael Emtinger 已提交
3279 3280


3281
		// draw darkening polygon
M
Mr.doob 已提交
3282

M
Mikael Emtinger 已提交
3283
		_oldBlending = "";
M
Mikael Emtinger 已提交
3284
		_currentProgram = _stencilShadow.program;
M
Mr.doob 已提交
3285

M
Mikael Emtinger 已提交
3286 3287 3288
		_gl.useProgram( _stencilShadow.program );
		_gl.uniformMatrix4fv( _stencilShadow.projectionLocation, false, _projectionMatrixArray );
		_gl.uniform1f( _stencilShadow.darknessLocation, _stencilShadow.darkness );
3289

M
Mikael Emtinger 已提交
3290 3291 3292
		_gl.bindBuffer( _gl.ARRAY_BUFFER, _stencilShadow.vertexBuffer );
		_gl.vertexAttribPointer( _stencilShadow.vertexLocation, 3, _gl.FLOAT, false, 0, 0 );
		_gl.enableVertexAttribArray( _stencilShadow.vertexLocation );
M
Mr.doob 已提交
3293

M
Mikael Emtinger 已提交
3294 3295
		_gl.blendFunc( _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
		_gl.blendEquation( _gl.FUNC_ADD );
3296

M
Mikael Emtinger 已提交
3297
		_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _stencilShadow.elementBuffer );
M
Mikael Emtinger 已提交
3298 3299 3300 3301 3302
		_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );


		// disable stencil

3303 3304 3305 3306
		_gl.disable( _gl.STENCIL_TEST );
		_gl.enable( _gl.DEPTH_TEST );
		_gl.depthMask( _currentDepthMask );

M
Mikael Emtinger 已提交
3307
	}
3308

3309

3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328
	/*
	 * Render sprites
	 * 
	 */

	function renderSprites( scene, camera ) {

		var o, ol, object;
		var attributes = _sprite.attributes;
		var uniforms = _sprite.uniforms;
		var anyCustom = false;
		var invAspect = _viewportHeight / _viewportWidth;
		var size, scale = [];
		var screenPosition;
		var halfViewportWidth = _viewportWidth * 0.5;
		var halfViewportHeight = _viewportHeight * 0.5;
		var mergeWith3D = true;

		// setup gl
3329

3330 3331 3332 3333
		_gl.useProgram( _sprite.program );
		_currentProgram = _sprite.program;
		_oldBlending = "";

M
Mr.doob 已提交
3334
		if ( !_spriteAttributesEnabled ) {
3335

M
Mr.doob 已提交
3336 3337
			_gl.enableVertexAttribArray( _sprite.attributes.position );
			_gl.enableVertexAttribArray( _sprite.attributes.uv );
3338

M
Mr.doob 已提交
3339 3340 3341
			_spriteAttributesEnabled = true;

		}
3342

3343
		_gl.disable( _gl.CULL_FACE );
3344
		_gl.enable( _gl.BLEND );
3345
		_gl.depthMask( true );
3346 3347 3348 3349 3350 3351

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

		_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _sprite.elementBuffer );
3352

3353 3354 3355 3356
		_gl.uniformMatrix4fv( uniforms.projectionMatrix, false, _projectionMatrixArray );

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

3358
		// update positions and sort
3359

3360
		for( o = 0, ol = scene.__webglSprites.length; o < ol; o++ ) {
3361

3362
			object = scene.__webglSprites[ o ];
3363

3364
			if( !object.useScreenCoordinates ) {
3365

3366 3367
				object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
				object.z = -object._modelViewMatrix.n34;
3368

3369
			} else {
3370

3371
				object.z = -object.position.z;
3372

3373
			}
3374

3375 3376 3377
		}

		scene.__webglSprites.sort( painterSort );
3378 3379

		// render all non-custom shader sprites
3380 3381

		for ( o = 0, ol = scene.__webglSprites.length; o < ol; o++ ) {
3382 3383 3384

			object = scene.__webglSprites[ o ];

3385 3386 3387 3388 3389
			if ( object.material === undefined ) {

				if ( object.map && object.map.image && object.map.image.width ) {

					if ( object.useScreenCoordinates ) {
3390 3391 3392 3393

						_gl.uniform1i( uniforms.useScreenCoordinates, 1 );
						_gl.uniform3f( uniforms.screenPosition, ( object.position.x - halfViewportWidth  ) / halfViewportWidth, 
														        ( halfViewportHeight - object.position.y ) / halfViewportHeight,
3394
														          Math.max( 0, Math.min( 1, object.position.z )));
3395

3396 3397
					} else {

3398

3399 3400 3401 3402

						_gl.uniform1i( uniforms.useScreenCoordinates, 0 );
						_gl.uniform1i( uniforms.affectedByDistance, object.affectedByDistance ? 1 : 0 );
						_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray );
3403

3404
					}
3405

3406
					size = object.map.image.width / ( object.affectedByDistance ? 1 : _viewportHeight );
3407
					scale[ 0 ] = size * invAspect * object.scale.x;
3408
					scale[ 1 ] = size * object.scale.y;
3409

3410 3411 3412 3413 3414 3415 3416
					_gl.uniform2f( uniforms.uvScale, object.uvScale.x, object.uvScale.y );
					_gl.uniform2f( uniforms.uvOffset, object.uvOffset.x, object.uvOffset.y );
					_gl.uniform2f( uniforms.alignment, object.alignment.x, object.alignment.y );
					_gl.uniform1f( uniforms.opacity, object.opacity );
					_gl.uniform1f( uniforms.rotation, object.rotation );
					_gl.uniform2fv( uniforms.scale, scale );

3417 3418
					if ( object.mergeWith3D && !mergeWith3D ) {

3419 3420
						_gl.enable( _gl.DEPTH_TEST );
						mergeWith3D = true;
3421 3422 3423

					} else if ( !object.mergeWith3D && mergeWith3D ) {

3424 3425
						_gl.disable( _gl.DEPTH_TEST );
						mergeWith3D = false;
3426

3427
					}
3428

3429 3430
					setBlending( object.blending );
					setTexture( object.map, 0 );
3431

3432 3433
					_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
				}
3434

3435
			} else {
3436

3437
				anyCustom = true;
3438

3439
			}
3440

3441 3442 3443 3444 3445
		}


		// loop through all custom

3446 3447 3448
		/*
		if( anyCustom ) {

3449
		}
3450
		*/
3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461

		// restore gl

		_gl.enable( _gl.CULL_FACE );
		_gl.enable( _gl.DEPTH_TEST );
		_gl.depthMask( _currentDepthMask );

	}



3462 3463 3464 3465 3466 3467 3468 3469 3470 3471
	/*
	 * 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 ) {
3472

3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494
		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 已提交
3495
		_currentProgram = _lensFlare.program;
3496 3497 3498
		_oldBlending = "";


M
Mr.doob 已提交
3499 3500 3501 3502 3503 3504 3505 3506 3507
		if ( ! _lensFlareAttributesEnabled ) {
		
			_gl.enableVertexAttribArray( _lensFlare.attributes.vertex );
			_gl.enableVertexAttribArray( _lensFlare.attributes.uv );
			
			_lensFlareAttributesEnabled = true;

		}

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

3511 3512
		_gl.uniform1i( uniforms.occlusionMap, 0 );
		_gl.uniform1i( uniforms.map, 1 );
3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523

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

3524 3525 3526 3527
		_gl.activeTexture( _gl.TEXTURE0 );
		_gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.occlusionTexture );

		_gl.activeTexture( _gl.TEXTURE1 );
3528

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

3531
			// calc object screen position
3532

3533
			object = scene.__webglLensFlares[ o ].object;
3534

3535
			tempPosition.set( object.matrixWorld.n14, object.matrixWorld.n24, object.matrixWorld.n34 );
3536

3537 3538 3539
			camera.matrixWorldInverse.multiplyVector3( tempPosition );
			objectZ = tempPosition.z;
			camera.projectionMatrix.multiplyVector3( tempPosition );
3540 3541


3542
			// setup arrays for gl programs
3543

3544 3545 3546
			screenPosition[ 0 ] = tempPosition.x;
			screenPosition[ 1 ] = tempPosition.y;
			screenPosition[ 2 ] = tempPosition.z;
3547

3548 3549
			screenPositionPixels[ 0 ] = screenPosition[ 0 ] * halfViewportWidth + halfViewportWidth;
			screenPositionPixels[ 1 ] = screenPosition[ 1 ] * halfViewportHeight + halfViewportHeight;
3550

3551

M
Mikael Emtinger 已提交
3552
			// screen cull 
3553
			
3554 3555
			if(	_lensFlare.hasVertexTexture ||
			  ( screenPositionPixels[ 0 ] > 0 &&
3556 3557
				screenPositionPixels[ 0 ] < _viewportWidth &&
				screenPositionPixels[ 1 ] > 0 &&
3558
				screenPositionPixels[ 1 ] < _viewportHeight )) {
3559 3560


3561 3562 3563
				// save current RGB to temp texture
	
				_gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.tempTexture );
3564
				_gl.copyTexImage2D( _gl.TEXTURE_2D, 0, _gl.RGB, screenPositionPixels[ 0 ] - 8, screenPositionPixels[ 1 ] - 8, 16, 16, 0 );
M
Mikael Emtinger 已提交
3565

3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581
	
				// 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 );
	
	
				// copy result to occlusionMap
	
				_gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.occlusionTexture );
3582
				_gl.copyTexImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, screenPositionPixels[ 0 ] - 8, screenPositionPixels[ 1 ] - 8, 16, 16, 0 );
3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606
	
	
				// 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();
	
3607
				}
3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642
	
	
				// 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 );
	
					}
	
				}
			
3643
			}
M
Mr.doob 已提交
3644

3645 3646 3647
		}

		// restore gl
3648

3649 3650
		_gl.enable( _gl.CULL_FACE );
		_gl.enable( _gl.DEPTH_TEST );
3651
		_gl.depthMask( _currentDepthMask );
3652

3653
	};
3654 3655


3656
	function setupMatrices( object, camera ) {
3657

3658 3659
		object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
		THREE.Matrix4.makeInvert3x3( object._modelViewMatrix ).transposeIntoArray( object._normalMatrixArray );
3660

3661
	};
3662

A
alteredq 已提交
3663
	this.initWebGLObjects = function ( scene ) {
3664

3665
		if ( !scene.__webglObjects ) {
3666

3667 3668
			scene.__webglObjects = [];
			scene.__webglObjectsImmediate = [];
M
Mikael Emtinger 已提交
3669
			scene.__webglShadowVolumes = [];
M
Mikael Emtinger 已提交
3670
			scene.__webglLensFlares = [];
M
Mikael Emtinger 已提交
3671
			scene.__webglSprites = [];
3672 3673
		}

M
Mr.doob 已提交
3674
		while ( scene.__objectsAdded.length ) {
3675

M
Mr.doob 已提交
3676 3677
			addObject( scene.__objectsAdded[ 0 ], scene );
			scene.__objectsAdded.splice( 0, 1 );
3678 3679 3680

		}

M
Mr.doob 已提交
3681
		while ( scene.__objectsRemoved.length ) {
3682

M
Mr.doob 已提交
3683 3684
			removeObject( scene.__objectsRemoved[ 0 ], scene );
			scene.__objectsRemoved.splice( 0, 1 );
3685 3686

		}
3687

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

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

M
Mr.doob 已提交
3692
			updateObject( scene.__webglObjects[ o ].object, scene );
A
alteredq 已提交
3693 3694

		}
3695

M
Mikael Emtinger 已提交
3696 3697 3698 3699 3700
		for ( var o = 0, ol = scene.__webglShadowVolumes.length; o < ol; o ++ ) {

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

		}
3701

M
Mikael Emtinger 已提交
3702 3703 3704 3705 3706
		for ( var o = 0, ol = scene.__webglLensFlares.length; o < ol; o ++ ) {

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

		}
A
alteredq 已提交
3707

3708 3709
		/*
		for ( var o = 0, ol = scene.__webglSprites.length; o < ol; o ++ ) {
M
Mikael Emtinger 已提交
3710 3711 3712

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

3713 3714
		}
		*/
M
Mikael Emtinger 已提交
3715

3716
	};
3717

3718
	function addObject( object, scene ) {
3719

3720
		var g, geometry, geometryGroup;
M
Mr.doob 已提交
3721

3722
		if ( object._modelViewMatrix == undefined ) {
3723

3724
			object._modelViewMatrix = new THREE.Matrix4();
3725

3726 3727 3728
			object._normalMatrixArray = new Float32Array( 9 );
			object._modelViewMatrixArray = new Float32Array( 16 );
			object._objectMatrixArray = new Float32Array( 16 );
3729

3730
			object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
3731

3732
		}
A
alteredq 已提交
3733

3734
		if ( object instanceof THREE.Mesh ) {
A
alteredq 已提交
3735

3736 3737 3738 3739 3740 3741 3742 3743
			geometry = object.geometry;

			if ( geometry.geometryGroups == undefined ) {

				sortFacesByMaterial( geometry );

			}

3744
			// create separate VBOs per geometry chunk
A
alteredq 已提交
3745

3746
			for ( g in geometry.geometryGroups ) {
A
alteredq 已提交
3747

3748
				geometryGroup = geometry.geometryGroups[ g ];
M
Mr.doob 已提交
3749

3750
				// initialise VBO on the first access
M
Mr.doob 已提交
3751

3752
				if ( ! geometryGroup.__webglVertexBuffer ) {
M
Mr.doob 已提交
3753

3754 3755
					createMeshBuffers( geometryGroup );
					initMeshBuffers( geometryGroup, object );
A
alteredq 已提交
3756

3757
					geometry.__dirtyVertices = true;
3758
					geometry.__dirtyMorphTargets = true;
3759 3760 3761 3762 3763
					geometry.__dirtyElements = true;
					geometry.__dirtyUvs = true;
					geometry.__dirtyNormals = true;
					geometry.__dirtyTangents = true;
					geometry.__dirtyColors = true;
M
Mr.doob 已提交
3764

3765
				}
3766

3767
				// create separate wrapper per each use of VBO
3768

3769 3770
				if ( object instanceof THREE.ShadowVolume ) {

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

M
Mikael Emtinger 已提交
3773
				} else {
3774

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

M
Mikael Emtinger 已提交
3777
				}
3778

3779
			}
M
Mr.doob 已提交
3780

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

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

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

3787 3788
			geometry = object.geometry;

3789
			if( ! geometry.__webglVertexBuffer ) {
A
alteredq 已提交
3790 3791 3792 3793 3794 3795 3796 3797 3798

				createRibbonBuffers( geometry );
				initRibbonBuffers( geometry );

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

			}

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

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

3803 3804
			geometry = object.geometry;

3805
			if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
3806

3807 3808
				createLineBuffers( geometry );
				initLineBuffers( geometry );
M
Mr.doob 已提交
3809

3810 3811
				geometry.__dirtyVertices = true;
				geometry.__dirtyColors = true;
M
Mr.doob 已提交
3812

3813
			}
M
Mr.doob 已提交
3814

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

A
alteredq 已提交
3817 3818 3819 3820
		} else if ( object instanceof THREE.ParticleSystem ) {

			geometry = object.geometry;

3821
			if ( ! geometry.__webglVertexBuffer ) {
A
alteredq 已提交
3822 3823 3824 3825 3826 3827

				createParticleBuffers( geometry );
				initParticleBuffers( geometry );

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

3829
			}
3830

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

A
alteredq 已提交
3833 3834 3835 3836
		} else if ( THREE.MarchingCubes !== undefined && object instanceof THREE.MarchingCubes ) {

			addBufferImmediate( scene.__webglObjectsImmediate, object );

3837
		} else if ( object instanceof THREE.Sprite ) {
3838

3839 3840
			scene.__webglSprites.push( object );
		}
3841

3842
		/*else if ( object instanceof THREE.Particle ) {
A
alteredq 已提交
3843 3844 3845 3846 3847

		}*/

	};

3848
	function updateObject( object, scene ) {
A
alteredq 已提交
3849

3850
		var g, geometry, geometryGroup, a, customAttributeDirty;
A
alteredq 已提交
3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861

		if ( object instanceof THREE.Mesh ) {

			geometry = object.geometry;

			// check all geometry groups

			for ( g in geometry.geometryGroups ) {

				geometryGroup = geometry.geometryGroups[ g ];

3862 3863
				customAttributeDirty = false;

M
Mr.doob 已提交
3864 3865 3866 3867
				for ( a in geometryGroup.__webglCustomAttributes ) {

					if( geometryGroup.__webglCustomAttributes[ a ].needsUpdate ) {

3868 3869 3870
						customAttributeDirty = true;
						break;
					}
M
Mr.doob 已提交
3871

3872 3873
				}

3874
				if ( geometry.__dirtyVertices || geometry.__dirtyMorphTargets || geometry.__dirtyElements ||
A
alteredq 已提交
3875
					geometry.__dirtyUvs || geometry.__dirtyNormals ||
3876
					geometry.__dirtyColors || geometry.__dirtyTangents || customAttributeDirty ) {
A
alteredq 已提交
3877 3878 3879 3880 3881 3882 3883

					setMeshBuffers( geometryGroup, object, _gl.DYNAMIC_DRAW );

				}

			}

3884
			geometry.__dirtyVertices = false;
3885
			geometry.__dirtyMorphTargets = false;
A
alteredq 已提交
3886 3887 3888 3889
			geometry.__dirtyElements = false;
			geometry.__dirtyUvs = false;
			geometry.__dirtyNormals = false;
			geometry.__dirtyTangents = false;
3890
			geometry.__dirtyColors = false;
M
Mr.doob 已提交
3891

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

3894 3895
			geometry = object.geometry;

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

A
alteredq 已提交
3898
				setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
3899

A
alteredq 已提交
3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911
			}

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

3913
			}
3914

A
alteredq 已提交
3915 3916 3917 3918 3919 3920 3921
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;

		} else if ( object instanceof THREE.ParticleSystem ) {

			geometry = object.geometry;

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

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

3926
			}
M
Mr.doob 已提交
3927

3928 3929
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
M
Mr.doob 已提交
3930

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

A
alteredq 已提交
3933
			// it updates itself in render callback
3934 3935

		} else if ( object instanceof THREE.Particle ) {
3936 3937

		}*/
3938

3939
	};
3940

3941
	function removeObject( object, scene ) {
M
Mr.doob 已提交
3942 3943 3944

		var o, ol, zobject;

3945 3946 3947 3948 3949 3950 3951 3952 3953 3954
		if ( object instanceof THREE.Mesh ) {

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

				zobject = scene.__webglObjects[ o ].object;

				if ( object == zobject ) {

					scene.__webglObjects.splice( o, 1 );
					return;
M
Mr.doob 已提交
3955

3956 3957 3958 3959 3960 3961 3962
				}

			}

		} else if ( object instanceof THREE.Sprite ) {

			for ( o = scene.__webglSprites.length - 1; o >= 0; o -- ) {
M
Mr.doob 已提交
3963

3964
				zobject = scene.__webglSprites[ o ];
M
Mr.doob 已提交
3965

3966 3967 3968 3969 3970 3971
				if ( object == zobject ) {

					scene.__webglSprites.splice( o, 1 );
					return;

				}
M
Mr.doob 已提交
3972 3973 3974 3975

			}

		}
3976 3977

		// add shadows, etc
M
Mr.doob 已提交
3978 3979 3980

	};

3981
	function sortFacesByMaterial( geometry ) {
3982 3983 3984 3985 3986 3987 3988

		// 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 = {};
3989
		var numMorphTargets = geometry.morphTargets !== undefined ? geometry.morphTargets.length : 0;
3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031

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

4032
				geometry.geometryGroups[ ghash ] = { 'faces': [], 'materials': materials, 'vertices': 0, 'numMorphTargets': numMorphTargets };
4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044

			}

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

4045
					geometry.geometryGroups[ ghash ] = { 'faces': [], 'materials': materials, 'vertices': 0, 'numMorphTargets': numMorphTargets };
4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057

				}

			}

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

		}

	};

4058
	function addBuffer( objlist, buffer, object ) {
4059

4060 4061 4062 4063 4064
		objlist.push( {
			buffer: buffer, object: object,
			opaque: { list: [], count: 0 },
			transparent: { list: [], count: 0 }
		} );
M
Mr.doob 已提交
4065

4066
	};
4067

4068
	function addBufferImmediate( objlist, object ) {
4069

4070 4071 4072 4073 4074
		objlist.push( {
			object: object,
			opaque: { list: [], count: 0 },
			transparent: { list: [], count: 0 }
		} );
4075

4076
	};
4077

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

4080
		if ( cullFace ) {
M
Mr.doob 已提交
4081

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

4084
				_gl.frontFace( _gl.CCW );
M
Mr.doob 已提交
4085

4086
			} else {
M
Mr.doob 已提交
4087

4088
				_gl.frontFace( _gl.CW );
M
Mr.doob 已提交
4089

4090
			}
M
Mr.doob 已提交
4091

4092
			if( cullFace == "back" ) {
M
Mr.doob 已提交
4093

4094
				_gl.cullFace( _gl.BACK );
M
Mr.doob 已提交
4095

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

4098
				_gl.cullFace( _gl.FRONT );
M
Mr.doob 已提交
4099

4100
			} else {
M
Mr.doob 已提交
4101

4102
				_gl.cullFace( _gl.FRONT_AND_BACK );
M
Mr.doob 已提交
4103

4104
			}
M
Mr.doob 已提交
4105

4106
			_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
4107

4108
		} else {
M
Mr.doob 已提交
4109

4110
			_gl.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
4111

4112 4113 4114
		}

	};
N
Nicolas Garcia Belmonte 已提交
4115

4116
	this.supportsVertexTextures = function () {
4117

4118
		return maxVertexTextures() > 0;
4119

4120
	};
4121

4122
	function maxVertexTextures() {
4123

4124 4125 4126
		return _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );

	};
4127

4128
	function initGL( antialias, clearColor, clearAlpha, stencil ) {
N
Nicolas Garcia Belmonte 已提交
4129 4130 4131

		try {

M
Mikael Emtinger 已提交
4132
			if ( ! ( _gl = _canvas.getContext( 'experimental-webgl', { antialias: antialias, stencil: stencil } ) ) ) {
N
Nicolas Garcia Belmonte 已提交
4133

4134
				throw 'Error creating WebGL context.';
N
Nicolas Garcia Belmonte 已提交
4135

4136 4137 4138
			}

		} catch ( e ) {
N
Nicolas Garcia Belmonte 已提交
4139

4140
			console.error( e );
N
Nicolas Garcia Belmonte 已提交
4141 4142 4143

		}

4144 4145 4146 4147 4148 4149 4150 4151
		console.log(
			navigator.userAgent + " | " +
			_gl.getParameter( _gl.VERSION ) + " | " +
			_gl.getParameter( _gl.VENDOR ) + " | " +
			_gl.getParameter( _gl.RENDERER ) + " | " +
			_gl.getParameter( _gl.SHADING_LANGUAGE_VERSION )
		);

N
Nicolas Garcia Belmonte 已提交
4152 4153 4154 4155 4156 4157
		_gl.clearColor( 0, 0, 0, 1 );
		_gl.clearDepth( 1 );

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

4158 4159
		_gl.frontFace( _gl.CCW );
		_gl.cullFace( _gl.BACK );
4160
		_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
4161

N
Nicolas Garcia Belmonte 已提交
4162
		_gl.enable( _gl.BLEND );
4163 4164 4165
		_gl.blendEquation( _gl.FUNC_ADD );
		_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA );

4166
		_gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearAlpha );
4167

4168 4169
		// _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, true );

A
alteredq 已提交
4170
		_cullEnabled = true;
N
Nicolas Garcia Belmonte 已提交
4171

4172
	};
M
Mr.doob 已提交
4173

4174
	function buildProgram( shaderID, fragmentShader, vertexShader, uniforms, attributes, parameters ) {
4175

4176
		var p, pl, program, code;
4177
		var chunks = [];
4178 4179 4180

		// Generate code

4181 4182 4183 4184 4185 4186 4187 4188 4189 4190
		if ( shaderID ) {

			chunks.push( shaderID );

		} else {

			chunks.push( fragmentShader );
			chunks.push( vertexShader );

		}
4191 4192 4193

		for ( p in parameters ) {

4194 4195
			chunks.push( p );
			chunks.push( parameters[ p ] );
4196 4197 4198

		}

4199 4200
		code = chunks.join();

4201 4202 4203 4204 4205 4206 4207
		// 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*/ );
4208

4209 4210 4211 4212 4213
				return _programs[ p ].program;

			}

		}
4214 4215
		
		//console.log( "building new program " );
4216 4217 4218 4219

		//

		program = _gl.createProgram(),
M
Mr.doob 已提交
4220

M
Mr.doob 已提交
4221 4222 4223 4224
		prefix_fragment = [
			"#ifdef GL_ES",
			"precision highp float;",
			"#endif",
M
Mr.doob 已提交
4225

4226 4227
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
A
alteredq 已提交
4228

4229 4230
			parameters.fog ? "#define USE_FOG" : "",
			parameters.fog instanceof THREE.FogExp2 ? "#define FOG_EXP2" : "",
4231

4232
			parameters.map ? "#define USE_MAP" : "",
4233 4234 4235
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
4236

4237
			"uniform mat4 viewMatrix;",
4238
			"uniform vec3 cameraPosition;",
M
Mr.doob 已提交
4239 4240
			""
		].join("\n"),
4241

M
Mr.doob 已提交
4242
		prefix_vertex = [
4243
			maxVertexTextures() > 0 ? "#define VERTEX_TEXTURES" : "",
4244

4245 4246 4247
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

4248 4249
			"#define MAX_BONES " + parameters.maxBones,

4250
			parameters.map ? "#define USE_MAP" : "",
4251 4252 4253
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
4254
			parameters.skinning ? "#define USE_SKINNING" : "",
4255
			parameters.morphTargets ? "#define USE_MORPHTARGETS" : "",
4256

4257

4258 4259
			parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",

M
Mr.doob 已提交
4260 4261 4262
			"uniform mat4 objectMatrix;",
			"uniform mat4 modelViewMatrix;",
			"uniform mat4 projectionMatrix;",
4263 4264
			"uniform mat4 viewMatrix;",
			"uniform mat3 normalMatrix;",
M
Mr.doob 已提交
4265
			"uniform vec3 cameraPosition;",
A
alteredq 已提交
4266 4267 4268

			"uniform mat4 cameraInverseMatrix;",

M
Mr.doob 已提交
4269 4270 4271
			"attribute vec3 position;",
			"attribute vec3 normal;",
			"attribute vec2 uv;",
4272
			"attribute vec2 uv2;",
4273

4274
			"#ifdef USE_COLOR",
4275

4276
				"attribute vec3 color;",
4277

4278 4279
			"#endif",

4280
			"#ifdef USE_MORPHTARGETS",
4281

4282 4283 4284 4285 4286 4287 4288 4289
				"attribute vec3 morphTarget0;",
				"attribute vec3 morphTarget1;",
				"attribute vec3 morphTarget2;",
				"attribute vec3 morphTarget3;",
				"attribute vec3 morphTarget4;",
				"attribute vec3 morphTarget5;",
				"attribute vec3 morphTarget6;",
				"attribute vec3 morphTarget7;",
4290

4291 4292 4293
			"#endif",

			"#ifdef USE_SKINNING",
4294

4295 4296 4297 4298
				"attribute vec4 skinVertexA;",
				"attribute vec4 skinVertexB;",
				"attribute vec4 skinIndex;",
				"attribute vec4 skinWeight;",
4299

4300
			"#endif",
4301

M
Mr.doob 已提交
4302 4303
			""
		].join("\n");
4304

4305 4306
		_gl.attachShader( program, getShader( "fragment", prefix_fragment + fragmentShader ) );
		_gl.attachShader( program, getShader( "vertex", prefix_vertex + vertexShader ) );
M
Mr.doob 已提交
4307

M
Mr.doob 已提交
4308
		_gl.linkProgram( program );
N
Nicolas Garcia Belmonte 已提交
4309

M
Mr.doob 已提交
4310
		if ( !_gl.getProgramParameter( program, _gl.LINK_STATUS ) ) {
N
Nicolas Garcia Belmonte 已提交
4311

4312
			console.error( "Could not initialise shader\n" + "VALIDATE_STATUS: " + _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) + ", gl error [" + _gl.getError() + "]" );
M
Mr.doob 已提交
4313

N
Nicolas Garcia Belmonte 已提交
4314
		}
4315

4316 4317
		//console.log( prefix_fragment + fragmentShader );
		//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
4318

M
Mr.doob 已提交
4319
		program.uniforms = {};
4320
		program.attributes = {};
M
Mr.doob 已提交
4321

4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339
		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 );
4340

4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363
		// 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 );

4364 4365
		_programs.push( { program: program, code: code } );

M
Mr.doob 已提交
4366
		return program;
M
Mr.doob 已提交
4367

M
Mr.doob 已提交
4368
	};
M
Mr.doob 已提交
4369

4370
	function loadUniformsSkinning( uniforms, object ) {
4371

M
Mr.doob 已提交
4372
		_gl.uniformMatrix4fv( uniforms.cameraInverseMatrix, false, _viewMatrixArray );
A
alteredq 已提交
4373
		_gl.uniformMatrix4fv( uniforms.boneGlobalMatrices, false, object.boneMatrices );
4374

4375
	};
4376

4377

4378
	function loadUniformsMatrices( uniforms, object ) {
4379

A
alteredq 已提交
4380 4381 4382 4383
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray );
		_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrixArray );

	};
4384

4385
	function loadUniformsGeneric( program, uniforms ) {
M
Mr.doob 已提交
4386

4387
		var u, uniform, value, type, location, texture;
M
Mr.doob 已提交
4388

M
Mr.doob 已提交
4389
		for( u in uniforms ) {
M
Mr.doob 已提交
4390

4391 4392
			location = program.uniforms[u];
			if ( !location ) continue;
M
Mr.doob 已提交
4393

4394
			uniform = uniforms[u];
M
Mr.doob 已提交
4395

4396 4397
			type = uniform.type;
			value = uniform.value;
M
Mr.doob 已提交
4398

M
Mr.doob 已提交
4399
			if( type == "i" ) {
M
Mr.doob 已提交
4400

M
Mr.doob 已提交
4401
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
4402

M
Mr.doob 已提交
4403
			} else if( type == "f" ) {
M
Mr.doob 已提交
4404

M
Mr.doob 已提交
4405
				_gl.uniform1f( location, value );
4406

A
alteredq 已提交
4407 4408 4409
			} else if( type == "fv1" ) {

				_gl.uniform1fv( location, value );
M
Mr.doob 已提交
4410

4411 4412 4413 4414
			} else if( type == "fv" ) {

				_gl.uniform3fv( location, value );

4415 4416 4417 4418
			} else if( type == "v2" ) {

				_gl.uniform2f( location, value.x, value.y );

4419 4420 4421
			} else if( type == "v3" ) {

				_gl.uniform3f( location, value.x, value.y, value.z );
4422

4423 4424 4425 4426
			} else if( type == "v4" ) {

				_gl.uniform4f( location, value.x, value.y, value.z, value.w );

4427 4428 4429
			} else if( type == "c" ) {

				_gl.uniform3f( location, value.r, value.g, value.b );
M
Mr.doob 已提交
4430

M
Mr.doob 已提交
4431
			} else if( type == "t" ) {
M
Mr.doob 已提交
4432

M
Mr.doob 已提交
4433
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
4434

4435
				texture = uniform.texture;
M
Mr.doob 已提交
4436

4437
				if ( !texture ) continue;
M
Mr.doob 已提交
4438

4439
				if ( texture.image instanceof Array && texture.image.length == 6 ) {
M
Mr.doob 已提交
4440

4441
					setCubeTexture( texture, value );
M
Mr.doob 已提交
4442

4443
				} else {
M
Mr.doob 已提交
4444

4445
					setTexture( texture, value );
M
Mr.doob 已提交
4446

4447
				}
M
Mr.doob 已提交
4448

4449
			}
M
Mr.doob 已提交
4450

4451
		}
M
Mr.doob 已提交
4452

4453
	};
M
Mr.doob 已提交
4454

4455
	function setBlending( blending ) {
A
alteredq 已提交
4456 4457

		if ( blending != _oldBlending ) {
4458

A
alteredq 已提交
4459 4460 4461 4462 4463
			switch ( blending ) {

				case THREE.AdditiveBlending:

					_gl.blendEquation( _gl.FUNC_ADD );
4464
					_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE );
A
alteredq 已提交
4465 4466 4467 4468 4469

					break;

				case THREE.SubtractiveBlending:

4470 4471 4472 4473
					// TODO: Find blendFuncSeparate() combination

					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.ZERO, _gl.ONE_MINUS_SRC_COLOR );
A
alteredq 已提交
4474 4475 4476

					break;

4477 4478 4479
				case THREE.MultiplyBlending:

					// TODO: Find blendFuncSeparate() combination
A
alteredq 已提交
4480 4481

					_gl.blendEquation( _gl.FUNC_ADD );
4482
					_gl.blendFunc( _gl.ZERO, _gl.SRC_COLOR );
A
alteredq 已提交
4483 4484 4485 4486 4487

					break;

				default:

4488 4489
					_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 已提交
4490 4491

					break;
4492

A
alteredq 已提交
4493
			}
4494

A
alteredq 已提交
4495
			_oldBlending = blending;
4496

A
alteredq 已提交
4497 4498 4499
		}

	};
4500

4501
	function setTextureParameters( textureType, texture, image ) {
4502

4503
		if ( isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ) ) {
M
Mr.doob 已提交
4504

4505 4506
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
M
Mr.doob 已提交
4507

4508 4509
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
M
Mr.doob 已提交
4510

4511
			_gl.generateMipmap( textureType );
M
Mr.doob 已提交
4512

4513
		} else {
M
Mr.doob 已提交
4514

4515 4516
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
4517

4518 4519
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
M
Mr.doob 已提交
4520

4521
		}
M
Mr.doob 已提交
4522

4523
	};
4524

4525
	function setTexture( texture, slot ) {
4526

4527
		if ( texture.needsUpdate ) {
A
alteredq 已提交
4528

4529
			if ( !texture.__webglInit ) {
M
Mr.doob 已提交
4530

4531
				texture.__webglTexture = _gl.createTexture();
A
alteredq 已提交
4532

4533
				_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
4534
				_gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image );
M
Mr.doob 已提交
4535

4536
				texture.__webglInit = true;
M
Mr.doob 已提交
4537

A
alteredq 已提交
4538
			} else {
M
Mr.doob 已提交
4539

4540
				_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
A
alteredq 已提交
4541
				_gl.texSubImage2D( _gl.TEXTURE_2D, 0, 0, 0, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image );
M
Mr.doob 已提交
4542 4543 4544

			}

4545 4546
			setTextureParameters( _gl.TEXTURE_2D, texture, texture.image );
			_gl.bindTexture( _gl.TEXTURE_2D, null );
4547

A
alteredq 已提交
4548
			texture.needsUpdate = false;
4549 4550 4551 4552

		}

		_gl.activeTexture( _gl.TEXTURE0 + slot );
4553
		_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
M
Mr.doob 已提交
4554

4555
	};
M
Mr.doob 已提交
4556

4557
	function setCubeTexture( texture, slot ) {
4558 4559 4560 4561 4562

		if ( texture.image.length == 6 ) {

			if ( texture.needsUpdate ) {

4563 4564 4565
				if ( !texture.__webglInit ) {

					texture.image.__webglTextureCube = _gl.createTexture();
4566

4567
					_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
4568

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

4571
						_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image[ i ] );
4572

4573
					}
4574 4575

					texture.__webglInit = true;
4576 4577 4578

				} else {

4579
					_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
4580

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

4583
						_gl.texSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image[ i ] );
4584

4585
					}
4586 4587 4588

				}

4589
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, texture.image[0] );
4590 4591 4592
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );

				texture.needsUpdate = false;
4593

4594 4595 4596
			}

			_gl.activeTexture( _gl.TEXTURE0 + slot );
4597
			_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
4598 4599 4600 4601 4602

		}

	};

4603
	function setRenderTarget( renderTexture ) {
4604

4605
		if ( renderTexture && !renderTexture.__webglFramebuffer ) {
M
Mr.doob 已提交
4606

M
Mikael Emtinger 已提交
4607 4608 4609
			if( renderTexture.depthBuffer === undefined ) renderTexture.depthBuffer = true;
			if( renderTexture.stencilBuffer === undefined ) renderTexture.stencilBuffer = true;

4610 4611 4612
			renderTexture.__webglFramebuffer = _gl.createFramebuffer();
			renderTexture.__webglRenderbuffer = _gl.createRenderbuffer();
			renderTexture.__webglTexture = _gl.createTexture();
4613 4614 4615


			// Setup texture
M
Mr.doob 已提交
4616

4617
			_gl.bindTexture( _gl.TEXTURE_2D, renderTexture.__webglTexture );
4618 4619 4620 4621
			_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 ) );
4622
			_gl.texImage2D( _gl.TEXTURE_2D, 0, paramThreeToGL( renderTexture.format ), renderTexture.width, renderTexture.height, 0, paramThreeToGL( renderTexture.format ), paramThreeToGL( renderTexture.type ), null );
4623

M
Mikael Emtinger 已提交
4624
			// Setup render and frame buffer
M
Mr.doob 已提交
4625

M
Mikael Emtinger 已提交
4626
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderTexture.__webglRenderbuffer );
4627
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTexture.__webglFramebuffer );
M
Mikael Emtinger 已提交
4628

4629
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, renderTexture.__webglTexture, 0 );
M
Mikael Emtinger 已提交
4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652
			
			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 );
				
			}
			
4653 4654

			// Release everything
M
Mr.doob 已提交
4655

4656 4657 4658
			_gl.bindTexture( _gl.TEXTURE_2D, null );
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
M
Mr.doob 已提交
4659

4660 4661
		}

4662
		var framebuffer, width, height;
M
Mr.doob 已提交
4663

4664
		if ( renderTexture ) {
M
Mr.doob 已提交
4665

4666
			framebuffer = renderTexture.__webglFramebuffer;
4667 4668
			width = renderTexture.width;
			height = renderTexture.height;
M
Mr.doob 已提交
4669

4670
		} else {
M
Mr.doob 已提交
4671

4672
			framebuffer = null;
4673 4674
			width = _viewportWidth;
			height = _viewportHeight;
M
Mr.doob 已提交
4675

4676
		}
M
Mr.doob 已提交
4677

4678
		if ( framebuffer != _currentFramebuffer ) {
M
Mr.doob 已提交
4679

4680
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
4681
			_gl.viewport( _viewportX, _viewportY, width, height );
M
Mr.doob 已提交
4682

4683
			_currentFramebuffer = framebuffer;
M
Mr.doob 已提交
4684

4685
		}
4686

4687
	};
M
Mr.doob 已提交
4688

4689
	function updateRenderTargetMipmap( renderTarget ) {
M
Mr.doob 已提交
4690

4691
		_gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
4692 4693
		_gl.generateMipmap( _gl.TEXTURE_2D );
		_gl.bindTexture( _gl.TEXTURE_2D, null );
M
Mr.doob 已提交
4694 4695

	};
4696

4697
	function cacheUniformLocations( program, identifiers ) {
M
Mr.doob 已提交
4698

M
Mr.doob 已提交
4699
		var i, l, id;
M
Mr.doob 已提交
4700

M
Mr.doob 已提交
4701
		for( i = 0, l = identifiers.length; i < l; i++ ) {
M
Mr.doob 已提交
4702

4703 4704
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
4705

M
Mr.doob 已提交
4706
		}
M
Mr.doob 已提交
4707

M
Mr.doob 已提交
4708
	};
M
Mr.doob 已提交
4709

4710
	function cacheAttributeLocations( program, identifiers ) {
4711

4712
		var i, l, id;
M
Mr.doob 已提交
4713

4714
		for( i = 0, l = identifiers.length; i < l; i++ ) {
M
Mr.doob 已提交
4715

4716 4717
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
M
Mr.doob 已提交
4718

4719
		}
M
Mr.doob 已提交
4720

M
Mr.doob 已提交
4721
	};
M
Mr.doob 已提交
4722

4723
	function getShader( type, string ) {
N
Nicolas Garcia Belmonte 已提交
4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741

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

4742
			console.error( _gl.getShaderInfoLog( shader ) );
4743
			console.error( string );
N
Nicolas Garcia Belmonte 已提交
4744 4745 4746 4747 4748
			return null;

		}

		return shader;
M
Mr.doob 已提交
4749

4750
	};
N
Nicolas Garcia Belmonte 已提交
4751

4752
	// fallback filters for non-power-of-2 textures
4753

4754
	function filterFallback( f ) {
4755

4756 4757 4758 4759 4760 4761 4762 4763
		switch ( f ) {

			case THREE.NearestFilter:
			case THREE.NearestMipMapNearestFilter:
			case THREE.NearestMipMapLinearFilter: return _gl.NEAREST; break;

			case THREE.LinearFilter:
			case THREE.LinearMipMapNearestFilter:
M
Mikael Emtinger 已提交
4764 4765
			case THREE.LinearMipMapLinearFilter: 
			default:
4766

M
Mikael Emtinger 已提交
4767
				return _gl.LINEAR; break;
4768 4769

		}
4770

4771
	};
4772 4773

	function paramThreeToGL( p ) {
M
Mr.doob 已提交
4774

4775
		switch ( p ) {
M
Mr.doob 已提交
4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788

			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;

4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802
			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;

4803
		}
M
Mr.doob 已提交
4804

4805
		return 0;
M
Mr.doob 已提交
4806

4807 4808
	};

4809
	function isPowerOfTwo( value ) {
4810 4811 4812 4813 4814

		return ( value & ( value - 1 ) ) == 0;

	};

4815
	function materialNeedsSmoothNormals( material ) {
4816 4817 4818

		return material && material.shading != undefined && material.shading == THREE.SmoothShading;

4819
	};
M
Mr.doob 已提交
4820

4821
	function bufferNeedsSmoothNormals( geometryGroup, object ) {
M
Mr.doob 已提交
4822

4823
		var m, ml, i, l, meshMaterial, needsSmoothNormals = false;
M
Mr.doob 已提交
4824

M
Mr.doob 已提交
4825
		for ( m = 0, ml = object.materials.length; m < ml; m++ ) {
4826

M
Mr.doob 已提交
4827
			meshMaterial = object.materials[ m ];
4828 4829 4830

			if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {

4831
				for ( i = 0, l = geometryGroup.materials.length; i < l; i++ ) {
4832

4833
					if ( materialNeedsSmoothNormals( geometryGroup.materials[ i ] ) ) {
4834

4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855
						needsSmoothNormals = true;
						break;

					}

				}

			} else {

				if ( materialNeedsSmoothNormals( meshMaterial ) ) {

					needsSmoothNormals = true;
					break;

				}

			}

			if ( needsSmoothNormals ) break;

		}
M
Mr.doob 已提交
4856

4857
		return needsSmoothNormals;
M
Mr.doob 已提交
4858

4859
	};
M
Mr.doob 已提交
4860

4861
	function unrollGroupMaterials( geometryGroup, object ) {
4862

4863 4864 4865
		var m, ml, i, il,
			material, meshMaterial,
			materials = [];
4866

4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877
		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 ) {
4878

4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897
						materials.push( material );

					}

				}

			} else {

				material = meshMaterial;

				if ( material ) {

					materials.push( material );

				}

			}

		}
4898

4899 4900 4901
		return materials;

	};
4902

4903
	function bufferGuessVertexColorType( materials, geometryGroup, object ) {
4904

4905
		var i, m, ml = materials.length;
4906

4907
		// use vertexColor type from the first material in unrolled materials
4908

4909
		for ( i = 0; i < ml; i++ ) {
4910

4911
			m = materials[ i ];
4912

4913
			if ( m.vertexColors ) {
4914

4915 4916 4917
				return m.vertexColors;

			}
4918

4919
		}
4920

4921
		return false;
4922

4923 4924
	};

4925
	function bufferGuessNormalType( materials, geometryGroup, object ) {
4926

4927
		var i, m, ml = materials.length;
4928

4929
		// only MeshBasicMaterial and MeshDepthMaterial don't need normals
4930

4931
		for ( i = 0; i < ml; i++ ) {
4932

4933
			m = materials[ i ];
4934

A
alteredq 已提交
4935
			if ( ( m instanceof THREE.MeshBasicMaterial && !m.envMap ) || m instanceof THREE.MeshDepthMaterial ) continue;
4936

4937
			if ( materialNeedsSmoothNormals( m ) ) {
4938

4939 4940 4941 4942 4943 4944 4945 4946 4947
				return THREE.SmoothShading;

			} else {

				return THREE.FlatShading;

			}

		}
4948

4949
		return false;
4950

4951 4952
	};

4953
	function bufferGuessUVType( materials, geometryGroup, object ) {
4954

4955
		var i, m, ml = materials.length;
4956

4957
		// material must use some texture to require uvs
4958

4959
		for ( i = 0; i < ml; i++ ) {
4960

4961
			m = materials[ i ];
4962

A
alteredq 已提交
4963
			if ( m.map || m.lightMap || m instanceof THREE.MeshShaderMaterial ) {
4964

4965
				return true;
4966

4967
			}
4968

4969
		}
4970

4971
		return false;
4972

4973
	};
4974

4975
	function allocateBones( object ) {
4976

4977 4978 4979 4980 4981 4982 4983
		// 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)
4984

4985
		var maxBones = 50;
4986

4987
		if ( object !== undefined && object instanceof THREE.SkinnedMesh ) {
4988

4989 4990 4991 4992 4993
			maxBones = object.bones.length;

		}

		return maxBones;
4994

4995
	};
4996

4997
	function allocateLights( lights, maxLights ) {
4998

4999 5000
		var l, ll, light, dirLights, pointLights, maxDirLights, maxPointLights;
		dirLights = pointLights = maxDirLights = maxPointLights = 0;
5001

5002
		for ( l = 0, ll = lights.length; l < ll; l++ ) {
5003

5004
			light = lights[ l ];
5005

5006 5007
			if ( light instanceof THREE.DirectionalLight ) dirLights++;
			if ( light instanceof THREE.PointLight ) pointLights++;
5008

5009
		}
5010

5011
		if ( ( pointLights + dirLights ) <= maxLights ) {
5012

5013 5014
			maxDirLights = dirLights;
			maxPointLights = pointLights;
5015

5016
		} else {
5017

5018 5019
			maxDirLights = Math.ceil( maxLights * dirLights / ( pointLights + dirLights ) );
			maxPointLights = maxLights - maxDirLights;
5020 5021 5022

		}

5023
		return { 'directional' : maxDirLights, 'point' : maxPointLights };
5024 5025

	};
M
Mr.doob 已提交
5026

A
alteredq 已提交
5027
	/* DEBUG
5028
	function getGLParams() {
M
Mr.doob 已提交
5029

5030
		var params  = {
M
Mr.doob 已提交
5031

5032 5033
			'MAX_VARYING_VECTORS': _gl.getParameter( _gl.MAX_VARYING_VECTORS ),
			'MAX_VERTEX_ATTRIBS': _gl.getParameter( _gl.MAX_VERTEX_ATTRIBS ),
M
Mr.doob 已提交
5034

5035 5036 5037
			'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 已提交
5038

5039 5040 5041
			'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 已提交
5042

5043 5044
		return params;
	};
M
Mr.doob 已提交
5045

5046
	function dumpObject( obj ) {
M
Mr.doob 已提交
5047

5048 5049
		var p, str = "";
		for ( p in obj ) {
M
Mr.doob 已提交
5050

5051
			str += p + ": " + obj[p] + "\n";
M
Mr.doob 已提交
5052

5053
		}
M
Mr.doob 已提交
5054

5055 5056
		return str;
	}
A
alteredq 已提交
5057
	*/
5058
};
5059