WebGLRenderer.js 128.7 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 _this = this,
	_gl, _canvas = document.createElement( 'canvas' ),
25
	_programs = [],
26 27
	_currentProgram = null,
	_currentFramebuffer = null,
28
	_currentDepthMask = true,
M
Mr.doob 已提交
29

A
alteredq 已提交
30
	// gl state cache
31

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

38 39 40 41 42
	_viewportX = 0,
	_viewportY = 0,
	_viewportWidth = 0,
	_viewportHeight = 0,

43
	// camera matrices caches
44 45

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

54
	_projScreenMatrix = new THREE.Matrix4(),
55
	_projectionMatrixArray = new Float32Array( 16 ),
56
	_viewMatrixArray = new Float32Array( 16 ),
57

58
	_vector3 = new THREE.Vector4(),
59

A
alteredq 已提交
60
	// light arrays cache
61

A
alteredq 已提交
62 63
	_lights = {

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

	},

M
Mr.doob 已提交
70

71
	// parameters
72

73
	parameters = parameters || {};
M
Mr.doob 已提交
74

75 76 77
	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 ),
78
	clearAlpha = parameters.clearAlpha !== undefined ? parameters.clearAlpha : 0;
M
Mr.doob 已提交
79

80 81 82 83 84
	this.data = {

		vertices: 0,
		faces: 0

85
	};
M
Mr.doob 已提交
86

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

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

94 95
	this.context = _gl;

M
Mikael Emtinger 已提交
96

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

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

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

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

107 108 109 110
		_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 已提交
111

M
Mikael Emtinger 已提交
112 113
		_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 已提交
114

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

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

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

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

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

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

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


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

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

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

M
Mikael Emtinger 已提交
145 146 147 148 149 150 151 152 153 154 155 156 157 158
	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;

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

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

M
Mikael Emtinger 已提交
167 168 169 170 171 172 173 174 175 176
	_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 );

177 178 179 180 181 182 183 184
	_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 ) {
185

186 187 188 189 190 191 192
		_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 );

193

194 195 196
	} else {

		_lensFlare.hasVertexTexture = true;
197

198 199 200 201
		_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 );
202

203
	}
M
Mikael Emtinger 已提交
204 205 206 207 208

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

M
Mr.doob 已提交
220
	var _lensFlareAttributesEnabled = false;
M
Mikael Emtinger 已提交
221

M
Mikael Emtinger 已提交
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259
	// 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 = {};
260 261 262 263 264 265 266 267 268 269 270 271 272 273
	_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 已提交
274

M
Mr.doob 已提交
275 276
	//_gl.enableVertexAttribArray( _sprite.attributes.position );
	//_gl.enableVertexAttribArray( _sprite.attributes.uv );
M
Mikael Emtinger 已提交
277

M
Mr.doob 已提交
278
	var _spriteAttributesEnabled = false;
M
Mikael Emtinger 已提交
279

N
Nicolas Garcia Belmonte 已提交
280 281 282 283
	this.setSize = function ( width, height ) {

		_canvas.width = width;
		_canvas.height = height;
284

285 286 287
		this.setViewport( 0, 0, _canvas.width, _canvas.height );

	};
N
Nicolas Garcia Belmonte 已提交
288

289
	this.setViewport = function ( x, y, width, height ) {
290

291 292
		_viewportX = x;
		_viewportY = y;
293

294 295
		_viewportWidth = width;
		_viewportHeight = height;
296

297
		_gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight );
298

N
Nicolas Garcia Belmonte 已提交
299
	};
300

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

303
		_gl.scissor( x, y, width, height );
304

305
	};
306

307
	this.enableScissorTest = function ( enable ) {
308

309 310 311 312
		if ( enable )
			_gl.enable( _gl.SCISSOR_TEST );
		else
			_gl.disable( _gl.SCISSOR_TEST );
313

314
	};
315

316
	this.enableDepthBufferWrite = function ( enable ) {
317

318
		_currentDepthMask = enable;
319 320 321
		_gl.depthMask( enable );

	};
322

323
	this.setClearColorHex = function ( hex, alpha ) {
324

325 326
		var color = new THREE.Color( hex );
		_gl.clearColor( color.r, color.g, color.b, alpha );
327

328
	};
A
alteredq 已提交
329

330
	this.setClearColor = function ( color, alpha ) {
A
alteredq 已提交
331 332 333 334

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

	};
335

N
Nicolas Garcia Belmonte 已提交
336 337
	this.clear = function () {

M
Mikael Emtinger 已提交
338
		_gl.clear( _gl.COLOR_BUFFER_BIT | _gl.DEPTH_BUFFER_BIT | _gl.STENCIL_BUFFER_BIT );
N
Nicolas Garcia Belmonte 已提交
339 340 341

	};

M
Mikael Emtinger 已提交
342 343 344 345 346
	this.setStencilShadowDarkness = function( value ) {
		
		_stencilShadow.darkness = value;
	};

347 348 349 350 351 352
	this.getContext = function() {
		
		return _gl;
		
	}

M
Mr.doob 已提交
353

A
alteredq 已提交
354
	function setupLights ( program, lights ) {
355

356
		var l, ll, light, r = 0, g = 0, b = 0,
357
		color, position, intensity, distance,
M
Mr.doob 已提交
358

359
		zlights = _lights,
M
Mr.doob 已提交
360

361
		dcolors = zlights.directional.colors,
362
		dpositions = zlights.directional.positions,
363

364
		pcolors = zlights.point.colors,
365
		ppositions = zlights.point.positions,
366
		pdistances = zlights.point.distances,
367

368 369
		dlength = 0,
		plength = 0,
370

371 372
		doffset = 0,
		poffset = 0;
M
Mr.doob 已提交
373

374
		for ( l = 0, ll = lights.length; l < ll; l++ ) {
375

376
			light = lights[ l ];
377
			color = light.color;
378

379 380
			position = light.position;
			intensity = light.intensity;
381
			distance = light.distance;
382 383 384

			if ( light instanceof THREE.AmbientLight ) {

385 386 387
				r += color.r;
				g += color.g;
				b += color.b;
M
Mr.doob 已提交
388

389
			} else if ( light instanceof THREE.DirectionalLight ) {
390

391
				doffset = dlength * 3;
392

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

397
				dpositions[ doffset ] = position.x;
398 399
				dpositions[ doffset + 1 ] = position.y;
				dpositions[ doffset + 2 ] = position.z;
400

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

403 404
			} else if( light instanceof THREE.PointLight ) {

405
				poffset = plength * 3;
406

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

411
				ppositions[ poffset ] = position.x;
412 413
				ppositions[ poffset + 1 ] = position.y;
				ppositions[ poffset + 2 ] = position.z;
M
Mr.doob 已提交
414

415 416
				pdistances[ plength ] = distance;

417
				plength += 1;
M
Mr.doob 已提交
418

419 420 421
			}

		}
422

423 424
		// null eventual remains from removed lights
		// (this is to avoid if in shader)
425

426 427
		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 已提交
428

429 430
		zlights.point.length = plength;
		zlights.directional.length = dlength;
M
Mr.doob 已提交
431

432 433 434
		zlights.ambient[ 0 ] = r;
		zlights.ambient[ 1 ] = g;
		zlights.ambient[ 2 ] = b;
M
Mr.doob 已提交
435

436
	};
M
Mr.doob 已提交
437

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

440 441
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
M
Mr.doob 已提交
442

443
	};
M
Mr.doob 已提交
444

445
	function createLineBuffers( geometry ) {
M
Mr.doob 已提交
446

447 448
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
M
Mr.doob 已提交
449

450
	};
451

452
	function createRibbonBuffers( geometry ) {
A
alteredq 已提交
453

454 455
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
A
alteredq 已提交
456 457 458

	};

459
	function createMeshBuffers( geometryGroup ) {
M
Mr.doob 已提交
460

461 462 463 464 465 466
		geometryGroup.__webglVertexBuffer = _gl.createBuffer();
		geometryGroup.__webglNormalBuffer = _gl.createBuffer();
		geometryGroup.__webglTangentBuffer = _gl.createBuffer();
		geometryGroup.__webglColorBuffer = _gl.createBuffer();
		geometryGroup.__webglUVBuffer = _gl.createBuffer();
		geometryGroup.__webglUV2Buffer = _gl.createBuffer();
467

468 469 470 471 472 473 474 475 476
		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 ) {
477

478
			var m, ml;
479 480 481 482 483 484
			geometryGroup.__webglMorphTargetsBuffers = []; 

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

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

485 486 487
			}

		}
M
Mr.doob 已提交
488

489
	};
490

491
	function initLineBuffers ( geometry ) {
M
Mr.doob 已提交
492

493 494 495
		var nvertices = geometry.vertices.length;

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

498
		geometry.__webglLineCount = nvertices;
M
Mr.doob 已提交
499

500
	};
M
Mr.doob 已提交
501

502
	function initRibbonBuffers ( geometry ) {
A
alteredq 已提交
503 504 505 506 507 508

		var nvertices = geometry.vertices.length;

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

509
		geometry.__webglVertexCount = nvertices;
A
alteredq 已提交
510 511

	};
512

513
	function initParticleBuffers ( geometry ) {
514 515 516 517

		var nvertices = geometry.vertices.length;

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

520
		geometry.__sortArray = [];
521

522
		geometry.__webglParticleCount = nvertices;
523 524 525

	};

526
	function initMeshBuffers ( geometryGroup, object ) {
M
Mr.doob 已提交
527

M
Mikael Emtinger 已提交
528
		var f, fl, fi, face,
529
		m, ml, size,
530 531 532 533 534 535
		nvertices = 0, ntris = 0, nlines = 0,

		uvType,
		vertexColorType,
		normalType,
		materials,
536
		attribute,
537 538 539 540

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

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

544 545
			fi = chunk_faces[ f ];
			face = obj_faces[ fi ];
M
Mr.doob 已提交
546

547
			if ( face instanceof THREE.Face3 ) {
M
Mr.doob 已提交
548

549 550 551
				nvertices += 3;
				ntris += 1;
				nlines += 3;
M
Mr.doob 已提交
552

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

555 556
				nvertices += 4;
				ntris += 2;
557
				nlines += 4;
M
Mr.doob 已提交
558

559
			}
M
Mr.doob 已提交
560

561
		}
562 563 564

		materials = unrollGroupMaterials( geometryGroup, object );

565 566
		uvType = bufferGuessUVType( materials, geometryGroup, object );
		normalType = bufferGuessNormalType( materials, geometryGroup, object );
A
alteredq 已提交
567 568
		vertexColorType = bufferGuessVertexColorType( materials, geometryGroup, object );

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

571
		geometryGroup.__vertexArray = new Float32Array( nvertices * 3 );
572

573
		if ( normalType ) {
M
Mr.doob 已提交
574

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

577
		}
578

579
		if ( geometry.hasTangents ) {
580

581
			geometryGroup.__tangentArray = new Float32Array( nvertices * 4 );
582

583
		}
584

585
		if ( vertexColorType ) {
586

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

589
		}
M
Mr.doob 已提交
590

591
		if ( uvType ) {
592

593
			if ( geometry.faceUvs.length > 0 || geometry.faceVertexUvs.length > 0 ) {
594

595 596 597 598 599
				geometryGroup.__uvArray = new Float32Array( nvertices * 2 );

			}

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

601 602 603 604 605 606 607 608 609 610 611 612 613 614 615
				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 已提交
616
		geometryGroup.__faceArray = new Uint16Array( ntris * 3 + ( object.geometry.edgeFaces ? object.geometry.edgeFaces.length * 2 * 3 : 0 ));
617
		geometryGroup.__lineArray = new Uint16Array( nlines * 2 );
M
Mr.doob 已提交
618

619 620
		if ( geometryGroup.numMorphTargets ) {

621
			geometryGroup.__morphTargetsArrays = []; 
622 623 624

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

625 626
				geometryGroup.__morphTargetsArrays.push( new Float32Array( nvertices * 3 ) );

627 628 629
			}

		}
630

631
		geometryGroup.__needsSmoothNormals = ( normalType == THREE.SmoothShading );
632

633 634 635 636
		geometryGroup.__uvType = uvType;
		geometryGroup.__vertexColorType = vertexColorType;
		geometryGroup.__normalType = normalType;

637 638
		geometryGroup.__webglFaceCount = ntris * 3 + ( object.geometry.edgeFaces ? object.geometry.edgeFaces.length * 2 * 3 : 0 );
		geometryGroup.__webglLineCount = nlines * 2;
639

M
Mr.doob 已提交
640

641
		// custom attributes
M
Mr.doob 已提交
642 643 644 645 646

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

			if ( materials[ m ].attributes ) {

647 648
				geometryGroup.__webglCustomAttributes = {};

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

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

653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669
					if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
						
						attribute.__webglInitialized = true;
						
						size = 1;		// "f" and "i"
	
						if( attribute.type === "v2" ) size = 2;
						else if( attribute.type === "v3" ) size = 3;
						else if( attribute.type === "v4" ) size = 4;
						else if( attribute.type === "c"  ) size = 3;
	
						attribute.size = size;
						attribute.needsUpdate = true;
						attribute.array = new Float32Array( nvertices * size );
						attribute.buffer = _gl.createBuffer();
						
					}
670 671 672 673 674 675

					geometryGroup.__webglCustomAttributes[ a ] = attribute;

				}

			}
M
Mr.doob 已提交
676

677
		}
678

679
	};
M
Mr.doob 已提交
680

681

682
	function setMeshBuffers ( geometryGroup, object, hint ) {
683

M
Mr.doob 已提交
684
		var f, fl, fi, face,
685 686 687 688 689 690 691 692 693 694 695 696 697
		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,
698
		a,
M
Mr.doob 已提交
699

700
		vertexIndex = 0,
701

702 703
		offset = 0,
		offset_uv = 0,
704
		offset_uv2 = 0,
705 706 707 708
		offset_face = 0,
		offset_normal = 0,
		offset_tangent = 0,
		offset_line = 0,
709
		offset_color = 0,
A
alteredq 已提交
710
		offset_skin = 0,
711
		offset_morphTarget = 0,
712
		offset_custom = 0,
713
		offset_customSrc = 0,
M
Mr.doob 已提交
714

715 716 717 718 719 720
		vertexArray = geometryGroup.__vertexArray,
		uvArray = geometryGroup.__uvArray,
		uv2Array = geometryGroup.__uv2Array,
		normalArray = geometryGroup.__normalArray,
		tangentArray = geometryGroup.__tangentArray,
		colorArray = geometryGroup.__colorArray,
721

722 723 724 725
		skinVertexAArray = geometryGroup.__skinVertexAArray,
		skinVertexBArray = geometryGroup.__skinVertexBArray,
		skinIndexArray = geometryGroup.__skinIndexArray,
		skinWeightArray = geometryGroup.__skinWeightArray,
M
Mr.doob 已提交
726

727 728
		morphTargetsArrays = geometryGroup.__morphTargetsArrays,

729 730
		customAttributes = geometryGroup.__webglCustomAttributes,
		customAttribute,
731

732 733
		faceArray = geometryGroup.__faceArray,
		lineArray = geometryGroup.__lineArray,
M
Mr.doob 已提交
734

735
		needsSmoothNormals = geometryGroup.__needsSmoothNormals,
736

737
		vertexColorType = geometryGroup.__vertexColorType,
A
alteredq 已提交
738 739
		uvType = geometryGroup.__uvType,
		normalType = geometryGroup.__normalType,
740

741
		geometry = object.geometry, // this is shared for all chunks
742

743
		dirtyVertices = geometry.__dirtyVertices,
744 745 746
		dirtyElements = geometry.__dirtyElements,
		dirtyUvs = geometry.__dirtyUvs,
		dirtyNormals = geometry.__dirtyNormals,
747
		dirtyTangents = geometry.__dirtyTangents,
748
		dirtyColors = geometry.__dirtyColors,
749
		dirtyMorphTargets = geometry.__dirtyMorphTargets,
M
Mr.doob 已提交
750

751
		vertices = geometry.vertices,
752
		chunk_faces = geometryGroup.faces,
753
		obj_faces = geometry.faces,
754

755 756
		obj_uvs  = geometry.faceVertexUvs[ 0 ],
		obj_uvs2 = geometry.faceVertexUvs[ 1 ],
757

A
alteredq 已提交
758
		obj_colors = geometry.colors,
759

A
alteredq 已提交
760 761 762
		obj_skinVerticesA = geometry.skinVerticesA,
		obj_skinVerticesB = geometry.skinVerticesB,
		obj_skinIndices = geometry.skinIndices,
763
		obj_skinWeights = geometry.skinWeights,
764
		obj_edgeFaces = object instanceof THREE.ShadowVolume ? geometry.edgeFaces : undefined;
765 766

		morphTargets = geometry.morphTargets;
767

768
		if ( customAttributes ) {
M
Mr.doob 已提交
769

770
			for ( a in customAttributes ) {
M
Mr.doob 已提交
771

772
				customAttributes[ a ].offset = 0;
773
				customAttributes[ a ].offsetSrc = 0;
M
Mr.doob 已提交
774

775 776
			}

M
Mr.doob 已提交
777
		}
778 779


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

782 783
			fi = chunk_faces[ f ];
			face = obj_faces[ fi ];
784 785

			if ( obj_uvs ) {
A
alteredq 已提交
786 787 788 789

				uv = obj_uvs[ fi ];

			}
790 791 792

			if ( obj_uvs2 ) {

A
alteredq 已提交
793 794 795
				uv2 = obj_uvs2[ fi ];

			}
M
Mr.doob 已提交
796

797
			vertexNormals = face.vertexNormals;
798
			faceNormal = face.normal;
799

800 801
			vertexColors = face.vertexColors;
			faceColor = face.color;
802

803
			vertexTangents = face.vertexTangents;
804 805 806

			if ( face instanceof THREE.Face3 ) {

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

809 810 811
					v1 = vertices[ face.a ].position;
					v2 = vertices[ face.b ].position;
					v3 = vertices[ face.c ].position;
M
Mr.doob 已提交
812

813 814 815
					vertexArray[ offset ]     = v1.x;
					vertexArray[ offset + 1 ] = v1.y;
					vertexArray[ offset + 2 ] = v1.z;
M
Mr.doob 已提交
816

817 818 819
					vertexArray[ offset + 3 ] = v2.x;
					vertexArray[ offset + 4 ] = v2.y;
					vertexArray[ offset + 5 ] = v2.z;
820

821 822 823
					vertexArray[ offset + 6 ] = v3.x;
					vertexArray[ offset + 7 ] = v3.y;
					vertexArray[ offset + 8 ] = v3.z;
M
Mr.doob 已提交
824

825
					offset += 9;
M
Mr.doob 已提交
826

827
				}
828

829
				if ( customAttributes ) {
M
Mr.doob 已提交
830

831
					for ( a in customAttributes ) {
M
Mr.doob 已提交
832

833 834
						customAttribute = customAttributes[ a ];

M
Mr.doob 已提交
835 836
						if ( customAttribute.needsUpdate ) {

837
							offset_custom = customAttribute.offset;
838
							offset_customSrc = customAttribute.offsetSrc;
M
Mr.doob 已提交
839

840
							if( customAttribute.size === 1 ) {
M
Mr.doob 已提交
841

842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864
								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 已提交
865

866
								customAttribute.offset += 3;
M
Mr.doob 已提交
867

868
							} else {
M
Mr.doob 已提交
869

870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892
								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 已提交
893

894
								if( customAttribute.size === 2 ) {
M
Mr.doob 已提交
895 896 897

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

M
Mr.doob 已提交
899 900
									customAttribute.array[ offset_custom + 2 ] = v2.x;
									customAttribute.array[ offset_custom + 3 ] = v2.y;
901

M
Mr.doob 已提交
902
									customAttribute.array[ offset_custom + 4 ] = v3.x;
903
									customAttribute.array[ offset_custom + 5 ] = v3.y;
M
Mr.doob 已提交
904

905
									customAttribute.offset += 6;
M
Mr.doob 已提交
906

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

909 910 911 912 913
									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;
914

915 916 917
										customAttribute.array[ offset_custom + 3 ] = v2.r;
										customAttribute.array[ offset_custom + 4 ] = v2.g;
										customAttribute.array[ offset_custom + 5 ] = v2.b;
918

919 920 921 922 923 924 925 926 927
										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;
928

929 930 931
										customAttribute.array[ offset_custom + 3 ] = v2.x;
										customAttribute.array[ offset_custom + 4 ] = v2.y;
										customAttribute.array[ offset_custom + 5 ] = v2.z;
932

933 934 935 936 937
										customAttribute.array[ offset_custom + 6 ] = v3.x;
										customAttribute.array[ offset_custom + 7 ] = v3.y;
										customAttribute.array[ offset_custom + 8 ] = v3.z;
										
									}
M
Mr.doob 已提交
938

939
									customAttribute.offset += 9;
M
Mr.doob 已提交
940

941
								} else {
M
Mr.doob 已提交
942 943 944 945 946

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

M
Mr.doob 已提交
948 949 950 951
									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;
952

M
Mr.doob 已提交
953
									customAttribute.array[ offset_custom + 8  ] = v3.x;
954 955 956
									customAttribute.array[ offset_custom + 9  ] = v3.y;
									customAttribute.array[ offset_custom + 10 ] = v3.z;
									customAttribute.array[ offset_custom + 11 ] = v3.w;
M
Mr.doob 已提交
957

958
									customAttribute.offset += 12;
M
Mr.doob 已提交
959

960
								}
M
Mr.doob 已提交
961

962
							}
M
Mr.doob 已提交
963

964
						}
M
Mr.doob 已提交
965

966
					}
M
Mr.doob 已提交
967

968 969 970
				}


971
				if ( dirtyMorphTargets ) {
972 973 974

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

975 976 977
						v1 = morphTargets[ vk ].vertices[ face.a ].position;
						v2 = morphTargets[ vk ].vertices[ face.b ].position;
						v3 = morphTargets[ vk ].vertices[ face.c ].position;
978

979
						vka = morphTargetsArrays[ vk ];
980

981 982 983
						vka[ offset_morphTarget + 0 ] = v1.x;
						vka[ offset_morphTarget + 1 ] = v1.y;
						vka[ offset_morphTarget + 2 ] = v1.z;
984

985 986 987
						vka[ offset_morphTarget + 3 ] = v2.x;
						vka[ offset_morphTarget + 4 ] = v2.y;
						vka[ offset_morphTarget + 5 ] = v2.z;
988

989 990 991
						vka[ offset_morphTarget + 6 ] = v3.x;
						vka[ offset_morphTarget + 7 ] = v3.y;
						vka[ offset_morphTarget + 8 ] = v3.z;
992 993
					}

994
					offset_morphTarget += 9;
995

996 997
				}

A
alteredq 已提交
998 999 1000
				if ( obj_skinWeights.length ) {

					// weights
1001

A
alteredq 已提交
1002 1003 1004
					sw1 = obj_skinWeights[ face.a ];
					sw2 = obj_skinWeights[ face.b ];
					sw3 = obj_skinWeights[ face.c ];
1005

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

A
alteredq 已提交
1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042
					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
1043

A
alteredq 已提交
1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063
					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
1064

A
alteredq 已提交
1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084
					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;
1085

A
alteredq 已提交
1086
				}
1087

1088 1089 1090
				if ( dirtyColors && vertexColorType ) {

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

1092 1093 1094 1095 1096
						c1 = vertexColors[ 0 ];
						c2 = vertexColors[ 1 ];
						c3 = vertexColors[ 2 ];

					} else {
1097

1098 1099 1100 1101 1102
						c1 = faceColor;
						c2 = faceColor;
						c3 = faceColor;

					}
1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114

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

1116 1117 1118 1119
					offset_color += 9;

				}

1120
				if ( dirtyTangents && geometry.hasTangents ) {
1121

1122 1123 1124
					t1 = vertexTangents[ 0 ];
					t2 = vertexTangents[ 1 ];
					t3 = vertexTangents[ 2 ];
1125

1126 1127 1128 1129
					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 已提交
1130

1131 1132 1133 1134
					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 已提交
1135

1136 1137 1138 1139
					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 已提交
1140

1141
					offset_tangent += 12;
M
Mr.doob 已提交
1142

1143 1144
				}

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

1147 1148 1149
					if ( vertexNormals.length == 3 && needsSmoothNormals ) {

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

1151
							vn = vertexNormals[ i ];
M
Mr.doob 已提交
1152

1153 1154 1155
							normalArray[ offset_normal ]     = vn.x;
							normalArray[ offset_normal + 1 ] = vn.y;
							normalArray[ offset_normal + 2 ] = vn.z;
M
Mr.doob 已提交
1156

1157
							offset_normal += 3;
M
Mr.doob 已提交
1158

1159
						}
M
Mr.doob 已提交
1160

1161
					} else {
1162

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

1165 1166 1167
							normalArray[ offset_normal ]     = faceNormal.x;
							normalArray[ offset_normal + 1 ] = faceNormal.y;
							normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
1168

1169
							offset_normal += 3;
M
Mr.doob 已提交
1170

1171
						}
M
Mr.doob 已提交
1172 1173

					}
M
Mr.doob 已提交
1174

1175 1176
				}

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

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

1181
						uvi = uv[ i ];
M
Mr.doob 已提交
1182

1183 1184
						uvArray[ offset_uv ]     = uvi.u;
						uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
1185

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

M
Mr.doob 已提交
1188
					}
1189 1190 1191

				}

A
alteredq 已提交
1192
				if ( dirtyUvs && uv2 !== undefined && uvType ) {
1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206

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

						uv2i = uv2[ i ];

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

						offset_uv2 += 2;

					}

				}

1207
				if ( dirtyElements ) {
M
Mr.doob 已提交
1208

1209 1210 1211
					faceArray[ offset_face ] = vertexIndex;
					faceArray[ offset_face + 1 ] = vertexIndex + 1;
					faceArray[ offset_face + 2 ] = vertexIndex + 2;
M
Mr.doob 已提交
1212

1213
					offset_face += 3;
M
Mr.doob 已提交
1214

1215 1216
					lineArray[ offset_line ]     = vertexIndex;
					lineArray[ offset_line + 1 ] = vertexIndex + 1;
M
Mr.doob 已提交
1217

1218 1219
					lineArray[ offset_line + 2 ] = vertexIndex;
					lineArray[ offset_line + 3 ] = vertexIndex + 2;
M
Mr.doob 已提交
1220

1221 1222
					lineArray[ offset_line + 4 ] = vertexIndex + 1;
					lineArray[ offset_line + 5 ] = vertexIndex + 2;
M
Mr.doob 已提交
1223

1224
					offset_line += 6;
1225

1226
					vertexIndex += 3;
M
Mr.doob 已提交
1227

1228
				}
M
Mr.doob 已提交
1229

1230 1231 1232

			} else if ( face instanceof THREE.Face4 ) {

1233
				if ( dirtyVertices ) {
M
Mr.doob 已提交
1234

1235 1236 1237 1238
					v1 = vertices[ face.a ].position;
					v2 = vertices[ face.b ].position;
					v3 = vertices[ face.c ].position;
					v4 = vertices[ face.d ].position;
M
Mr.doob 已提交
1239

1240 1241 1242
					vertexArray[ offset ]     = v1.x;
					vertexArray[ offset + 1 ] = v1.y;
					vertexArray[ offset + 2 ] = v1.z;
M
Mr.doob 已提交
1243

1244 1245 1246
					vertexArray[ offset + 3 ] = v2.x;
					vertexArray[ offset + 4 ] = v2.y;
					vertexArray[ offset + 5 ] = v2.z;
1247

1248 1249 1250
					vertexArray[ offset + 6 ] = v3.x;
					vertexArray[ offset + 7 ] = v3.y;
					vertexArray[ offset + 8 ] = v3.z;
1251

1252
					vertexArray[ offset + 9 ]  = v4.x;
1253 1254
					vertexArray[ offset + 10 ] = v4.y;
					vertexArray[ offset + 11 ] = v4.z;
M
Mr.doob 已提交
1255

1256
					offset += 12;
M
Mr.doob 已提交
1257

1258
				}
1259

1260
				if ( customAttributes ) {
M
Mr.doob 已提交
1261

1262
					for ( a in customAttributes ) {
M
Mr.doob 已提交
1263

1264 1265
						customAttribute = customAttributes[ a ];

M
Mr.doob 已提交
1266
						if ( customAttribute.needsUpdate ) {
1267 1268

							offset_custom = customAttribute.offset;
1269
							offset_customSrc = customAttribute.offsetSrc;
M
Mr.doob 已提交
1270

1271
							if( customAttribute.size === 1 ) {
M
Mr.doob 已提交
1272

1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297
								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 已提交
1298

1299
								customAttribute.offset += 4;
M
Mr.doob 已提交
1300

1301
							} else {
M
Mr.doob 已提交
1302

1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328
								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 已提交
1329

1330
								if( customAttribute.size === 2 ) {
M
Mr.doob 已提交
1331 1332 1333

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

M
Mr.doob 已提交
1335 1336
									customAttribute.array[ offset_custom + 2 ] = v2.x;
									customAttribute.array[ offset_custom + 3 ] = v2.y;
1337

M
Mr.doob 已提交
1338
									customAttribute.array[ offset_custom + 4 ] = v3.x;
1339
									customAttribute.array[ offset_custom + 5 ] = v3.y;
1340

M
Mr.doob 已提交
1341
									customAttribute.array[ offset_custom + 6 ] = v4.x;
1342
									customAttribute.array[ offset_custom + 7 ] = v4.y;
M
Mr.doob 已提交
1343

1344
									customAttribute.offset += 8;
M
Mr.doob 已提交
1345

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

1348 1349 1350 1351 1352
									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;
1353

1354 1355 1356
										customAttribute.array[ offset_custom + 3  ] = v2.r;
										customAttribute.array[ offset_custom + 4  ] = v2.g;
										customAttribute.array[ offset_custom + 5  ] = v2.b;
1357

1358 1359 1360
										customAttribute.array[ offset_custom + 6  ] = v3.r;
										customAttribute.array[ offset_custom + 7  ] = v3.g;
										customAttribute.array[ offset_custom + 8  ] = v3.b;
1361

1362 1363 1364 1365 1366 1367 1368 1369 1370
										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;
1371

1372 1373 1374
										customAttribute.array[ offset_custom + 3  ] = v2.x;
										customAttribute.array[ offset_custom + 4  ] = v2.y;
										customAttribute.array[ offset_custom + 5  ] = v2.z;
1375

1376 1377 1378
										customAttribute.array[ offset_custom + 6  ] = v3.x;
										customAttribute.array[ offset_custom + 7  ] = v3.y;
										customAttribute.array[ offset_custom + 8  ] = v3.z;
1379

1380 1381 1382 1383 1384
										customAttribute.array[ offset_custom + 9  ] = v4.x;
										customAttribute.array[ offset_custom + 10 ] = v4.y;
										customAttribute.array[ offset_custom + 11 ] = v4.z;
										
									}
M
Mr.doob 已提交
1385

1386
									customAttribute.offset += 12;
M
Mr.doob 已提交
1387

1388
								} else {
M
Mr.doob 已提交
1389 1390 1391 1392 1393

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

M
Mr.doob 已提交
1395 1396 1397 1398
									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;
1399

M
Mr.doob 已提交
1400
									customAttribute.array[ offset_custom + 8  ] = v3.x;
1401 1402 1403
									customAttribute.array[ offset_custom + 9  ] = v3.y;
									customAttribute.array[ offset_custom + 10 ] = v3.z;
									customAttribute.array[ offset_custom + 11 ] = v3.w;
1404

M
Mr.doob 已提交
1405
									customAttribute.array[ offset_custom + 12 ] = v4.x;
1406 1407 1408
									customAttribute.array[ offset_custom + 13 ] = v4.y;
									customAttribute.array[ offset_custom + 14 ] = v4.z;
									customAttribute.array[ offset_custom + 15 ] = v4.w;
M
Mr.doob 已提交
1409

1410
									customAttribute.offset += 16;
M
Mr.doob 已提交
1411

1412
								}
M
Mr.doob 已提交
1413

1414
							}
M
Mr.doob 已提交
1415

1416
						}
M
Mr.doob 已提交
1417

1418
					}
M
Mr.doob 已提交
1419

1420 1421 1422
				}


1423
				if ( dirtyMorphTargets ) {
1424 1425 1426

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

1427 1428 1429 1430
						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;
1431

1432
						vka = morphTargetsArrays[ vk ];
1433

1434 1435 1436
						vka[ offset_morphTarget + 0 ] = v1.x;
						vka[ offset_morphTarget + 1 ] = v1.y;
						vka[ offset_morphTarget + 2 ] = v1.z;
1437

1438 1439 1440
						vka[ offset_morphTarget + 3 ] = v2.x;
						vka[ offset_morphTarget + 4 ] = v2.y;
						vka[ offset_morphTarget + 5 ] = v2.z;
1441

1442 1443 1444
						vka[ offset_morphTarget + 6 ] = v3.x;
						vka[ offset_morphTarget + 7 ] = v3.y;
						vka[ offset_morphTarget + 8 ] = v3.z;
1445

1446 1447 1448
						vka[ offset_morphTarget + 9 ] = v4.x;
						vka[ offset_morphTarget + 10 ] = v4.y;
						vka[ offset_morphTarget + 11 ] = v4.z;
1449 1450
					}

1451
					offset_morphTarget += 12;
1452

1453 1454
				}

A
alteredq 已提交
1455 1456 1457
				if ( obj_skinWeights.length ) {

					// weights
1458

A
alteredq 已提交
1459 1460 1461 1462
					sw1 = obj_skinWeights[ face.a ];
					sw2 = obj_skinWeights[ face.b ];
					sw3 = obj_skinWeights[ face.c ];
					sw4 = obj_skinWeights[ face.d ];
1463

A
alteredq 已提交
1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484
					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
1485

A
alteredq 已提交
1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511
					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
1512

A
alteredq 已提交
1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538
					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
1539

A
alteredq 已提交
1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559
					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;

1560 1561
					skinVertexBArray[ offset_skin + 12 ] = sb4.x;
					skinVertexBArray[ offset_skin + 13 ] = sb4.y;
A
alteredq 已提交
1562 1563 1564
					skinVertexBArray[ offset_skin + 14 ] = sb4.z;
					skinVertexBArray[ offset_skin + 15 ] = 1;

1565 1566
					offset_skin += 16;

A
alteredq 已提交
1567
				}
1568

1569 1570 1571
				if ( dirtyColors && vertexColorType ) {

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

1573 1574 1575 1576 1577 1578
						c1 = vertexColors[ 0 ];
						c2 = vertexColors[ 1 ];
						c3 = vertexColors[ 2 ];
						c4 = vertexColors[ 3 ];

					} else {
1579

1580 1581 1582 1583 1584 1585
						c1 = faceColor;
						c2 = faceColor;
						c3 = faceColor;
						c4 = faceColor;

					}
1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597

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

1599 1600 1601
					colorArray[ offset_color + 9 ]  = c4.r;
					colorArray[ offset_color + 10 ] = c4.g;
					colorArray[ offset_color + 11 ] = c4.b;
1602

1603 1604
					offset_color += 12;

1605 1606
				}

1607
				if ( dirtyTangents && geometry.hasTangents ) {
1608

1609 1610 1611 1612
					t1 = vertexTangents[ 0 ];
					t2 = vertexTangents[ 1 ];
					t3 = vertexTangents[ 2 ];
					t4 = vertexTangents[ 3 ];
1613

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

1619 1620 1621 1622
					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 已提交
1623

1624 1625
					tangentArray[ offset_tangent + 8 ]  = t3.x;
					tangentArray[ offset_tangent + 9 ]  = t3.y;
1626 1627
					tangentArray[ offset_tangent + 10 ] = t3.z;
					tangentArray[ offset_tangent + 11 ] = t3.w;
M
Mr.doob 已提交
1628

1629 1630 1631 1632
					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 已提交
1633

1634
					offset_tangent += 16;
M
Mr.doob 已提交
1635

1636
				}
M
Mr.doob 已提交
1637

M
Mr.doob 已提交
1638
				if ( dirtyNormals && normalType ) {
M
Mr.doob 已提交
1639

1640
					if ( vertexNormals.length == 4 && needsSmoothNormals ) {
1641

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

1644
							vn = vertexNormals[ i ];
M
Mr.doob 已提交
1645

1646 1647 1648
							normalArray[ offset_normal ]     = vn.x;
							normalArray[ offset_normal + 1 ] = vn.y;
							normalArray[ offset_normal + 2 ] = vn.z;
M
Mr.doob 已提交
1649

1650
							offset_normal += 3;
M
Mr.doob 已提交
1651

1652
						}
M
Mr.doob 已提交
1653

1654
					} else {
1655

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

1658 1659 1660
							normalArray[ offset_normal ]     = faceNormal.x;
							normalArray[ offset_normal + 1 ] = faceNormal.y;
							normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
1661

1662
							offset_normal += 3;
M
Mr.doob 已提交
1663

1664
						}
M
Mr.doob 已提交
1665 1666

					}
M
Mr.doob 已提交
1667

1668 1669
				}

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

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

1674
						uvi = uv[ i ];
M
Mr.doob 已提交
1675

1676 1677
						uvArray[ offset_uv ]     = uvi.u;
						uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
1678

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

M
Mr.doob 已提交
1681
					}
1682 1683

				}
1684

A
alteredq 已提交
1685
				if ( dirtyUvs && uv2 !== undefined && uvType ) {
1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698

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

1700
				if ( dirtyElements ) {
M
Mr.doob 已提交
1701

1702
					faceArray[ offset_face ]     = vertexIndex;
1703 1704
					faceArray[ offset_face + 1 ] = vertexIndex + 1;
					faceArray[ offset_face + 2 ] = vertexIndex + 3;
M
Mr.doob 已提交
1705

1706 1707 1708
					faceArray[ offset_face + 3 ] = vertexIndex + 1;
					faceArray[ offset_face + 4 ] = vertexIndex + 2;
					faceArray[ offset_face + 5 ] = vertexIndex + 3;
M
Mr.doob 已提交
1709

1710
					offset_face += 6;
M
Mr.doob 已提交
1711

1712 1713
					lineArray[ offset_line ]     = vertexIndex;
					lineArray[ offset_line + 1 ] = vertexIndex + 1;
M
Mr.doob 已提交
1714

1715
					lineArray[ offset_line + 2 ] = vertexIndex;
1716
					lineArray[ offset_line + 3 ] = vertexIndex + 3;
M
Mr.doob 已提交
1717

1718 1719
					lineArray[ offset_line + 4 ] = vertexIndex + 1;
					lineArray[ offset_line + 5 ] = vertexIndex + 2;
M
Mr.doob 已提交
1720

1721 1722
					lineArray[ offset_line + 6 ] = vertexIndex + 2;
					lineArray[ offset_line + 7 ] = vertexIndex + 3;
M
Mr.doob 已提交
1723

1724
					offset_line += 8;
M
Mr.doob 已提交
1725

1726
					vertexIndex += 4;
M
Mr.doob 已提交
1727

1728
				}
M
Mr.doob 已提交
1729

1730
			}
M
Mr.doob 已提交
1731

1732 1733
		}

1734 1735 1736 1737
		if ( obj_edgeFaces ) {

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

M
Mikael Emtinger 已提交
1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748
				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;
			}

1749
		}
M
Mikael Emtinger 已提交
1750

1751
		if ( dirtyVertices ) {
M
Mr.doob 已提交
1752

1753
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
1754
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
M
Mr.doob 已提交
1755

1756
		}
M
Mr.doob 已提交
1757

1758
		if ( customAttributes ) {
M
Mr.doob 已提交
1759

1760
			for ( a in customAttributes ) {
M
Mr.doob 已提交
1761

1762 1763
				customAttribute = customAttributes[ a ];

M
Mr.doob 已提交
1764
				if ( customAttribute.needsUpdate ) {
1765 1766 1767 1768

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

M
Mr.doob 已提交
1769
					customAttribute.needsUpdate = false;
1770

1771 1772 1773 1774 1775 1776
				}

			}

		}

1777
		if ( dirtyMorphTargets ) {
1778 1779 1780 1781

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

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

1784 1785 1786
			}
		}

1787
		if ( dirtyColors && offset_color > 0 ) {
1788

1789
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
1790 1791 1792
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}
1793

1794
		if ( dirtyNormals ) {
M
Mr.doob 已提交
1795

1796
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
1797
			_gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
M
Mr.doob 已提交
1798

1799 1800
		}

1801
		if ( dirtyTangents && geometry.hasTangents ) {
1802

1803
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
1804
			_gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint );
M
Mr.doob 已提交
1805

1806
		}
1807

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

1810
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
1811
			_gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
M
Mr.doob 已提交
1812

1813
		}
M
Mr.doob 已提交
1814

1815 1816
		if ( dirtyUvs && offset_uv2 > 0 ) {

1817
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
1818 1819 1820 1821
			_gl.bufferData( _gl.ARRAY_BUFFER, uv2Array, hint );

		}

1822
		if ( dirtyElements ) {
M
Mr.doob 已提交
1823

1824
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
1825
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint );
1826

1827
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
1828
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
M
Mr.doob 已提交
1829

1830
		}
1831

1832
		if ( offset_skin > 0 ) {
1833

1834
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
A
alteredq 已提交
1835 1836
			_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexAArray, hint );

1837
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
A
alteredq 已提交
1838 1839
			_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexBArray, hint );

1840
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
A
alteredq 已提交
1841 1842
			_gl.bufferData( _gl.ARRAY_BUFFER, skinIndexArray, hint );

1843
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
A
alteredq 已提交
1844
			_gl.bufferData( _gl.ARRAY_BUFFER, skinWeightArray, hint );
1845

A
alteredq 已提交
1846
		}
1847 1848

	};
1849

1850
	function setLineBuffers ( geometry, hint ) {
M
Mr.doob 已提交
1851

1852
		var v, c, vertex, offset,
1853 1854 1855 1856
		vertices = geometry.vertices,
		colors = geometry.colors,
		vl = vertices.length,
		cl = colors.length,
M
Mr.doob 已提交
1857

1858 1859
		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,
1860

1861 1862
		dirtyVertices = geometry.__dirtyVertices,
		dirtyColors = geometry.__dirtyColors;
M
Mr.doob 已提交
1863

1864
		if ( dirtyVertices ) {
M
Mr.doob 已提交
1865

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

1868
				vertex = vertices[ v ].position;
M
Mr.doob 已提交
1869

1870
				offset = v * 3;
M
Mr.doob 已提交
1871

1872 1873 1874
				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;
M
Mr.doob 已提交
1875

1876 1877
			}

1878
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
A
alteredq 已提交
1879 1880
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );

1881
		}
M
Mr.doob 已提交
1882

1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896
		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;

			}

1897
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
1898 1899 1900 1901
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}

1902
	};
M
Mr.doob 已提交
1903

1904
	function setRibbonBuffers ( geometry, hint ) {
A
alteredq 已提交
1905 1906

		var v, c, vertex, offset,
1907 1908 1909 1910
		vertices = geometry.vertices,
		colors = geometry.colors,
		vl = vertices.length,
		cl = colors.length,
A
alteredq 已提交
1911

1912 1913
		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,
1914

1915 1916
		dirtyVertices = geometry.__dirtyVertices,
		dirtyColors = geometry.__dirtyColors;
A
alteredq 已提交
1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931

		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;

			}

1932
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
A
alteredq 已提交
1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950
			_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;

			}

1951
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
A
alteredq 已提交
1952 1953 1954 1955 1956
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}

	};
1957

1958
	function setParticleBuffers ( geometry, hint, object ) {
1959

A
alteredq 已提交
1960
		var v, c, vertex, offset,
1961 1962
		vertices = geometry.vertices,
		vl = vertices.length,
1963

1964 1965
		colors = geometry.colors,
		cl = colors.length,
1966

1967 1968
		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,
1969

1970
		sortArray = geometry.__sortArray,
1971

1972 1973 1974
		dirtyVertices = geometry.__dirtyVertices,
		dirtyElements = geometry.__dirtyElements,
		dirtyColors = geometry.__dirtyColors;
1975

1976
		if ( object.sortParticles ) {
1977

1978
			_projScreenMatrix.multiplySelf( object.matrixWorld );
1979

1980 1981 1982
			for ( v = 0; v < vl; v++ ) {

				vertex = vertices[ v ].position;
1983

1984 1985
				_vector3.copy( vertex );
				_projScreenMatrix.multiplyVector3( _vector3 );
1986

1987
				sortArray[ v ] = [ _vector3.z, v ];
1988

1989
			}
1990

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

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

1995
				vertex = vertices[ sortArray[v][1] ].position;
1996

1997
				offset = v * 3;
1998

1999 2000 2001
				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;
2002

2003
			}
2004

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

A
alteredq 已提交
2007
				offset = c * 3;
2008

A
alteredq 已提交
2009 2010 2011 2012 2013
				color = colors[ sortArray[c][1] ];

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

2015
			}
2016 2017


2018
		} else {
2019

2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032
			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;

				}
2033 2034

			}
2035

A
alteredq 已提交
2036
			if ( dirtyColors ) {
2037

A
alteredq 已提交
2038 2039 2040 2041 2042 2043 2044 2045 2046 2047
				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;

2048
				}
2049

A
alteredq 已提交
2050
			}
2051 2052

		}
2053

A
alteredq 已提交
2054
		if ( dirtyVertices || object.sortParticles ) {
2055

2056
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
A
alteredq 已提交
2057
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
2058

A
alteredq 已提交
2059
		}
2060

A
alteredq 已提交
2061
		if ( dirtyColors || object.sortParticles ) {
2062

2063
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
A
alteredq 已提交
2064
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
2065

A
alteredq 已提交
2066
		}
2067

2068
	};
M
Mr.doob 已提交
2069

2070
	function setMaterialShaders( material, shaders ) {
2071

2072
		material.uniforms = THREE.UniformsUtils.clone( shaders.uniforms );
2073 2074
		material.vertexShader = shaders.vertexShader;
		material.fragmentShader = shaders.fragmentShader;
2075

M
Mr.doob 已提交
2076
	};
2077

2078
	function refreshUniformsCommon( uniforms, material ) {
M
Mr.doob 已提交
2079

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

2084
		uniforms.lightMap.texture = material.lightMap;
2085

2086
		uniforms.envMap.texture = material.envMap;
A
alteredq 已提交
2087
		uniforms.reflectivity.value = material.reflectivity;
2088
		uniforms.refractionRatio.value = material.refractionRatio;
A
alteredq 已提交
2089
		uniforms.combine.value = material.combine;
2090
		uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
2091

2092
	};
2093

2094
	function refreshUniformsLine( uniforms, material ) {
2095

M
Mr.doob 已提交
2096
		uniforms.diffuse.value = material.color;
A
alteredq 已提交
2097
		uniforms.opacity.value = material.opacity;
2098 2099

	};
M
Mr.doob 已提交
2100

2101
	function refreshUniformsParticle( uniforms, material ) {
2102

M
Mr.doob 已提交
2103
		uniforms.psColor.value = material.color;
A
alteredq 已提交
2104 2105
		uniforms.opacity.value = material.opacity;
		uniforms.size.value = material.size;
M
Mr.doob 已提交
2106
		uniforms.scale.value = _canvas.height / 2.0; // TODO: Cache this.
A
alteredq 已提交
2107
		uniforms.map.texture = material.map;
2108

A
alteredq 已提交
2109
	};
2110

2111
	function refreshUniformsFog( uniforms, fog ) {
2112

M
Mr.doob 已提交
2113
		uniforms.fogColor.value = fog.color;
2114

A
alteredq 已提交
2115
		if ( fog instanceof THREE.Fog ) {
2116

A
alteredq 已提交
2117 2118
			uniforms.fogNear.value = fog.near;
			uniforms.fogFar.value = fog.far;
2119

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

A
alteredq 已提交
2122
			uniforms.fogDensity.value = fog.density;
2123 2124

		}
2125

2126 2127
	};

2128
	function refreshUniformsPhong( uniforms, material ) {
M
Mr.doob 已提交
2129

M
Mr.doob 已提交
2130 2131
		uniforms.ambient.value = material.ambient;
		uniforms.specular.value = material.specular;
A
alteredq 已提交
2132
		uniforms.shininess.value = material.shininess;
M
Mr.doob 已提交
2133

2134
	};
M
Mr.doob 已提交
2135 2136


2137
	function refreshUniformsLights( uniforms, lights ) {
M
Mr.doob 已提交
2138

A
alteredq 已提交
2139 2140
		uniforms.enableLighting.value = lights.directional.length + lights.point.length;
		uniforms.ambientLightColor.value = lights.ambient;
2141

A
alteredq 已提交
2142 2143
		uniforms.directionalLightColor.value = lights.directional.colors;
		uniforms.directionalLightDirection.value = lights.directional.positions;
2144

A
alteredq 已提交
2145 2146
		uniforms.pointLightColor.value = lights.point.colors;
		uniforms.pointLightPosition.value = lights.point.positions;
2147
		uniforms.pointLightDistance.value = lights.point.distances;
M
Mr.doob 已提交
2148

A
alteredq 已提交
2149
	};
M
Mr.doob 已提交
2150

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

2153
		var u, a, identifiers, i, parameters, maxLightCount, maxBones, shaderID;
2154

A
alteredq 已提交
2155
		if ( material instanceof THREE.MeshDepthMaterial ) {
2156

2157
			shaderID = 'depth';
2158

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

2161
			shaderID = 'shadowVolumeDynamic';
M
Mikael Emtinger 已提交
2162

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

2165
			shaderID = 'normal';
2166

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

2169
			shaderID = 'basic';
2170

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

2173
			shaderID = 'lambert';
M
Mr.doob 已提交
2174

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

2177
			shaderID = 'phong';
M
Mr.doob 已提交
2178

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

2181
			shaderID = 'basic';
2182

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

2185 2186 2187 2188 2189 2190 2191
			shaderID = 'particle_basic';

		}

		if ( shaderID ) {

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

A
alteredq 已提交
2193
		}
2194

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

2198
		maxLightCount = allocateLights( lights, 4 );
2199

2200
		maxBones = allocateBones( object );
M
Mr.doob 已提交
2201

2202
		parameters = {
2203 2204
			map: !!material.map, envMap: !!material.envMap, lightMap: !!material.lightMap, 
			vertexColors: material.vertexColors,
2205 2206 2207
			fog: fog, sizeAttenuation: material.sizeAttenuation,
			skinning: material.skinning,
			morphTargets: material.morphTargets,
2208
			maxMorphTargets: this.maxMorphTargets,
2209 2210 2211
			maxDirLights: maxLightCount.directional, maxPointLights: maxLightCount.point,
			maxBones: maxBones
		};
M
Mikael Emtinger 已提交
2212

2213
		material.program = buildProgram( shaderID, material.fragmentShader, material.vertexShader, material.uniforms, material.attributes, parameters );
2214

2215
		var attributes = material.program.attributes;
2216

2217
		_gl.enableVertexAttribArray( attributes.position );
2218

2219 2220 2221
		if ( attributes.color >= 0 ) _gl.enableVertexAttribArray( attributes.color );
		if ( attributes.normal >= 0 ) _gl.enableVertexAttribArray( attributes.normal );
		if ( attributes.tangent >= 0 ) _gl.enableVertexAttribArray( attributes.tangent );
2222

2223 2224 2225
		if ( material.skinning &&
			 attributes.skinVertexA >=0 && attributes.skinVertexB >= 0 &&
			 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
2226

2227 2228 2229 2230
			_gl.enableVertexAttribArray( attributes.skinVertexA );
			_gl.enableVertexAttribArray( attributes.skinVertexB );
			_gl.enableVertexAttribArray( attributes.skinIndex );
			_gl.enableVertexAttribArray( attributes.skinWeight );
2231

2232
		}
2233

2234
		for ( a in material.attributes ) {
2235

2236
			if( attributes[ a ] >= 0 ) _gl.enableVertexAttribArray( attributes[ a ] );
2237

2238
		}
2239 2240


2241
		if ( material.morphTargets ) {
2242

2243
			material.numSupportedMorphTargets = 0;
2244

2245

2246
			if ( attributes.morphTarget0 >= 0 ) {
2247

2248 2249
				_gl.enableVertexAttribArray( attributes.morphTarget0 );
				material.numSupportedMorphTargets ++;
2250

2251
			}
2252

2253
			if ( attributes.morphTarget1 >= 0 ) {
2254

2255 2256
				_gl.enableVertexAttribArray( attributes.morphTarget1 );
				material.numSupportedMorphTargets ++;
2257

2258
			}
2259

2260
			if ( attributes.morphTarget2 >= 0 ) {
2261

2262 2263
				_gl.enableVertexAttribArray( attributes.morphTarget2 );
				material.numSupportedMorphTargets ++;
2264

2265
			}
2266

2267
			if ( attributes.morphTarget3 >= 0 ) {
2268

2269 2270
				_gl.enableVertexAttribArray( attributes.morphTarget3 );
				material.numSupportedMorphTargets ++;
2271

2272
			}
2273

2274
			if ( attributes.morphTarget4 >= 0 ) {
2275

2276 2277
				_gl.enableVertexAttribArray( attributes.morphTarget4 );
				material.numSupportedMorphTargets ++;
2278

2279
			}
2280

2281
			if ( attributes.morphTarget5 >= 0 ) {
2282

2283 2284
				_gl.enableVertexAttribArray( attributes.morphTarget5 );
				material.numSupportedMorphTargets ++;
2285

2286
			}
2287

2288
			if ( attributes.morphTarget6 >= 0 ) {
2289

2290 2291
				_gl.enableVertexAttribArray( attributes.morphTarget6 );
				material.numSupportedMorphTargets ++;
2292

2293
			}
2294

2295
			if ( attributes.morphTarget7 >= 0 ) {
2296

2297 2298
				_gl.enableVertexAttribArray( attributes.morphTarget7 );
				material.numSupportedMorphTargets ++;
2299

2300
			}
2301

2302
			object.__webglMorphTargetInfluences = new Float32Array( this.maxMorphTargets );
2303

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

2306
				object.__webglMorphTargetInfluences[ i ] = 0;
2307 2308 2309

			}

2310
		}
M
Mr.doob 已提交
2311

2312
	};
2313

2314
	function setProgram( camera, lights, fog, material, object ) {
2315

2316
		if ( ! material.program ) {
2317 2318 2319 2320

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

		}
M
Mr.doob 已提交
2321

2322
		var program = material.program,
A
alteredq 已提交
2323 2324
			p_uniforms = program.uniforms,
			m_uniforms = material.uniforms;
2325

2326
		if ( program != _currentProgram ) {
M
Mr.doob 已提交
2327

M
Mr.doob 已提交
2328
			_gl.useProgram( program );
2329
			_currentProgram = program;
2330

M
Mr.doob 已提交
2331
		}
2332

2333 2334
		_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, _projectionMatrixArray );

A
alteredq 已提交
2335
		// refresh uniforms common to several materials
2336 2337

		if ( fog && (
A
alteredq 已提交
2338 2339
			 material instanceof THREE.MeshBasicMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
2340
			 material instanceof THREE.MeshPhongMaterial ||
A
alteredq 已提交
2341
			 material instanceof THREE.LineBasicMaterial ||
2342 2343
			 material instanceof THREE.ParticleBasicMaterial ||
			 material.fog )
A
alteredq 已提交
2344
			) {
2345

A
alteredq 已提交
2346
			refreshUniformsFog( m_uniforms, fog );
2347 2348

		}
M
Mr.doob 已提交
2349

M
Mr.doob 已提交
2350
		if ( material instanceof THREE.MeshPhongMaterial ||
2351 2352
			 material instanceof THREE.MeshLambertMaterial ||
			 material.lights ) {
2353

A
alteredq 已提交
2354
			setupLights( program, lights );
A
alteredq 已提交
2355
			refreshUniformsLights( m_uniforms, _lights );
M
Mr.doob 已提交
2356 2357 2358

		}

2359 2360 2361
		if ( material instanceof THREE.MeshBasicMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
			 material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
2362

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

A
alteredq 已提交
2365
		}
M
Mr.doob 已提交
2366

A
alteredq 已提交
2367
		// refresh single material specific uniforms
2368

2369
		if ( material instanceof THREE.LineBasicMaterial ) {
M
Mr.doob 已提交
2370

A
alteredq 已提交
2371
			refreshUniformsLine( m_uniforms, material );
2372

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

A
alteredq 已提交
2375
			refreshUniformsParticle( m_uniforms, material );
2376

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

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

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

2383 2384
			m_uniforms.mNear.value = camera.near;
			m_uniforms.mFar.value = camera.far;
A
alteredq 已提交
2385
			m_uniforms.opacity.value = material.opacity;
2386

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

A
alteredq 已提交
2389
			m_uniforms.opacity.value = material.opacity;
2390
		}
2391

A
alteredq 已提交
2392
		// load common uniforms
2393

A
alteredq 已提交
2394 2395
		loadUniformsGeneric( program, m_uniforms );
		loadUniformsMatrices( p_uniforms, object );
2396

A
alteredq 已提交
2397 2398
		// load material specific uniforms
		// (shader material also gets them for the sake of genericity)
2399

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

2404 2405 2406 2407 2408
			if( p_uniforms.cameraPosition >= 0 ) {
				
				_gl.uniform3f( p_uniforms.cameraPosition, camera.position.x, camera.position.y, camera.position.z );
				
			}
2409

2410
		}
2411

A
alteredq 已提交
2412
		if ( material instanceof THREE.MeshShaderMaterial ||
2413
			 material.envMap ||
2414
			 material.skinning ) {
2415

2416 2417 2418 2419 2420
			if ( p_uniforms.objectMatrix >= 0 ) {
				
				_gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object._objectMatrixArray );
				
			}
2421

A
alteredq 已提交
2422
		}
2423

A
alteredq 已提交
2424 2425
		if ( material instanceof THREE.MeshPhongMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
A
alteredq 已提交
2426
			 material instanceof THREE.MeshShaderMaterial ||
2427 2428
			 material.skinning ) {

2429 2430 2431 2432 2433
			if( p_uniforms.viewMatrix >= 0 ) {
				
				_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, _viewMatrixArray );
				
			} 
2434

A
alteredq 已提交
2435
		}
2436

2437 2438
		if ( material instanceof THREE.ShadowVolumeDynamicMaterial ) {

M
Mikael Emtinger 已提交
2439
			var dirLight = m_uniforms.directionalLightDirection.value;
2440

2441 2442 2443
			dirLight[ 0 ] = -lights[ 1 ].position.x;
			dirLight[ 1 ] = -lights[ 1 ].position.y;
			dirLight[ 2 ] = -lights[ 1 ].position.z;
2444

M
Mikael Emtinger 已提交
2445 2446 2447 2448 2449 2450
			_gl.uniform3fv( p_uniforms.directionalLightDirection, dirLight );
			_gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object._objectMatrixArray );
			_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, _viewMatrixArray );
		}


2451
		if ( material.skinning ) {
2452

2453
			loadUniformsSkinning( p_uniforms, object );
2454

A
alteredq 已提交
2455
		}
2456

A
alteredq 已提交
2457
		return program;
2458

A
alteredq 已提交
2459
	};
2460

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

2463 2464
		if ( material.opacity == 0 ) return;

2465
		var program, attributes, linewidth, primitives, a, attribute;
A
alteredq 已提交
2466

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

2469
		attributes = program.attributes;
M
Mr.doob 已提交
2470

2471
		// vertices
M
Mr.doob 已提交
2472

2473
		if ( !material.morphTargets && attributes.position >= 0 ) {
2474 2475

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

2478
		} else {
2479

M
Mikael Emtinger 已提交
2480
			setupMorphTargets( material, geometryGroup, object );
2481

2482 2483
		}

2484 2485 2486 2487

		// custom attributes

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

2489
			for( a in geometryGroup.__webglCustomAttributes ) {
M
Mr.doob 已提交
2490

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

2493
					attribute = geometryGroup.__webglCustomAttributes[ a ];
M
Mr.doob 已提交
2494

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

2498
				}
M
Mr.doob 已提交
2499

2500
			}
M
Mr.doob 已提交
2501

2502 2503 2504
		}


A
alteredq 已提交
2505 2506 2507 2508
		// colors

		if ( attributes.color >= 0 ) {

2509
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
2510
			_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
2511 2512 2513

		}

2514
		// normals
M
Mr.doob 已提交
2515

2516
		if ( attributes.normal >= 0 ) {
2517

2518
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
2519
			_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
2520

2521
		}
2522

2523 2524 2525
		// tangents

		if ( attributes.tangent >= 0 ) {
2526

2527
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
2528
			_gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
2529

2530
		}
2531

2532
		// uvs
M
Mr.doob 已提交
2533

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

2536
			if ( geometryGroup.__webglUVBuffer ) {
2537

2538
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
2539
				_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
2540

2541
				_gl.enableVertexAttribArray( attributes.uv );
2542

2543
			} else {
2544

2545
				_gl.disableVertexAttribArray( attributes.uv );
M
Mr.doob 已提交
2546

2547
			}
2548 2549 2550

		}

2551 2552
		if ( attributes.uv2 >= 0 ) {

2553
			if ( geometryGroup.__webglUV2Buffer ) {
2554

2555
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567
				_gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );

				_gl.enableVertexAttribArray( attributes.uv2 );

			} else {

				_gl.disableVertexAttribArray( attributes.uv2 );

			}

		}

2568
		if ( material.skinning &&
2569
			 attributes.skinVertexA >= 0 && attributes.skinVertexB >= 0 &&
A
alteredq 已提交
2570
			 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
2571

2572
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
A
alteredq 已提交
2573 2574
			_gl.vertexAttribPointer( attributes.skinVertexA, 4, _gl.FLOAT, false, 0, 0 );

2575
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
A
alteredq 已提交
2576 2577
			_gl.vertexAttribPointer( attributes.skinVertexB, 4, _gl.FLOAT, false, 0, 0 );

2578
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
A
alteredq 已提交
2579 2580
			_gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 );

2581
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
A
alteredq 已提交
2582
			_gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 );
2583

A
alteredq 已提交
2584
		}
2585

2586
		// render mesh
M
Mr.doob 已提交
2587

2588
		if ( object instanceof THREE.Mesh ) {
2589

2590
			// wireframe
2591

2592
			if ( material.wireframe ) {
M
Mr.doob 已提交
2593

2594
				_gl.lineWidth( material.wireframeLinewidth );
2595 2596
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
				_gl.drawElements( _gl.LINES, geometryGroup.__webglLineCount, _gl.UNSIGNED_SHORT, 0 );
2597

2598
			// triangles
2599

2600
			} else {
2601

2602 2603 2604
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
				_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );

2605
			}
2606

2607 2608 2609
			_this.data.vertices += geometryGroup.__webglFaceCount;
			_this.data.faces += geometryGroup.__webglFaceCount / 3;

2610
		// render lines
2611

2612
		} else if ( object instanceof THREE.Line ) {
2613

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

2616
			_gl.lineWidth( material.linewidth );
2617
			_gl.drawArrays( primitives, 0, geometryGroup.__webglLineCount );
2618

2619
		// render particles
2620

2621
		} else if ( object instanceof THREE.ParticleSystem ) {
2622

2623
			_gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webglParticleCount );
2624

A
alteredq 已提交
2625
		// render ribbon
2626

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

2629
			_gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webglVertexCount );
2630

2631 2632 2633 2634
		}

	};

M
Mikael Emtinger 已提交
2635

M
Mikael Emtinger 已提交
2636
	function setupMorphTargets( material, geometryGroup, object ) {
2637

M
Mikael Emtinger 已提交
2638
		// set base
2639

M
Mikael Emtinger 已提交
2640
		var attributes = material.program.attributes;
2641

2642
		if (  object.morphTargetBase !== - 1 ) {
2643 2644

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

2647
		} else if ( attributes.position >= 0 ) {
2648 2649

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

M
Mikael Emtinger 已提交
2652
		}
2653

2654
		if ( object.morphTargetForcedOrder.length ) {
M
Mikael Emtinger 已提交
2655 2656

			// set forced order
2657

M
Mikael Emtinger 已提交
2658 2659 2660
			var m = 0;
			var order = object.morphTargetForcedOrder;
			var influences = object.morphTargetInfluences;
2661 2662 2663 2664

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

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

2667 2668 2669 2670
				object.__webglMorphTargetInfluences[ m ] = influences[ order[ m ]];

				m ++;
			}
2671

M
Mikael Emtinger 已提交
2672
		} else {
2673

M
Mikael Emtinger 已提交
2674
			// find most influencing
2675

M
Mikael Emtinger 已提交
2676
			var used = [];
2677
			var candidateInfluence = - 1;
M
Mikael Emtinger 已提交
2678 2679 2680 2681
			var candidate = 0;
			var influences = object.morphTargetInfluences;
			var i, il = influences.length;
			var m = 0;
2682

2683
			if ( object.morphTargetBase !== - 1 ) {
2684

M
Mikael Emtinger 已提交
2685
				used[ object.morphTargetBase ] = true;
2686

M
Mikael Emtinger 已提交
2687
			}
2688 2689 2690

			while ( m < material.numSupportedMorphTargets ) {

2691
				for ( i = 0; i < il; i ++ ) {
2692 2693 2694

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

M
Mikael Emtinger 已提交
2695 2696
						candidate = i;
						candidateInfluence = influences[ candidate ];
2697

M
Mikael Emtinger 已提交
2698 2699
					}
				}
2700 2701

				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ candidate ] );
M
Mikael Emtinger 已提交
2702
				_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
2703 2704 2705

				object.__webglMorphTargetInfluences[ m ] = candidateInfluence;

M
Mikael Emtinger 已提交
2706 2707
				used[ candidate ] = 1;
				candidateInfluence = -1;
2708
				m ++;
M
Mikael Emtinger 已提交
2709 2710 2711 2712
			}
		}

		// load updated influences uniform
2713

2714 2715 2716 2717 2718 2719
		if( material.program.uniforms.morphTargetInfluences !== null ) {
			
			_gl.uniform1fv( material.program.uniforms.morphTargetInfluences, object.__webglMorphTargetInfluences );
			
		}

M
Mikael Emtinger 已提交
2720 2721 2722
	}


2723
	function renderBufferImmediate( object, program, shading ) {
2724

2725 2726
		if ( ! object.__webglVertexBuffer ) object.__webglVertexBuffer = _gl.createBuffer();
		if ( ! object.__webglNormalBuffer ) object.__webglNormalBuffer = _gl.createBuffer();
2727

A
alteredq 已提交
2728
		if ( object.hasPos ) {
2729

2730 2731 2732 2733
			_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 );
2734

A
alteredq 已提交
2735
		}
2736

A
alteredq 已提交
2737
		if ( object.hasNormal ) {
2738

2739
			_gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglNormalBuffer );
2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783

			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;

				}

			}

2784 2785 2786
			_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 );
2787

A
alteredq 已提交
2788
		}
2789

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

A
alteredq 已提交
2792
		object.count = 0;
2793

A
alteredq 已提交
2794
	};
2795

2796
	function setObjectFaces( object ) {
2797

2798
		if ( _oldDoubleSided != object.doubleSided ) {
2799

2800
			if( object.doubleSided ) {
2801

2802
				_gl.disable( _gl.CULL_FACE );
2803

2804
			} else {
2805

A
alteredq 已提交
2806
				_gl.enable( _gl.CULL_FACE );
2807

A
alteredq 已提交
2808
			}
2809

2810
			_oldDoubleSided = object.doubleSided;
2811

2812
		}
2813

2814
		if ( _oldFlipSided != object.flipSided ) {
2815

2816 2817 2818 2819
			if( object.flipSided ) {

				_gl.frontFace( _gl.CW );

2820
			} else {
2821 2822 2823 2824

				_gl.frontFace( _gl.CCW );

			}
2825

2826
			_oldFlipSided = object.flipSided;
2827 2828

		}
2829

2830
	};
2831

2832
	function setDepthTest( test ) {
2833

A
alteredq 已提交
2834 2835 2836
		if ( _oldDepth != test ) {

			if( test ) {
2837

A
alteredq 已提交
2838
				_gl.enable( _gl.DEPTH_TEST );
2839

A
alteredq 已提交
2840
			} else {
2841

A
alteredq 已提交
2842
				_gl.disable( _gl.DEPTH_TEST );
2843

A
alteredq 已提交
2844
			}
2845

A
alteredq 已提交
2846 2847 2848
			_oldDepth = test;

		}
2849

A
alteredq 已提交
2850
	};
2851

2852
	function computeFrustum( m ) {
2853 2854 2855 2856 2857 2858 2859 2860 2861

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

A
alteredq 已提交
2863
		for ( i = 0; i < 6; i ++ ) {
2864 2865 2866 2867 2868 2869 2870

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

		}

	};
2871

2872
	function isInFrustum( object ) {
2873

2874
		var distance, matrix = object.matrixWorld,
2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886
		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;

	};
2887

2888
	function addToFixedArray( where, what ) {
2889

2890 2891
		where.list[ where.count ] = what;
		where.count += 1;
2892

2893
	};
2894

2895
	function unrollImmediateBufferMaterials( globject ) {
2896

2897 2898 2899 2900 2901 2902 2903
		var i, l, m, ml, material,
			object = globject.object,
			opaque = globject.opaque,
			transparent = globject.transparent;

		transparent.count = 0;
		opaque.count = 0;
2904

2905 2906 2907
		for ( m = 0, ml = object.materials.length; m < ml; m++ ) {

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

2910
		}
2911

2912
	};
2913

2914
	function unrollBufferMaterials( globject ) {
2915

2916 2917 2918 2919 2920 2921 2922 2923
		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;
2924

2925 2926 2927 2928 2929 2930 2931 2932 2933
		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 ];
2934
					if ( material ) material.transparent ? addToFixedArray( transparent, material ) : addToFixedArray( opaque, material );
2935 2936 2937 2938 2939 2940

				}

			} else {

				material = meshMaterial;
2941
				if ( material ) material.transparent ? addToFixedArray( transparent, material ) : addToFixedArray( opaque, material );
2942

2943 2944 2945
			}

		}
2946

2947
	};
2948 2949


2950
	function painterSort( a, b ) {
2951

2952
		return b.z - a.z;
2953 2954

	};
2955

2956
	this.render = function( scene, camera, renderTarget, forceClear ) {
2957

A
alteredq 已提交
2958
		var i, program, opaque, transparent, material,
2959
			o, ol, oil, webglObject, object, buffer,
A
alteredq 已提交
2960
			lights = scene.lights,
N
Nicholas Kinsey 已提交
2961
			fog = scene.fog;
2962

2963 2964 2965
		_this.data.vertices = 0;
		_this.data.faces = 0;

2966
		camera.matrixAutoUpdate && camera.update( undefined, true );
2967

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

M
Mr.doob 已提交
2970
		camera.matrixWorldInverse.flattenToArray( _viewMatrixArray );
2971
		camera.projectionMatrix.flattenToArray( _projectionMatrixArray );
M
Mr.doob 已提交
2972

M
Mr.doob 已提交
2973
		_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
2974
		computeFrustum( _projScreenMatrix );
2975

A
alteredq 已提交
2976
		this.initWebGLObjects( scene );
M
Mr.doob 已提交
2977

A
alteredq 已提交
2978
		setRenderTarget( renderTarget );
M
Mr.doob 已提交
2979

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

2982
			this.clear();
M
Mr.doob 已提交
2983

2984 2985
		}

2986
		// set matrices
2987

2988
		ol = scene.__webglObjects.length;
2989

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

2992 2993
			webglObject = scene.__webglObjects[ o ];
			object = webglObject.object;
M
Mr.doob 已提交
2994

2995
			if ( object.visible ) {
2996 2997

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

2999
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
3000

3001
					setupMatrices( object, camera );
3002

3003
					unrollBufferMaterials( webglObject );
3004

3005
					webglObject.render = true;
3006

3007
					if ( this.sortObjects ) {
3008

3009 3010 3011
						_vector3.copy( object.position );
						_projScreenMatrix.multiplyVector3( _vector3 );

3012
						webglObject.z = _vector3.z;
3013

3014
					}
3015

3016
				} else {
3017

3018
					webglObject.render = false;
3019

3020
				}
3021

3022
			} else {
3023

3024
				webglObject.render = false;
3025

3026
			}
3027

3028
		}
3029

3030
		if ( this.sortObjects ) {
3031

3032
			scene.__webglObjects.sort( painterSort );
3033

3034
		}
3035

3036
		oil = scene.__webglObjectsImmediate.length;
3037

3038
		for ( o = 0; o < oil; o++ ) {
3039

3040 3041
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
3042

3043
			if ( object.visible ) {
3044 3045 3046

				if( object.matrixAutoUpdate ) {

3047
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
3048

A
alteredq 已提交
3049
				}
3050

3051
				setupMatrices( object, camera );
3052

3053
				unrollImmediateBufferMaterials( webglObject );
3054

3055
			}
3056

3057
		}
A
alteredq 已提交
3058

3059 3060
		// opaque pass

3061
		setBlending( THREE.NormalBlending );
3062

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

3065
			webglObject = scene.__webglObjects[ o ];
3066

3067
			if ( webglObject.render ) {
3068

3069 3070 3071
				object = webglObject.object;
				buffer = webglObject.buffer;
				opaque = webglObject.opaque;
3072

3073
				setObjectFaces( object );
3074

3075
				for ( i = 0; i < opaque.count; i ++ ) {
3076

3077
					material = opaque.list[ i ];
3078

3079
					setDepthTest( material.depthTest );
A
alteredq 已提交
3080
					renderBuffer( camera, lights, fog, material, buffer, object );
3081

3082
				}
3083 3084 3085 3086 3087

			}

		}

A
alteredq 已提交
3088
		// opaque pass (immediate simulator)
3089

3090
		for ( o = 0; o < oil; o++ ) {
3091

3092 3093
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
3094

A
alteredq 已提交
3095
			if ( object.visible ) {
3096

3097
				opaque = webglObject.opaque;
3098

3099
				setObjectFaces( object );
3100

3101
				for( i = 0; i < opaque.count; i++ ) {
3102

3103
					material = opaque.list[ i ];
3104

3105
					setDepthTest( material.depthTest );
3106

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

3110
				}
3111

A
alteredq 已提交
3112
			}
3113

A
alteredq 已提交
3114 3115
		}

3116 3117
		// transparent pass

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

3120
			webglObject = scene.__webglObjects[ o ];
3121

3122
			if ( webglObject.render ) {
3123

3124 3125 3126
				object = webglObject.object;
				buffer = webglObject.buffer;
				transparent = webglObject.transparent;
3127

3128
				setObjectFaces( object );
3129

3130
				for ( i = 0; i < transparent.count; i ++ ) {
3131

3132
					material = transparent.list[ i ];
3133

3134
					setBlending( material.blending );
3135
					setDepthTest( material.depthTest );
3136

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

3139
				}
3140

3141
			}
M
Mr.doob 已提交
3142

M
Mr.doob 已提交
3143
		}
M
Mr.doob 已提交
3144

3145
		// transparent pass (immediate simulator)
3146

3147
		for ( o = 0; o < oil; o++ ) {
3148

3149 3150
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
3151

3152
			if ( object.visible ) {
3153

3154
				transparent = webglObject.transparent;
3155

3156
				setObjectFaces( object );
3157

3158
				for ( i = 0; i < transparent.count; i ++ ) {
3159

3160
					material = transparent.list[ i ];
3161

3162
					setBlending( material.blending );
3163
					setDepthTest( material.depthTest );
3164

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

3168
				}
3169

3170
			}
3171

3172
		}
3173

M
Mikael Emtinger 已提交
3174
		// render 2d
3175

M
Mikael Emtinger 已提交
3176
		if ( scene.__webglSprites.length ) {
3177

3178
			renderSprites( scene, camera );
3179

M
Mikael Emtinger 已提交
3180 3181
		}

M
Mikael Emtinger 已提交
3182
		// render stencil shadows
M
Mikael Emtinger 已提交
3183

3184
		if ( stencil && scene.__webglShadowVolumes.length && scene.lights.length ) {
M
Mikael Emtinger 已提交
3185 3186

			renderStencilShadows( scene );
3187

M
Mikael Emtinger 已提交
3188 3189
		}

3190

3191
		// render lens flares
3192 3193 3194

		if ( scene.__webglLensFlares.length ) {

3195
			renderLensFlares( scene, camera );
3196

3197 3198
		}

M
Mikael Emtinger 已提交
3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221

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

M
Mikael Emtinger 已提交
3223 3224 3225 3226 3227
		// setup stencil

		_gl.enable( _gl.POLYGON_OFFSET_FILL );
		_gl.polygonOffset( 0.1, 1.0 );
		_gl.enable( _gl.STENCIL_TEST );
3228
		_gl.enable( _gl.DEPTH_TEST );
M
Mikael Emtinger 已提交
3229 3230
		_gl.depthMask( false );
		_gl.colorMask( false, false, false, false );
3231

M
Mikael Emtinger 已提交
3232 3233 3234 3235
		_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 );

3236

M
Mikael Emtinger 已提交
3237
		// loop through all directional lights
3238

M
Mikael Emtinger 已提交
3239 3240
		var l, ll = scene.lights.length;
		var p;
M
Mikael Emtinger 已提交
3241
		var light, lights = scene.lights;
3242
		var dirLight = [];
M
Mikael Emtinger 已提交
3243
		var object, geometryGroup, material;
3244
		var program;
M
Mikael Emtinger 已提交
3245
		var p_uniforms;
3246 3247
		var m_uniforms;
		var attributes;
M
Mikael Emtinger 已提交
3248
		var o, ol = scene.__webglShadowVolumes.length;
3249 3250 3251

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

M
Mikael Emtinger 已提交
3252
			light = scene.lights[ l ];
3253

3254
			if ( light instanceof THREE.DirectionalLight && light.castShadow ) {
M
Mikael Emtinger 已提交
3255 3256 3257 3258 3259 3260

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

				// render all volumes
3261 3262 3263

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

M
Mikael Emtinger 已提交
3264 3265 3266
					object        = scene.__webglShadowVolumes[ o ].object;
					geometryGroup = scene.__webglShadowVolumes[ o ].buffer;
					material      = object.materials[ 0 ];
3267

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

M
Mikael Emtinger 已提交
3270 3271
					program = material.program,
		  			p_uniforms = program.uniforms,
3272 3273
					m_uniforms = material.uniforms,
					attributes = program.attributes;
3274

3275
					if ( _currentProgram !== program ) {
3276

M
Mikael Emtinger 已提交
3277
						_gl.useProgram( program );
M
Mikael Emtinger 已提交
3278
						_currentProgram = program;
3279

M
Mikael Emtinger 已提交
3280 3281 3282 3283
						_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, _projectionMatrixArray );
						_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, _viewMatrixArray );
						_gl.uniform3fv( p_uniforms.directionalLightDirection, dirLight );
					}
3284 3285


M
Mikael Emtinger 已提交
3286 3287
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
					_gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object._objectMatrixArray );
3288 3289


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

M
Mikael Emtinger 已提交
3293
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
M
Mikael Emtinger 已提交
3294
					_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
3295

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

M
Mikael Emtinger 已提交
3298
					_gl.cullFace( _gl.FRONT );
M
Mikael Emtinger 已提交
3299
					_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );
3300

M
Mikael Emtinger 已提交
3301
					_gl.cullFace( _gl.BACK );
M
Mikael Emtinger 已提交
3302
					_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );
3303

M
Mikael Emtinger 已提交
3304
				}
M
Mikael Emtinger 已提交
3305

M
Mikael Emtinger 已提交
3306
			}
M
Mikael Emtinger 已提交
3307

M
Mikael Emtinger 已提交
3308 3309
		}

3310

M
Mikael Emtinger 已提交
3311
		// setup color+stencil
M
Mikael Emtinger 已提交
3312

M
Mikael Emtinger 已提交
3313 3314 3315 3316
		_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 );
3317
		_gl.disable( _gl.DEPTH_TEST );
M
Mikael Emtinger 已提交
3318 3319


3320
		// draw darkening polygon
M
Mr.doob 已提交
3321

M
Mikael Emtinger 已提交
3322
		_oldBlending = "";
M
Mikael Emtinger 已提交
3323
		_currentProgram = _stencilShadow.program;
M
Mr.doob 已提交
3324

M
Mikael Emtinger 已提交
3325 3326 3327
		_gl.useProgram( _stencilShadow.program );
		_gl.uniformMatrix4fv( _stencilShadow.projectionLocation, false, _projectionMatrixArray );
		_gl.uniform1f( _stencilShadow.darknessLocation, _stencilShadow.darkness );
3328

M
Mikael Emtinger 已提交
3329 3330 3331
		_gl.bindBuffer( _gl.ARRAY_BUFFER, _stencilShadow.vertexBuffer );
		_gl.vertexAttribPointer( _stencilShadow.vertexLocation, 3, _gl.FLOAT, false, 0, 0 );
		_gl.enableVertexAttribArray( _stencilShadow.vertexLocation );
M
Mr.doob 已提交
3332

M
Mikael Emtinger 已提交
3333 3334
		_gl.blendFunc( _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
		_gl.blendEquation( _gl.FUNC_ADD );
3335

M
Mikael Emtinger 已提交
3336
		_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _stencilShadow.elementBuffer );
M
Mikael Emtinger 已提交
3337 3338 3339 3340 3341
		_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );


		// disable stencil

3342 3343 3344 3345
		_gl.disable( _gl.STENCIL_TEST );
		_gl.enable( _gl.DEPTH_TEST );
		_gl.depthMask( _currentDepthMask );

M
Mikael Emtinger 已提交
3346
	}
3347

3348

3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367
	/*
	 * 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
3368

3369 3370 3371 3372
		_gl.useProgram( _sprite.program );
		_currentProgram = _sprite.program;
		_oldBlending = "";

M
Mr.doob 已提交
3373
		if ( !_spriteAttributesEnabled ) {
3374

M
Mr.doob 已提交
3375 3376
			_gl.enableVertexAttribArray( _sprite.attributes.position );
			_gl.enableVertexAttribArray( _sprite.attributes.uv );
3377

M
Mr.doob 已提交
3378 3379 3380
			_spriteAttributesEnabled = true;

		}
3381

3382
		_gl.disable( _gl.CULL_FACE );
3383
		_gl.enable( _gl.BLEND );
3384
		_gl.depthMask( true );
3385 3386 3387 3388 3389 3390

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

3392 3393 3394 3395
		_gl.uniformMatrix4fv( uniforms.projectionMatrix, false, _projectionMatrixArray );

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

3397
		// update positions and sort
3398

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

3401
			object = scene.__webglSprites[ o ];
3402

3403
			if( !object.useScreenCoordinates ) {
3404

3405 3406
				object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
				object.z = -object._modelViewMatrix.n34;
3407

3408
			} else {
3409

3410
				object.z = -object.position.z;
3411

3412
			}
3413

3414 3415 3416
		}

		scene.__webglSprites.sort( painterSort );
3417 3418

		// render all non-custom shader sprites
3419 3420

		for ( o = 0, ol = scene.__webglSprites.length; o < ol; o++ ) {
3421 3422 3423

			object = scene.__webglSprites[ o ];

3424 3425 3426 3427 3428
			if ( object.material === undefined ) {

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

					if ( object.useScreenCoordinates ) {
3429 3430 3431 3432

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

3435 3436
					} else {

3437

3438 3439 3440 3441

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

3443
					}
3444

3445
					size = object.map.image.width / ( object.affectedByDistance ? 1 : _viewportHeight );
3446
					scale[ 0 ] = size * invAspect * object.scale.x;
3447
					scale[ 1 ] = size * object.scale.y;
3448

3449 3450 3451 3452 3453 3454 3455
					_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 );

3456 3457
					if ( object.mergeWith3D && !mergeWith3D ) {

3458 3459
						_gl.enable( _gl.DEPTH_TEST );
						mergeWith3D = true;
3460 3461 3462

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

3463 3464
						_gl.disable( _gl.DEPTH_TEST );
						mergeWith3D = false;
3465

3466
					}
3467

3468 3469
					setBlending( object.blending );
					setTexture( object.map, 0 );
3470

3471 3472
					_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
				}
3473

3474
			} else {
3475

3476
				anyCustom = true;
3477

3478
			}
3479

3480 3481 3482 3483 3484
		}


		// loop through all custom

3485 3486 3487
		/*
		if( anyCustom ) {

3488
		}
3489
		*/
3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500

		// restore gl

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

	}



3501 3502 3503 3504 3505 3506 3507 3508 3509 3510
	/*
	 * 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 ) {
3511

3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533
		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 已提交
3534
		_currentProgram = _lensFlare.program;
3535 3536 3537
		_oldBlending = "";


M
Mr.doob 已提交
3538 3539 3540 3541 3542 3543 3544 3545 3546
		if ( ! _lensFlareAttributesEnabled ) {
		
			_gl.enableVertexAttribArray( _lensFlare.attributes.vertex );
			_gl.enableVertexAttribArray( _lensFlare.attributes.uv );
			
			_lensFlareAttributesEnabled = true;

		}

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

3550 3551
		_gl.uniform1i( uniforms.occlusionMap, 0 );
		_gl.uniform1i( uniforms.map, 1 );
3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562

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

3563 3564 3565 3566
		_gl.activeTexture( _gl.TEXTURE0 );
		_gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.occlusionTexture );

		_gl.activeTexture( _gl.TEXTURE1 );
3567

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

3570
			// calc object screen position
3571

3572
			object = scene.__webglLensFlares[ o ].object;
3573

3574
			tempPosition.set( object.matrixWorld.n14, object.matrixWorld.n24, object.matrixWorld.n34 );
3575

3576 3577 3578
			camera.matrixWorldInverse.multiplyVector3( tempPosition );
			objectZ = tempPosition.z;
			camera.projectionMatrix.multiplyVector3( tempPosition );
3579 3580


3581
			// setup arrays for gl programs
3582

3583 3584 3585
			screenPosition[ 0 ] = tempPosition.x;
			screenPosition[ 1 ] = tempPosition.y;
			screenPosition[ 2 ] = tempPosition.z;
3586

3587 3588
			screenPositionPixels[ 0 ] = screenPosition[ 0 ] * halfViewportWidth + halfViewportWidth;
			screenPositionPixels[ 1 ] = screenPosition[ 1 ] * halfViewportHeight + halfViewportHeight;
3589

3590

M
Mikael Emtinger 已提交
3591
			// screen cull 
3592 3593

			if ( _lensFlare.hasVertexTexture || ( screenPositionPixels[ 0 ] > 0 &&
3594 3595
				screenPositionPixels[ 0 ] < _viewportWidth &&
				screenPositionPixels[ 1 ] > 0 &&
3596
				screenPositionPixels[ 1 ] < _viewportHeight )) {
3597 3598


3599
				// save current RGB to temp texture
3600

3601
				_gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.tempTexture );
3602
				_gl.copyTexImage2D( _gl.TEXTURE_2D, 0, _gl.RGB, screenPositionPixels[ 0 ] - 8, screenPositionPixels[ 1 ] - 8, 16, 16, 0 );
M
Mikael Emtinger 已提交
3603

3604

3605
				// render pink quad
3606

3607 3608 3609
				_gl.uniform1i( uniforms.renderType, 0 );
				_gl.uniform2fv( uniforms.scale, scale );
				_gl.uniform3fv( uniforms.screenPosition, screenPosition );
3610

3611 3612
				_gl.disable( _gl.BLEND );
				_gl.enable( _gl.DEPTH_TEST );
3613

3614
				_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
3615 3616


3617
				// copy result to occlusionMap
3618

3619
				_gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.occlusionTexture );
3620
				_gl.copyTexImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, screenPositionPixels[ 0 ] - 8, screenPositionPixels[ 1 ] - 8, 16, 16, 0 );
3621 3622


3623
				// restore graphics
3624

3625 3626 3627 3628
				_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 );
3629 3630


3631
				// update object positions
3632

3633 3634 3635
				object.positionScreen.x = screenPosition[ 0 ];
				object.positionScreen.y = screenPosition[ 1 ];
				object.positionScreen.z = screenPosition[ 2 ];
3636

3637
				if ( object.customUpdateCallback ) {
3638

3639
					object.customUpdateCallback( object );
3640

3641
				} else {
3642

3643
					object.updateLensFlares();
3644

3645
				}
3646 3647


3648
				// render flares
3649

3650 3651
				_gl.uniform1i( uniforms.renderType, 2 );
				_gl.enable( _gl.BLEND );
3652

3653
				for ( f = 0, fl = object.lensFlares.length; f < fl; f ++ ) {
3654

3655
					flare = object.lensFlares[ f ];
3656

3657
					if ( flare.opacity > 0.001 && flare.scale > 0.001 ) {
3658

3659 3660 3661
						screenPosition[ 0 ] = flare.x;
						screenPosition[ 1 ] = flare.y;
						screenPosition[ 2 ] = flare.z;
3662

3663 3664 3665
						size = flare.size * flare.scale / _viewportHeight;
						scale[ 0 ] = size * invAspect;
						scale[ 1 ] = size;
3666

3667 3668 3669 3670
						_gl.uniform3fv( uniforms.screenPosition, screenPosition );
						_gl.uniform2fv( uniforms.scale, scale );
						_gl.uniform1f( uniforms.rotation, flare.rotation );
						_gl.uniform1f( uniforms.opacity, flare.opacity );
3671

3672 3673
						setBlending( flare.blending );
						setTexture( flare.texture, 1 );
3674

3675
						_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
3676

3677
					}
3678

3679
				}
3680

3681
			}
M
Mr.doob 已提交
3682

3683 3684 3685
		}

		// restore gl
3686

3687 3688
		_gl.enable( _gl.CULL_FACE );
		_gl.enable( _gl.DEPTH_TEST );
3689
		_gl.depthMask( _currentDepthMask );
3690

3691
	};
3692 3693


3694
	function setupMatrices( object, camera ) {
3695

3696 3697
		object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
		THREE.Matrix4.makeInvert3x3( object._modelViewMatrix ).transposeIntoArray( object._normalMatrixArray );
3698

3699
	};
3700

A
alteredq 已提交
3701
	this.initWebGLObjects = function ( scene ) {
3702

3703
		if ( !scene.__webglObjects ) {
3704

3705 3706
			scene.__webglObjects = [];
			scene.__webglObjectsImmediate = [];
M
Mikael Emtinger 已提交
3707
			scene.__webglShadowVolumes = [];
M
Mikael Emtinger 已提交
3708
			scene.__webglLensFlares = [];
M
Mikael Emtinger 已提交
3709
			scene.__webglSprites = [];
3710 3711
		}

M
Mr.doob 已提交
3712
		while ( scene.__objectsAdded.length ) {
3713

M
Mr.doob 已提交
3714 3715
			addObject( scene.__objectsAdded[ 0 ], scene );
			scene.__objectsAdded.splice( 0, 1 );
3716 3717 3718

		}

M
Mr.doob 已提交
3719
		while ( scene.__objectsRemoved.length ) {
3720

M
Mr.doob 已提交
3721 3722
			removeObject( scene.__objectsRemoved[ 0 ], scene );
			scene.__objectsRemoved.splice( 0, 1 );
3723 3724

		}
3725

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

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

M
Mr.doob 已提交
3730
			updateObject( scene.__webglObjects[ o ].object, scene );
A
alteredq 已提交
3731 3732

		}
3733

M
Mikael Emtinger 已提交
3734 3735 3736 3737 3738
		for ( var o = 0, ol = scene.__webglShadowVolumes.length; o < ol; o ++ ) {

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

		}
3739

M
Mikael Emtinger 已提交
3740 3741 3742 3743 3744
		for ( var o = 0, ol = scene.__webglLensFlares.length; o < ol; o ++ ) {

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

		}
A
alteredq 已提交
3745

3746 3747
		/*
		for ( var o = 0, ol = scene.__webglSprites.length; o < ol; o ++ ) {
M
Mikael Emtinger 已提交
3748 3749 3750

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

3751 3752
		}
		*/
M
Mikael Emtinger 已提交
3753

3754
	};
3755

3756
	function addObject( object, scene ) {
3757

3758
		var g, geometry, geometryGroup;
M
Mr.doob 已提交
3759

3760
		if ( object._modelViewMatrix == undefined ) {
3761

3762
			object._modelViewMatrix = new THREE.Matrix4();
3763

3764 3765 3766
			object._normalMatrixArray = new Float32Array( 9 );
			object._modelViewMatrixArray = new Float32Array( 16 );
			object._objectMatrixArray = new Float32Array( 16 );
3767

3768
			object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
3769

3770
		}
A
alteredq 已提交
3771

3772
		if ( object instanceof THREE.Mesh ) {
A
alteredq 已提交
3773

3774 3775 3776 3777 3778 3779 3780 3781
			geometry = object.geometry;

			if ( geometry.geometryGroups == undefined ) {

				sortFacesByMaterial( geometry );

			}

3782
			// create separate VBOs per geometry chunk
A
alteredq 已提交
3783

3784
			for ( g in geometry.geometryGroups ) {
A
alteredq 已提交
3785

3786
				geometryGroup = geometry.geometryGroups[ g ];
M
Mr.doob 已提交
3787

3788
				// initialise VBO on the first access
M
Mr.doob 已提交
3789

3790
				if ( ! geometryGroup.__webglVertexBuffer ) {
M
Mr.doob 已提交
3791

3792 3793
					createMeshBuffers( geometryGroup );
					initMeshBuffers( geometryGroup, object );
A
alteredq 已提交
3794

3795
					geometry.__dirtyVertices = true;
3796
					geometry.__dirtyMorphTargets = true;
3797 3798 3799 3800 3801
					geometry.__dirtyElements = true;
					geometry.__dirtyUvs = true;
					geometry.__dirtyNormals = true;
					geometry.__dirtyTangents = true;
					geometry.__dirtyColors = true;
M
Mr.doob 已提交
3802

3803
				}
3804

3805
				// create separate wrapper per each use of VBO
3806

3807 3808
				if ( object instanceof THREE.ShadowVolume ) {

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

M
Mikael Emtinger 已提交
3811
				} else {
3812

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

M
Mikael Emtinger 已提交
3815
				}
3816

3817
			}
M
Mr.doob 已提交
3818

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

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

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

3825 3826
			geometry = object.geometry;

3827
			if( ! geometry.__webglVertexBuffer ) {
A
alteredq 已提交
3828 3829 3830 3831 3832 3833 3834 3835 3836

				createRibbonBuffers( geometry );
				initRibbonBuffers( geometry );

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

			}

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

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

3841 3842
			geometry = object.geometry;

3843
			if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
3844

3845 3846
				createLineBuffers( geometry );
				initLineBuffers( geometry );
M
Mr.doob 已提交
3847

3848 3849
				geometry.__dirtyVertices = true;
				geometry.__dirtyColors = true;
M
Mr.doob 已提交
3850

3851
			}
M
Mr.doob 已提交
3852

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

A
alteredq 已提交
3855 3856 3857 3858
		} else if ( object instanceof THREE.ParticleSystem ) {

			geometry = object.geometry;

3859
			if ( ! geometry.__webglVertexBuffer ) {
A
alteredq 已提交
3860 3861 3862 3863 3864 3865

				createParticleBuffers( geometry );
				initParticleBuffers( geometry );

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

3867
			}
3868

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

A
alteredq 已提交
3871 3872 3873 3874
		} else if ( THREE.MarchingCubes !== undefined && object instanceof THREE.MarchingCubes ) {

			addBufferImmediate( scene.__webglObjectsImmediate, object );

3875
		} else if ( object instanceof THREE.Sprite ) {
3876

3877 3878
			scene.__webglSprites.push( object );
		}
3879

3880
		/*else if ( object instanceof THREE.Particle ) {
A
alteredq 已提交
3881 3882 3883 3884 3885

		}*/

	};

3886
	function updateObject( object, scene ) {
A
alteredq 已提交
3887

3888
		var g, geometry, geometryGroup, a, customAttributeDirty;
A
alteredq 已提交
3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899

		if ( object instanceof THREE.Mesh ) {

			geometry = object.geometry;

			// check all geometry groups

			for ( g in geometry.geometryGroups ) {

				geometryGroup = geometry.geometryGroups[ g ];

3900 3901
				customAttributeDirty = false;

M
Mr.doob 已提交
3902 3903 3904 3905
				for ( a in geometryGroup.__webglCustomAttributes ) {

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

3906 3907 3908
						customAttributeDirty = true;
						break;
					}
M
Mr.doob 已提交
3909

3910 3911
				}

3912
				if ( geometry.__dirtyVertices || geometry.__dirtyMorphTargets || geometry.__dirtyElements ||
A
alteredq 已提交
3913
					geometry.__dirtyUvs || geometry.__dirtyNormals ||
3914
					geometry.__dirtyColors || geometry.__dirtyTangents || customAttributeDirty ) {
A
alteredq 已提交
3915 3916 3917 3918 3919 3920 3921

					setMeshBuffers( geometryGroup, object, _gl.DYNAMIC_DRAW );

				}

			}

3922
			geometry.__dirtyVertices = false;
3923
			geometry.__dirtyMorphTargets = false;
A
alteredq 已提交
3924 3925 3926 3927
			geometry.__dirtyElements = false;
			geometry.__dirtyUvs = false;
			geometry.__dirtyNormals = false;
			geometry.__dirtyTangents = false;
3928
			geometry.__dirtyColors = false;
M
Mr.doob 已提交
3929

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

3932 3933
			geometry = object.geometry;

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

A
alteredq 已提交
3936
				setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
3937

A
alteredq 已提交
3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949
			}

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

3951
			}
3952

A
alteredq 已提交
3953 3954 3955 3956 3957 3958 3959
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;

		} else if ( object instanceof THREE.ParticleSystem ) {

			geometry = object.geometry;

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

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

3964
			}
M
Mr.doob 已提交
3965

3966 3967
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
M
Mr.doob 已提交
3968

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

A
alteredq 已提交
3971
			// it updates itself in render callback
3972 3973

		} else if ( object instanceof THREE.Particle ) {
3974 3975

		}*/
3976

3977
	};
3978

3979
	function removeObject( object, scene ) {
M
Mr.doob 已提交
3980 3981 3982

		var o, ol, zobject;

3983 3984 3985 3986 3987 3988 3989 3990 3991 3992
		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 已提交
3993

3994 3995 3996 3997 3998 3999 4000
				}

			}

		} else if ( object instanceof THREE.Sprite ) {

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

4002
				zobject = scene.__webglSprites[ o ];
M
Mr.doob 已提交
4003

4004 4005 4006 4007 4008 4009
				if ( object == zobject ) {

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

				}
M
Mr.doob 已提交
4010 4011 4012 4013

			}

		}
4014 4015

		// add shadows, etc
M
Mr.doob 已提交
4016 4017 4018

	};

4019
	function sortFacesByMaterial( geometry ) {
4020 4021 4022 4023 4024 4025 4026

		// 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 = {};
4027
		var numMorphTargets = geometry.morphTargets !== undefined ? geometry.morphTargets.length : 0;
4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069

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

4070
				geometry.geometryGroups[ ghash ] = { 'faces': [], 'materials': materials, 'vertices': 0, 'numMorphTargets': numMorphTargets };
4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082

			}

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

4083
					geometry.geometryGroups[ ghash ] = { 'faces': [], 'materials': materials, 'vertices': 0, 'numMorphTargets': numMorphTargets };
4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095

				}

			}

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

		}

	};

4096
	function addBuffer( objlist, buffer, object ) {
4097

4098 4099 4100 4101 4102
		objlist.push( {
			buffer: buffer, object: object,
			opaque: { list: [], count: 0 },
			transparent: { list: [], count: 0 }
		} );
M
Mr.doob 已提交
4103

4104
	};
4105

4106
	function addBufferImmediate( objlist, object ) {
4107

4108 4109 4110 4111 4112
		objlist.push( {
			object: object,
			opaque: { list: [], count: 0 },
			transparent: { list: [], count: 0 }
		} );
4113

4114
	};
4115

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

4118
		if ( cullFace ) {
M
Mr.doob 已提交
4119

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

4122
				_gl.frontFace( _gl.CCW );
M
Mr.doob 已提交
4123

4124
			} else {
M
Mr.doob 已提交
4125

4126
				_gl.frontFace( _gl.CW );
M
Mr.doob 已提交
4127

4128
			}
M
Mr.doob 已提交
4129

4130
			if( cullFace == "back" ) {
M
Mr.doob 已提交
4131

4132
				_gl.cullFace( _gl.BACK );
M
Mr.doob 已提交
4133

4134
			} else if( cullFace == "front" ) {
M
Mr.doob 已提交
4135

4136
				_gl.cullFace( _gl.FRONT );
M
Mr.doob 已提交
4137

4138
			} else {
M
Mr.doob 已提交
4139

4140
				_gl.cullFace( _gl.FRONT_AND_BACK );
M
Mr.doob 已提交
4141

4142
			}
M
Mr.doob 已提交
4143

4144
			_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
4145

4146
		} else {
M
Mr.doob 已提交
4147

4148
			_gl.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
4149

4150 4151 4152
		}

	};
N
Nicolas Garcia Belmonte 已提交
4153

4154
	this.supportsVertexTextures = function () {
4155

4156
		return maxVertexTextures() > 0;
4157

4158
	};
4159

4160
	function maxVertexTextures() {
4161

4162 4163 4164
		return _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );

	};
4165

4166
	function initGL( antialias, clearColor, clearAlpha, stencil ) {
N
Nicolas Garcia Belmonte 已提交
4167 4168 4169

		try {

M
Mikael Emtinger 已提交
4170
			if ( ! ( _gl = _canvas.getContext( 'experimental-webgl', { antialias: antialias, stencil: stencil } ) ) ) {
N
Nicolas Garcia Belmonte 已提交
4171

4172
				throw 'Error creating WebGL context.';
N
Nicolas Garcia Belmonte 已提交
4173

4174 4175 4176
			}

		} catch ( e ) {
N
Nicolas Garcia Belmonte 已提交
4177

4178
			console.error( e );
N
Nicolas Garcia Belmonte 已提交
4179 4180 4181

		}

4182 4183 4184 4185 4186 4187 4188 4189
		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 已提交
4190 4191 4192 4193 4194 4195
		_gl.clearColor( 0, 0, 0, 1 );
		_gl.clearDepth( 1 );

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

4196 4197
		_gl.frontFace( _gl.CCW );
		_gl.cullFace( _gl.BACK );
4198
		_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
4199

N
Nicolas Garcia Belmonte 已提交
4200
		_gl.enable( _gl.BLEND );
4201 4202 4203
		_gl.blendEquation( _gl.FUNC_ADD );
		_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA );

4204
		_gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearAlpha );
4205

4206 4207
		// _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, true );

A
alteredq 已提交
4208
		_cullEnabled = true;
N
Nicolas Garcia Belmonte 已提交
4209

4210
	};
M
Mr.doob 已提交
4211

4212
	function buildProgram( shaderID, fragmentShader, vertexShader, uniforms, attributes, parameters ) {
4213

4214
		var p, pl, program, code;
4215
		var chunks = [];
4216 4217 4218

		// Generate code

4219 4220 4221 4222 4223 4224 4225 4226 4227 4228
		if ( shaderID ) {

			chunks.push( shaderID );

		} else {

			chunks.push( fragmentShader );
			chunks.push( vertexShader );

		}
4229 4230 4231

		for ( p in parameters ) {

4232 4233
			chunks.push( p );
			chunks.push( parameters[ p ] );
4234 4235 4236

		}

4237 4238
		code = chunks.join();

4239 4240 4241 4242 4243 4244 4245
		// 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*/ );
4246

4247 4248 4249 4250 4251
				return _programs[ p ].program;

			}

		}
4252

4253
		//console.log( "building new program " );
4254 4255 4256 4257

		//

		program = _gl.createProgram(),
M
Mr.doob 已提交
4258

M
Mr.doob 已提交
4259 4260 4261 4262
		prefix_fragment = [
			"#ifdef GL_ES",
			"precision highp float;",
			"#endif",
M
Mr.doob 已提交
4263

4264 4265
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
A
alteredq 已提交
4266

4267 4268
			parameters.fog ? "#define USE_FOG" : "",
			parameters.fog instanceof THREE.FogExp2 ? "#define FOG_EXP2" : "",
4269

4270
			parameters.map ? "#define USE_MAP" : "",
4271 4272 4273
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
4274

4275
			"uniform mat4 viewMatrix;",
4276
			"uniform vec3 cameraPosition;",
M
Mr.doob 已提交
4277 4278
			""
		].join("\n"),
4279

M
Mr.doob 已提交
4280
		prefix_vertex = [
4281
			maxVertexTextures() > 0 ? "#define VERTEX_TEXTURES" : "",
4282

4283 4284 4285
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

4286 4287
			"#define MAX_BONES " + parameters.maxBones,

4288
			parameters.map ? "#define USE_MAP" : "",
4289 4290 4291
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
4292
			parameters.skinning ? "#define USE_SKINNING" : "",
4293
			parameters.morphTargets ? "#define USE_MORPHTARGETS" : "",
4294

4295

4296 4297
			parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",

M
Mr.doob 已提交
4298 4299 4300
			"uniform mat4 objectMatrix;",
			"uniform mat4 modelViewMatrix;",
			"uniform mat4 projectionMatrix;",
4301 4302
			"uniform mat4 viewMatrix;",
			"uniform mat3 normalMatrix;",
M
Mr.doob 已提交
4303
			"uniform vec3 cameraPosition;",
A
alteredq 已提交
4304 4305 4306

			"uniform mat4 cameraInverseMatrix;",

M
Mr.doob 已提交
4307 4308 4309
			"attribute vec3 position;",
			"attribute vec3 normal;",
			"attribute vec2 uv;",
4310
			"attribute vec2 uv2;",
4311

4312
			"#ifdef USE_COLOR",
4313

4314
				"attribute vec3 color;",
4315

4316 4317
			"#endif",

4318
			"#ifdef USE_MORPHTARGETS",
4319

4320 4321 4322 4323 4324 4325 4326 4327
				"attribute vec3 morphTarget0;",
				"attribute vec3 morphTarget1;",
				"attribute vec3 morphTarget2;",
				"attribute vec3 morphTarget3;",
				"attribute vec3 morphTarget4;",
				"attribute vec3 morphTarget5;",
				"attribute vec3 morphTarget6;",
				"attribute vec3 morphTarget7;",
4328

4329 4330 4331
			"#endif",

			"#ifdef USE_SKINNING",
4332

4333 4334 4335 4336
				"attribute vec4 skinVertexA;",
				"attribute vec4 skinVertexB;",
				"attribute vec4 skinIndex;",
				"attribute vec4 skinWeight;",
4337

4338
			"#endif",
4339

M
Mr.doob 已提交
4340 4341
			""
		].join("\n");
4342

4343 4344
		_gl.attachShader( program, getShader( "fragment", prefix_fragment + fragmentShader ) );
		_gl.attachShader( program, getShader( "vertex", prefix_vertex + vertexShader ) );
M
Mr.doob 已提交
4345

M
Mr.doob 已提交
4346
		_gl.linkProgram( program );
N
Nicolas Garcia Belmonte 已提交
4347

M
Mr.doob 已提交
4348
		if ( !_gl.getProgramParameter( program, _gl.LINK_STATUS ) ) {
N
Nicolas Garcia Belmonte 已提交
4349

4350
			console.error( "Could not initialise shader\n" + "VALIDATE_STATUS: " + _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) + ", gl error [" + _gl.getError() + "]" );
M
Mr.doob 已提交
4351

N
Nicolas Garcia Belmonte 已提交
4352
		}
4353

4354 4355
		//console.log( prefix_fragment + fragmentShader );
		//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
4356

M
Mr.doob 已提交
4357
		program.uniforms = {};
4358
		program.attributes = {};
M
Mr.doob 已提交
4359

4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377
		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 );
4378

4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401
		// 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 );

4402 4403
		_programs.push( { program: program, code: code } );

M
Mr.doob 已提交
4404
		return program;
M
Mr.doob 已提交
4405

M
Mr.doob 已提交
4406
	};
M
Mr.doob 已提交
4407

4408
	function loadUniformsSkinning( uniforms, object ) {
4409

M
Mr.doob 已提交
4410
		_gl.uniformMatrix4fv( uniforms.cameraInverseMatrix, false, _viewMatrixArray );
A
alteredq 已提交
4411
		_gl.uniformMatrix4fv( uniforms.boneGlobalMatrices, false, object.boneMatrices );
4412

4413
	};
4414

4415

4416
	function loadUniformsMatrices( uniforms, object ) {
4417

A
alteredq 已提交
4418 4419 4420 4421
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray );
		_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrixArray );

	};
4422

4423
	function loadUniformsGeneric( program, uniforms ) {
M
Mr.doob 已提交
4424

4425
		var u, uniform, value, type, location, texture;
M
Mr.doob 已提交
4426

M
Mr.doob 已提交
4427
		for( u in uniforms ) {
M
Mr.doob 已提交
4428

4429 4430
			location = program.uniforms[u];
			if ( !location ) continue;
M
Mr.doob 已提交
4431

4432
			uniform = uniforms[u];
M
Mr.doob 已提交
4433

4434 4435
			type = uniform.type;
			value = uniform.value;
M
Mr.doob 已提交
4436

M
Mr.doob 已提交
4437
			if( type == "i" ) {
M
Mr.doob 已提交
4438

M
Mr.doob 已提交
4439
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
4440

M
Mr.doob 已提交
4441
			} else if( type == "f" ) {
M
Mr.doob 已提交
4442

M
Mr.doob 已提交
4443
				_gl.uniform1f( location, value );
4444

A
alteredq 已提交
4445 4446 4447
			} else if( type == "fv1" ) {

				_gl.uniform1fv( location, value );
M
Mr.doob 已提交
4448

4449 4450 4451 4452
			} else if( type == "fv" ) {

				_gl.uniform3fv( location, value );

4453 4454 4455 4456
			} else if( type == "v2" ) {

				_gl.uniform2f( location, value.x, value.y );

4457 4458 4459
			} else if( type == "v3" ) {

				_gl.uniform3f( location, value.x, value.y, value.z );
4460

4461 4462 4463 4464
			} else if( type == "v4" ) {

				_gl.uniform4f( location, value.x, value.y, value.z, value.w );

4465 4466 4467
			} else if( type == "c" ) {

				_gl.uniform3f( location, value.r, value.g, value.b );
M
Mr.doob 已提交
4468

M
Mr.doob 已提交
4469
			} else if( type == "t" ) {
M
Mr.doob 已提交
4470

M
Mr.doob 已提交
4471
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
4472

4473
				texture = uniform.texture;
M
Mr.doob 已提交
4474

4475
				if ( !texture ) continue;
M
Mr.doob 已提交
4476

4477
				if ( texture.image instanceof Array && texture.image.length == 6 ) {
M
Mr.doob 已提交
4478

4479
					setCubeTexture( texture, value );
M
Mr.doob 已提交
4480

4481
				} else {
M
Mr.doob 已提交
4482

4483
					setTexture( texture, value );
M
Mr.doob 已提交
4484

4485
				}
M
Mr.doob 已提交
4486

4487
			}
M
Mr.doob 已提交
4488

4489
		}
M
Mr.doob 已提交
4490

4491
	};
M
Mr.doob 已提交
4492

4493
	function setBlending( blending ) {
A
alteredq 已提交
4494 4495

		if ( blending != _oldBlending ) {
4496

A
alteredq 已提交
4497 4498 4499 4500 4501
			switch ( blending ) {

				case THREE.AdditiveBlending:

					_gl.blendEquation( _gl.FUNC_ADD );
4502
					_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE );
A
alteredq 已提交
4503 4504 4505 4506 4507

					break;

				case THREE.SubtractiveBlending:

4508 4509 4510 4511
					// TODO: Find blendFuncSeparate() combination

					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.ZERO, _gl.ONE_MINUS_SRC_COLOR );
A
alteredq 已提交
4512 4513 4514

					break;

4515 4516 4517
				case THREE.MultiplyBlending:

					// TODO: Find blendFuncSeparate() combination
A
alteredq 已提交
4518 4519

					_gl.blendEquation( _gl.FUNC_ADD );
4520
					_gl.blendFunc( _gl.ZERO, _gl.SRC_COLOR );
A
alteredq 已提交
4521 4522 4523 4524 4525

					break;

				default:

4526 4527
					_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 已提交
4528 4529

					break;
4530

A
alteredq 已提交
4531
			}
4532

A
alteredq 已提交
4533
			_oldBlending = blending;
4534

A
alteredq 已提交
4535 4536 4537
		}

	};
4538

4539
	function setTextureParameters( textureType, texture, image ) {
4540

4541
		if ( isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ) ) {
M
Mr.doob 已提交
4542

4543 4544
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
M
Mr.doob 已提交
4545

4546 4547
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
M
Mr.doob 已提交
4548

4549
			_gl.generateMipmap( textureType );
M
Mr.doob 已提交
4550

4551
		} else {
M
Mr.doob 已提交
4552

4553 4554
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
4555

4556 4557
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
M
Mr.doob 已提交
4558

4559
		}
M
Mr.doob 已提交
4560

4561
	};
4562

4563
	function setTexture( texture, slot ) {
4564

4565
		if ( texture.needsUpdate ) {
A
alteredq 已提交
4566

4567
			if ( !texture.__webglInit ) {
M
Mr.doob 已提交
4568

4569
				texture.__webglTexture = _gl.createTexture();
A
alteredq 已提交
4570

4571
				_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
4572
				_gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image );
M
Mr.doob 已提交
4573

4574
				texture.__webglInit = true;
M
Mr.doob 已提交
4575

A
alteredq 已提交
4576
			} else {
M
Mr.doob 已提交
4577

4578
				_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
M
Mr.doob 已提交
4579
				// _gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image );
A
alteredq 已提交
4580
				_gl.texSubImage2D( _gl.TEXTURE_2D, 0, 0, 0, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image );
M
Mr.doob 已提交
4581 4582 4583

			}

4584 4585
			setTextureParameters( _gl.TEXTURE_2D, texture, texture.image );
			_gl.bindTexture( _gl.TEXTURE_2D, null );
4586

A
alteredq 已提交
4587
			texture.needsUpdate = false;
4588 4589 4590 4591

		}

		_gl.activeTexture( _gl.TEXTURE0 + slot );
4592
		_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
M
Mr.doob 已提交
4593

4594
	};
M
Mr.doob 已提交
4595

4596
	function setCubeTexture( texture, slot ) {
4597 4598 4599 4600 4601

		if ( texture.image.length == 6 ) {

			if ( texture.needsUpdate ) {

4602 4603 4604
				if ( !texture.__webglInit ) {

					texture.image.__webglTextureCube = _gl.createTexture();
4605

4606
					_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
4607

4608
					for ( var i = 0; i < 6; ++i ) {
4609

4610
						_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image[ i ] );
4611

4612
					}
4613 4614

					texture.__webglInit = true;
4615 4616 4617

				} else {

4618
					_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
4619

4620
					for ( var i = 0; i < 6; ++i ) {
4621

M
Mr.doob 已提交
4622
						// _gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image[ i ] );
4623
						_gl.texSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image[ i ] );
4624

4625
					}
4626 4627 4628

				}

4629
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, texture.image[0] );
4630 4631 4632
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );

				texture.needsUpdate = false;
4633

4634 4635 4636
			}

			_gl.activeTexture( _gl.TEXTURE0 + slot );
4637
			_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
4638 4639 4640 4641 4642

		}

	};

4643
	function setRenderTarget( renderTexture ) {
4644

4645
		if ( renderTexture && !renderTexture.__webglFramebuffer ) {
M
Mr.doob 已提交
4646

M
Mikael Emtinger 已提交
4647 4648 4649
			if( renderTexture.depthBuffer === undefined ) renderTexture.depthBuffer = true;
			if( renderTexture.stencilBuffer === undefined ) renderTexture.stencilBuffer = true;

4650 4651 4652
			renderTexture.__webglFramebuffer = _gl.createFramebuffer();
			renderTexture.__webglRenderbuffer = _gl.createRenderbuffer();
			renderTexture.__webglTexture = _gl.createTexture();
4653 4654 4655


			// Setup texture
M
Mr.doob 已提交
4656

4657
			_gl.bindTexture( _gl.TEXTURE_2D, renderTexture.__webglTexture );
4658 4659 4660 4661
			_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 ) );
4662
			_gl.texImage2D( _gl.TEXTURE_2D, 0, paramThreeToGL( renderTexture.format ), renderTexture.width, renderTexture.height, 0, paramThreeToGL( renderTexture.format ), paramThreeToGL( renderTexture.type ), null );
4663

M
Mikael Emtinger 已提交
4664
			// Setup render and frame buffer
M
Mr.doob 已提交
4665

M
Mikael Emtinger 已提交
4666
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderTexture.__webglRenderbuffer );
4667
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTexture.__webglFramebuffer );
M
Mikael Emtinger 已提交
4668

4669
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, renderTexture.__webglTexture, 0 );
4670 4671 4672

			if ( renderTexture.depthBuffer && !renderTexture.stencilBuffer ) {

M
Mikael Emtinger 已提交
4673 4674
				_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTexture.width, renderTexture.height );
				_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderTexture.__webglRenderbuffer );
4675 4676

			/* For some reason this is not working. Defaulting to RGBA4.	
M
Mikael Emtinger 已提交
4677
			} else if( !renderTexture.depthBuffer && renderTexture.stencilBuffer ) {
4678

M
Mikael Emtinger 已提交
4679 4680 4681 4682
				_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 ) {
4683

M
Mikael Emtinger 已提交
4684 4685
				_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTexture.width, renderTexture.height );
				_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderTexture.__webglRenderbuffer );
4686

M
Mikael Emtinger 已提交
4687
			} else {
4688

M
Mikael Emtinger 已提交
4689
				_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTexture.width, renderTexture.height );
4690

M
Mikael Emtinger 已提交
4691
			}
4692

4693 4694

			// Release everything
M
Mr.doob 已提交
4695

4696 4697 4698
			_gl.bindTexture( _gl.TEXTURE_2D, null );
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
M
Mr.doob 已提交
4699

4700 4701
		}

4702
		var framebuffer, width, height;
M
Mr.doob 已提交
4703

4704
		if ( renderTexture ) {
M
Mr.doob 已提交
4705

4706
			framebuffer = renderTexture.__webglFramebuffer;
4707 4708
			width = renderTexture.width;
			height = renderTexture.height;
M
Mr.doob 已提交
4709

4710
		} else {
M
Mr.doob 已提交
4711

4712
			framebuffer = null;
4713 4714
			width = _viewportWidth;
			height = _viewportHeight;
M
Mr.doob 已提交
4715

4716
		}
M
Mr.doob 已提交
4717

4718
		if ( framebuffer != _currentFramebuffer ) {
M
Mr.doob 已提交
4719

4720
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
4721
			_gl.viewport( _viewportX, _viewportY, width, height );
M
Mr.doob 已提交
4722

4723
			_currentFramebuffer = framebuffer;
M
Mr.doob 已提交
4724

4725
		}
4726

4727
	};
M
Mr.doob 已提交
4728

4729
	function updateRenderTargetMipmap( renderTarget ) {
M
Mr.doob 已提交
4730

4731
		_gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
4732 4733
		_gl.generateMipmap( _gl.TEXTURE_2D );
		_gl.bindTexture( _gl.TEXTURE_2D, null );
M
Mr.doob 已提交
4734 4735

	};
4736

4737
	function cacheUniformLocations( program, identifiers ) {
M
Mr.doob 已提交
4738

M
Mr.doob 已提交
4739
		var i, l, id;
M
Mr.doob 已提交
4740

M
Mr.doob 已提交
4741
		for( i = 0, l = identifiers.length; i < l; i++ ) {
M
Mr.doob 已提交
4742

4743 4744
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
4745

M
Mr.doob 已提交
4746
		}
M
Mr.doob 已提交
4747

M
Mr.doob 已提交
4748
	};
M
Mr.doob 已提交
4749

4750
	function cacheAttributeLocations( program, identifiers ) {
4751

4752
		var i, l, id;
M
Mr.doob 已提交
4753

4754
		for( i = 0, l = identifiers.length; i < l; i++ ) {
M
Mr.doob 已提交
4755

4756 4757
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
M
Mr.doob 已提交
4758

4759
		}
M
Mr.doob 已提交
4760

M
Mr.doob 已提交
4761
	};
M
Mr.doob 已提交
4762

4763
	function getShader( type, string ) {
N
Nicolas Garcia Belmonte 已提交
4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781

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

4782
			console.error( _gl.getShaderInfoLog( shader ) );
4783
			console.error( string );
N
Nicolas Garcia Belmonte 已提交
4784 4785 4786 4787 4788
			return null;

		}

		return shader;
M
Mr.doob 已提交
4789

4790
	};
N
Nicolas Garcia Belmonte 已提交
4791

4792
	// fallback filters for non-power-of-2 textures
4793

4794
	function filterFallback( f ) {
4795

4796 4797 4798 4799 4800 4801 4802 4803
		switch ( f ) {

			case THREE.NearestFilter:
			case THREE.NearestMipMapNearestFilter:
			case THREE.NearestMipMapLinearFilter: return _gl.NEAREST; break;

			case THREE.LinearFilter:
			case THREE.LinearMipMapNearestFilter:
M
Mikael Emtinger 已提交
4804 4805
			case THREE.LinearMipMapLinearFilter: 
			default:
4806

M
Mikael Emtinger 已提交
4807
				return _gl.LINEAR; break;
4808 4809

		}
4810

4811
	};
4812 4813

	function paramThreeToGL( p ) {
M
Mr.doob 已提交
4814

4815
		switch ( p ) {
M
Mr.doob 已提交
4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828

			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;

4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842
			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;

4843
		}
M
Mr.doob 已提交
4844

4845
		return 0;
M
Mr.doob 已提交
4846

4847 4848
	};

4849
	function isPowerOfTwo( value ) {
4850 4851 4852 4853 4854

		return ( value & ( value - 1 ) ) == 0;

	};

4855
	function materialNeedsSmoothNormals( material ) {
4856 4857 4858

		return material && material.shading != undefined && material.shading == THREE.SmoothShading;

4859
	};
M
Mr.doob 已提交
4860

4861
	function bufferNeedsSmoothNormals( geometryGroup, object ) {
M
Mr.doob 已提交
4862

4863
		var m, ml, i, l, meshMaterial, needsSmoothNormals = false;
M
Mr.doob 已提交
4864

M
Mr.doob 已提交
4865
		for ( m = 0, ml = object.materials.length; m < ml; m++ ) {
4866

M
Mr.doob 已提交
4867
			meshMaterial = object.materials[ m ];
4868 4869 4870

			if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {

4871
				for ( i = 0, l = geometryGroup.materials.length; i < l; i++ ) {
4872

4873
					if ( materialNeedsSmoothNormals( geometryGroup.materials[ i ] ) ) {
4874

4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895
						needsSmoothNormals = true;
						break;

					}

				}

			} else {

				if ( materialNeedsSmoothNormals( meshMaterial ) ) {

					needsSmoothNormals = true;
					break;

				}

			}

			if ( needsSmoothNormals ) break;

		}
M
Mr.doob 已提交
4896

4897
		return needsSmoothNormals;
M
Mr.doob 已提交
4898

4899
	};
M
Mr.doob 已提交
4900

4901
	function unrollGroupMaterials( geometryGroup, object ) {
4902

4903 4904 4905
		var m, ml, i, il,
			material, meshMaterial,
			materials = [];
4906

4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917
		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 ) {
4918

4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937
						materials.push( material );

					}

				}

			} else {

				material = meshMaterial;

				if ( material ) {

					materials.push( material );

				}

			}

		}
4938

4939 4940 4941
		return materials;

	};
4942

4943
	function bufferGuessVertexColorType( materials, geometryGroup, object ) {
4944

4945
		var i, m, ml = materials.length;
4946

4947
		// use vertexColor type from the first material in unrolled materials
4948

4949
		for ( i = 0; i < ml; i++ ) {
4950

4951
			m = materials[ i ];
4952

4953
			if ( m.vertexColors ) {
4954

4955 4956 4957
				return m.vertexColors;

			}
4958

4959
		}
4960

4961
		return false;
4962

4963 4964
	};

4965
	function bufferGuessNormalType( materials, geometryGroup, object ) {
4966

4967
		var i, m, ml = materials.length;
4968

4969
		// only MeshBasicMaterial and MeshDepthMaterial don't need normals
4970

4971
		for ( i = 0; i < ml; i++ ) {
4972

4973
			m = materials[ i ];
4974

A
alteredq 已提交
4975
			if ( ( m instanceof THREE.MeshBasicMaterial && !m.envMap ) || m instanceof THREE.MeshDepthMaterial ) continue;
4976

4977
			if ( materialNeedsSmoothNormals( m ) ) {
4978

4979 4980 4981 4982 4983 4984 4985 4986 4987
				return THREE.SmoothShading;

			} else {

				return THREE.FlatShading;

			}

		}
4988

4989
		return false;
4990

4991 4992
	};

4993
	function bufferGuessUVType( materials, geometryGroup, object ) {
4994

4995
		var i, m, ml = materials.length;
4996

4997
		// material must use some texture to require uvs
4998

4999
		for ( i = 0; i < ml; i++ ) {
5000

5001
			m = materials[ i ];
5002

A
alteredq 已提交
5003
			if ( m.map || m.lightMap || m instanceof THREE.MeshShaderMaterial ) {
5004

5005
				return true;
5006

5007
			}
5008

5009
		}
5010

5011
		return false;
5012

5013
	};
5014

5015
	function allocateBones( object ) {
5016

5017 5018 5019 5020 5021 5022 5023
		// 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)
5024

5025
		var maxBones = 50;
5026

5027
		if ( object !== undefined && object instanceof THREE.SkinnedMesh ) {
5028

5029 5030 5031 5032 5033
			maxBones = object.bones.length;

		}

		return maxBones;
5034

5035
	};
5036

5037
	function allocateLights( lights, maxLights ) {
5038

5039 5040
		var l, ll, light, dirLights, pointLights, maxDirLights, maxPointLights;
		dirLights = pointLights = maxDirLights = maxPointLights = 0;
5041

5042
		for ( l = 0, ll = lights.length; l < ll; l++ ) {
5043

5044
			light = lights[ l ];
5045

5046 5047
			if ( light instanceof THREE.DirectionalLight ) dirLights++;
			if ( light instanceof THREE.PointLight ) pointLights++;
5048

5049
		}
5050

5051
		if ( ( pointLights + dirLights ) <= maxLights ) {
5052

5053 5054
			maxDirLights = dirLights;
			maxPointLights = pointLights;
5055

5056
		} else {
5057

5058 5059
			maxDirLights = Math.ceil( maxLights * dirLights / ( pointLights + dirLights ) );
			maxPointLights = maxLights - maxDirLights;
5060 5061 5062

		}

5063
		return { 'directional' : maxDirLights, 'point' : maxPointLights };
5064 5065

	};
M
Mr.doob 已提交
5066

A
alteredq 已提交
5067
	/* DEBUG
5068
	function getGLParams() {
M
Mr.doob 已提交
5069

5070
		var params  = {
M
Mr.doob 已提交
5071

5072 5073
			'MAX_VARYING_VECTORS': _gl.getParameter( _gl.MAX_VARYING_VECTORS ),
			'MAX_VERTEX_ATTRIBS': _gl.getParameter( _gl.MAX_VERTEX_ATTRIBS ),
M
Mr.doob 已提交
5074

5075 5076 5077
			'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 已提交
5078

5079 5080 5081
			'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 已提交
5082

5083 5084
		return params;
	};
M
Mr.doob 已提交
5085

5086
	function dumpObject( obj ) {
M
Mr.doob 已提交
5087

5088 5089
		var p, str = "";
		for ( p in obj ) {
M
Mr.doob 已提交
5090

5091
			str += p + ": " + obj[p] + "\n";
M
Mr.doob 已提交
5092

5093
		}
M
Mr.doob 已提交
5094

5095 5096
		return str;
	}
A
alteredq 已提交
5097
	*/
5098
};
5099