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

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

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

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

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

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

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

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

A
alteredq 已提交
30
	_this = this,
31

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

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

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

45
	// camera matrices caches
46 47

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

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

60
	_vector3 = new THREE.Vector4(),
61

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

A
alteredq 已提交
64 65
	_lights = {

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

	},

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

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

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

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

86
	}
M
Mr.doob 已提交
87

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

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

95 96
	this.context = _gl;

M
Mikael Emtinger 已提交
97

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

		
	} else {

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

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

M
Mikael Emtinger 已提交
218

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



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

		_canvas.width = width;
		_canvas.height = height;
278

279 280 281
		this.setViewport( 0, 0, _canvas.width, _canvas.height );

	};
N
Nicolas Garcia Belmonte 已提交
282

283
	this.setViewport = function ( x, y, width, height ) {
284

285 286
		_viewportX = x;
		_viewportY = y;
287

288 289
		_viewportWidth = width;
		_viewportHeight = height;
290

291
		_gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight );
292

N
Nicolas Garcia Belmonte 已提交
293
	};
294

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

297
		_gl.scissor( x, y, width, height );
298

299
	};
300

301
	this.enableScissorTest = function ( enable ) {
302

303 304 305 306
		if ( enable )
			_gl.enable( _gl.SCISSOR_TEST );
		else
			_gl.disable( _gl.SCISSOR_TEST );
307

308
	};
309

310
	this.enableDepthBufferWrite = function ( enable ) {
311

312
		_currentDepthMask = enable;
313 314 315
		_gl.depthMask( enable );

	};
316

317
	this.setClearColorHex = function ( hex, alpha ) {
318

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

322
	};
A
alteredq 已提交
323

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

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

	};
329

N
Nicolas Garcia Belmonte 已提交
330 331
	this.clear = function () {

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

	};

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

M
Mr.doob 已提交
341

A
alteredq 已提交
342
	function setupLights ( program, lights ) {
343

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

347
		zlights = _lights,
M
Mr.doob 已提交
348

349
		dcolors = zlights.directional.colors,
350
		dpositions = zlights.directional.positions,
351

352
		pcolors = zlights.point.colors,
353
		ppositions = zlights.point.positions,
354
		pdistances = zlights.point.distances,
355

356 357
		dlength = 0,
		plength = 0,
358

359 360
		doffset = 0,
		poffset = 0;
M
Mr.doob 已提交
361

362
		for ( l = 0, ll = lights.length; l < ll; l++ ) {
363

364
			light = lights[ l ];
365
			color = light.color;
366

367 368
			position = light.position;
			intensity = light.intensity;
369
			distance = light.distance;
370 371 372

			if ( light instanceof THREE.AmbientLight ) {

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

377
			} else if ( light instanceof THREE.DirectionalLight ) {
378

379
				doffset = dlength * 3;
380

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

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

389
				dlength += 1;
M
Mr.doob 已提交
390

391 392
			} else if( light instanceof THREE.PointLight ) {

393
				poffset = plength * 3;
394

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

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

403 404
				pdistances[ plength ] = distance;

405
				plength += 1;
M
Mr.doob 已提交
406

407 408 409
			}

		}
410

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

414 415
		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 已提交
416

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

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

424
	};
M
Mr.doob 已提交
425

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

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

431
	};
M
Mr.doob 已提交
432

433
	function createLineBuffers( geometry ) {
M
Mr.doob 已提交
434

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

438
	};
439

440
	function createRibbonBuffers( geometry ) {
A
alteredq 已提交
441

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

	};

447
	function createMeshBuffers( geometryGroup ) {
M
Mr.doob 已提交
448

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

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

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

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

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

473 474 475
			}

		}
M
Mr.doob 已提交
476

477
	};
478

479
	function initLineBuffers ( geometry ) {
M
Mr.doob 已提交
480

481 482 483
		var nvertices = geometry.vertices.length;

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

486
		geometry.__webglLineCount = nvertices;
M
Mr.doob 已提交
487

488
	};
M
Mr.doob 已提交
489

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

		var nvertices = geometry.vertices.length;

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

497
		geometry.__webglVertexCount = nvertices;
A
alteredq 已提交
498 499

	};
500

501
	function initParticleBuffers ( geometry ) {
502 503 504 505

		var nvertices = geometry.vertices.length;

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

508
		geometry.__sortArray = [];
509

510
		geometry.__webglParticleCount = nvertices;
511 512 513

	};

514
	function initMeshBuffers ( geometryGroup, object ) {
M
Mr.doob 已提交
515

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

		uvType,
		vertexColorType,
		normalType,
		materials,
524
		attribute,
525 526 527 528

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

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

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

535
			if ( face instanceof THREE.Face3 ) {
M
Mr.doob 已提交
536

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

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

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

547
			}
M
Mr.doob 已提交
548

549
		}
550 551 552

		materials = unrollGroupMaterials( geometryGroup, object );

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

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

559
		geometryGroup.__vertexArray = new Float32Array( nvertices * 3 );
560

561
		if ( normalType ) {
M
Mr.doob 已提交
562

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

565
		}
566

567
		if ( geometry.hasTangents ) {
568

569
			geometryGroup.__tangentArray = new Float32Array( nvertices * 4 );
570

571
		}
572

573
		if ( vertexColorType ) {
574

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

577
		}
M
Mr.doob 已提交
578

579
		if ( uvType ) {
580

581
			if ( geometry.faceUvs.length > 0 || geometry.faceVertexUvs.length > 0 ) {
582

583 584 585 586 587
				geometryGroup.__uvArray = new Float32Array( nvertices * 2 );

			}

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

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

607 608
		if ( geometryGroup.numMorphTargets ) {

609
			geometryGroup.__morphTargetsArrays = []; 
610 611 612

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

613 614
				geometryGroup.__morphTargetsArrays.push( new Float32Array( nvertices * 3 ) );

615 616 617
			}

		}
618

619
		geometryGroup.__needsSmoothNormals = ( normalType == THREE.SmoothShading );
620

621 622 623 624
		geometryGroup.__uvType = uvType;
		geometryGroup.__vertexColorType = vertexColorType;
		geometryGroup.__normalType = normalType;

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

M
Mr.doob 已提交
628

629
		// custom attributes
M
Mr.doob 已提交
630 631 632 633 634

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

			if ( materials[ m ].attributes ) {

635 636
				geometryGroup.__webglCustomAttributes = {};

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

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

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

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

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

					geometryGroup.__webglCustomAttributes[ a ] = attribute;

				}

			}
M
Mr.doob 已提交
658

659
		}
660

661
	};
M
Mr.doob 已提交
662

663

664
	function setMeshBuffers ( geometryGroup, object, hint ) {
665

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

682
		vertexIndex = 0,
683

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

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

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

709 710
		morphTargetsArrays = geometryGroup.__morphTargetsArrays,

711 712
		customAttributes = geometryGroup.__webglCustomAttributes,
		customAttribute,
713

714 715
		faceArray = geometryGroup.__faceArray,
		lineArray = geometryGroup.__lineArray,
M
Mr.doob 已提交
716

717
		needsSmoothNormals = geometryGroup.__needsSmoothNormals,
718

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

723
		geometry = object.geometry, // this is shared for all chunks
724

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

733
		vertices = geometry.vertices,
734
		chunk_faces = geometryGroup.faces,
735
		obj_faces = geometry.faces,
736

737 738
		obj_uvs  = geometry.faceVertexUvs[ 0 ],
		obj_uvs2 = geometry.faceVertexUvs[ 1 ],
739

A
alteredq 已提交
740
		obj_colors = geometry.colors,
741

A
alteredq 已提交
742 743 744
		obj_skinVerticesA = geometry.skinVerticesA,
		obj_skinVerticesB = geometry.skinVerticesB,
		obj_skinIndices = geometry.skinIndices,
745
		obj_skinWeights = geometry.skinWeights,
M
Mikael Emtinger 已提交
746
		obj_edgeFaces = geometry.edgeFaces,
747 748

		morphTargets = geometry.morphTargets;
749

750
		if ( customAttributes ) {
M
Mr.doob 已提交
751

752
			for ( a in customAttributes ) {
M
Mr.doob 已提交
753

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

757 758
			}

M
Mr.doob 已提交
759
		}
760 761


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

764 765
			fi = chunk_faces[ f ];
			face = obj_faces[ fi ];
766 767

			if ( obj_uvs ) {
A
alteredq 已提交
768 769 770 771

				uv = obj_uvs[ fi ];

			}
772 773 774

			if ( obj_uvs2 ) {

A
alteredq 已提交
775 776 777
				uv2 = obj_uvs2[ fi ];

			}
M
Mr.doob 已提交
778

779
			vertexNormals = face.vertexNormals;
780
			faceNormal = face.normal;
781

782 783
			vertexColors = face.vertexColors;
			faceColor = face.color;
784

785
			vertexTangents = face.vertexTangents;
786 787 788

			if ( face instanceof THREE.Face3 ) {

789
				if ( dirtyVertices ) {
M
Mr.doob 已提交
790

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

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

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

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

807
					offset += 9;
M
Mr.doob 已提交
808

809
				}
810

811
				if ( customAttributes ) {
M
Mr.doob 已提交
812

813
					for ( a in customAttributes ) {
M
Mr.doob 已提交
814

815 816
						customAttribute = customAttributes[ a ];

M
Mr.doob 已提交
817 818
						if ( customAttribute.needsUpdate ) {

819
							offset_custom = customAttribute.offset;
820
							offset_customSrc = customAttribute.offsetSrc;
M
Mr.doob 已提交
821

822
							if( customAttribute.size === 1 ) {
M
Mr.doob 已提交
823

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

848
								customAttribute.offset += 3;
M
Mr.doob 已提交
849

850
							} else {
M
Mr.doob 已提交
851

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

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

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

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

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

887
									customAttribute.offset += 6;
M
Mr.doob 已提交
888

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

891 892 893 894 895
									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;
896

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

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

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

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

921
									customAttribute.offset += 9;
M
Mr.doob 已提交
922

923
								} else {
M
Mr.doob 已提交
924 925 926 927 928

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

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

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

940
									customAttribute.offset += 12;
M
Mr.doob 已提交
941

942
								}
M
Mr.doob 已提交
943

944
							}
M
Mr.doob 已提交
945

946
						}
M
Mr.doob 已提交
947

948
					}
M
Mr.doob 已提交
949

950 951 952
				}


953
				if ( dirtyMorphTargets ) {
954 955 956

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

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

961
						vka = morphTargetsArrays[ vk ];
962

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

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

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

976
					offset_morphTarget += 9;
977

978 979
				}

A
alteredq 已提交
980 981 982
				if ( obj_skinWeights.length ) {

					// weights
983

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

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

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

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

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

A
alteredq 已提交
1068
				}
1069

1070 1071 1072
				if ( dirtyColors && vertexColorType ) {

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

1074 1075 1076 1077 1078
						c1 = vertexColors[ 0 ];
						c2 = vertexColors[ 1 ];
						c3 = vertexColors[ 2 ];

					} else {
1079

1080 1081 1082 1083 1084
						c1 = faceColor;
						c2 = faceColor;
						c3 = faceColor;

					}
1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096

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

1098 1099 1100 1101
					offset_color += 9;

				}

1102
				if ( dirtyTangents && geometry.hasTangents ) {
1103

1104 1105 1106
					t1 = vertexTangents[ 0 ];
					t2 = vertexTangents[ 1 ];
					t3 = vertexTangents[ 2 ];
1107

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

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

1118 1119 1120 1121
					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 已提交
1122

1123
					offset_tangent += 12;
M
Mr.doob 已提交
1124

1125 1126
				}

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

1129 1130 1131
					if ( vertexNormals.length == 3 && needsSmoothNormals ) {

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

1133
							vn = vertexNormals[ i ];
M
Mr.doob 已提交
1134

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

1139
							offset_normal += 3;
M
Mr.doob 已提交
1140

1141
						}
M
Mr.doob 已提交
1142

1143
					} else {
1144

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

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

1151
							offset_normal += 3;
M
Mr.doob 已提交
1152

1153
						}
M
Mr.doob 已提交
1154 1155

					}
M
Mr.doob 已提交
1156

1157 1158
				}

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

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

1163
						uvi = uv[ i ];
M
Mr.doob 已提交
1164

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

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

M
Mr.doob 已提交
1170
					}
1171 1172 1173

				}

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

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

						uv2i = uv2[ i ];

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

						offset_uv2 += 2;

					}

				}

1189
				if ( dirtyElements ) {
M
Mr.doob 已提交
1190

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

1195
					offset_face += 3;
M
Mr.doob 已提交
1196

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

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

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

1206
					offset_line += 6;
1207

1208
					vertexIndex += 3;
M
Mr.doob 已提交
1209

1210
				}
M
Mr.doob 已提交
1211

1212 1213 1214

			} else if ( face instanceof THREE.Face4 ) {

1215
				if ( dirtyVertices ) {
M
Mr.doob 已提交
1216

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

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

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

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

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

1238
					offset += 12;
M
Mr.doob 已提交
1239

1240
				}
1241

1242
				if ( customAttributes ) {
M
Mr.doob 已提交
1243

1244
					for ( a in customAttributes ) {
M
Mr.doob 已提交
1245

1246 1247
						customAttribute = customAttributes[ a ];

M
Mr.doob 已提交
1248
						if ( customAttribute.needsUpdate ) {
1249 1250

							offset_custom = customAttribute.offset;
1251
							offset_customSrc = customAttribute.offsetSrc;
M
Mr.doob 已提交
1252

1253
							if( customAttribute.size === 1 ) {
M
Mr.doob 已提交
1254

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

1281
								customAttribute.offset += 4;
M
Mr.doob 已提交
1282

1283
							} else {
M
Mr.doob 已提交
1284

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

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

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

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

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

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

1326
									customAttribute.offset += 8;
M
Mr.doob 已提交
1327

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

1330 1331 1332 1333 1334
									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;
1335

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

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

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

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

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

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

1368
									customAttribute.offset += 12;
M
Mr.doob 已提交
1369

1370
								} else {
M
Mr.doob 已提交
1371 1372 1373 1374 1375

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

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

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

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

1392
									customAttribute.offset += 16;
M
Mr.doob 已提交
1393

1394
								}
M
Mr.doob 已提交
1395

1396
							}
M
Mr.doob 已提交
1397

1398
						}
M
Mr.doob 已提交
1399

1400
					}
M
Mr.doob 已提交
1401

1402 1403 1404
				}


1405
				if ( dirtyMorphTargets ) {
1406 1407 1408

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

1409 1410 1411 1412
						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;
1413

1414
						vka = morphTargetsArrays[ vk ];
1415

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

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

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

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

1433
					offset_morphTarget += 12;
1434

1435 1436
				}

A
alteredq 已提交
1437 1438 1439
				if ( obj_skinWeights.length ) {

					// weights
1440

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

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

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

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

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

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

1547 1548
					offset_skin += 16;

A
alteredq 已提交
1549
				}
1550

1551 1552 1553
				if ( dirtyColors && vertexColorType ) {

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

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

					} else {
1561

1562 1563 1564 1565 1566 1567
						c1 = faceColor;
						c2 = faceColor;
						c3 = faceColor;
						c4 = faceColor;

					}
1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579

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

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

1585 1586
					offset_color += 12;

1587 1588
				}

1589
				if ( dirtyTangents && geometry.hasTangents ) {
1590

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

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

1601 1602 1603 1604
					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 已提交
1605

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

1611 1612 1613 1614
					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 已提交
1615

1616
					offset_tangent += 16;
M
Mr.doob 已提交
1617

1618
				}
M
Mr.doob 已提交
1619

M
Mr.doob 已提交
1620
				if ( dirtyNormals && normalType ) {
M
Mr.doob 已提交
1621

1622
					if ( vertexNormals.length == 4 && needsSmoothNormals ) {
1623

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

1626
							vn = vertexNormals[ i ];
M
Mr.doob 已提交
1627

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

1632
							offset_normal += 3;
M
Mr.doob 已提交
1633

1634
						}
M
Mr.doob 已提交
1635

1636
					} else {
1637

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

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

1644
							offset_normal += 3;
M
Mr.doob 已提交
1645

1646
						}
M
Mr.doob 已提交
1647 1648

					}
M
Mr.doob 已提交
1649

1650 1651
				}

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

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

1656
						uvi = uv[ i ];
M
Mr.doob 已提交
1657

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

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

M
Mr.doob 已提交
1663
					}
1664 1665

				}
1666

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

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

1682
				if ( dirtyElements ) {
M
Mr.doob 已提交
1683

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

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

1692
					offset_face += 6;
M
Mr.doob 已提交
1693

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

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

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

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

1706
					offset_line += 8;
M
Mr.doob 已提交
1707

1708
					vertexIndex += 4;
M
Mr.doob 已提交
1709

1710
				}
M
Mr.doob 已提交
1711

1712
			}
M
Mr.doob 已提交
1713

1714 1715
		}

1716 1717 1718 1719
		if ( obj_edgeFaces ) {

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

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

1731
		}
M
Mikael Emtinger 已提交
1732

1733
		if ( dirtyVertices ) {
M
Mr.doob 已提交
1734

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

1738
		}
M
Mr.doob 已提交
1739

1740
		if ( customAttributes ) {
M
Mr.doob 已提交
1741

1742
			for ( a in customAttributes ) {
M
Mr.doob 已提交
1743

1744 1745
				customAttribute = customAttributes[ a ];

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

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

M
Mr.doob 已提交
1751
					customAttribute.needsUpdate = false;
1752

1753 1754 1755 1756 1757 1758
				}

			}

		}

1759
		if ( dirtyMorphTargets ) {
1760 1761 1762 1763

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

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

1766 1767 1768
			}
		}

1769
		if ( dirtyColors && offset_color > 0 ) {
1770

1771
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
1772 1773 1774
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}
1775

1776
		if ( dirtyNormals ) {
M
Mr.doob 已提交
1777

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

1781 1782
		}

1783
		if ( dirtyTangents && geometry.hasTangents ) {
1784

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

1788
		}
1789

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

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

1795
		}
M
Mr.doob 已提交
1796

1797 1798
		if ( dirtyUvs && offset_uv2 > 0 ) {

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

		}

1804
		if ( dirtyElements ) {
M
Mr.doob 已提交
1805

1806
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
1807
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint );
1808

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

1812
		}
1813

1814
		if ( offset_skin > 0 ) {
1815

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

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

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

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

A
alteredq 已提交
1828
		}
1829 1830

	};
1831

1832
	function setLineBuffers ( geometry, hint ) {
M
Mr.doob 已提交
1833

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

1840 1841
		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,
1842

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

1846
		if ( dirtyVertices ) {
M
Mr.doob 已提交
1847

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

1850
				vertex = vertices[ v ].position;
M
Mr.doob 已提交
1851

1852
				offset = v * 3;
M
Mr.doob 已提交
1853

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

1858 1859
			}

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

1863
		}
M
Mr.doob 已提交
1864

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

			}

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

		}

1884
	};
M
Mr.doob 已提交
1885

1886
	function setRibbonBuffers ( geometry, hint ) {
A
alteredq 已提交
1887 1888

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

1894 1895
		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,
1896

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

		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;

			}

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

			}

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

		}

	};
1939

1940
	function setParticleBuffers ( geometry, hint, object ) {
1941

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

1946 1947
		colors = geometry.colors,
		cl = colors.length,
1948

1949 1950
		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,
1951

1952
		sortArray = geometry.__sortArray,
1953

1954 1955 1956
		dirtyVertices = geometry.__dirtyVertices,
		dirtyElements = geometry.__dirtyElements,
		dirtyColors = geometry.__dirtyColors;
1957

1958
		if ( object.sortParticles ) {
1959

1960
			_projScreenMatrix.multiplySelf( object.matrixWorld );
1961

1962 1963 1964
			for ( v = 0; v < vl; v++ ) {

				vertex = vertices[ v ].position;
1965

1966 1967
				_vector3.copy( vertex );
				_projScreenMatrix.multiplyVector3( _vector3 );
1968

1969
				sortArray[ v ] = [ _vector3.z, v ];
1970

1971
			}
1972

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

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

1977
				vertex = vertices[ sortArray[v][1] ].position;
1978

1979
				offset = v * 3;
1980

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

1985
			}
1986

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

A
alteredq 已提交
1989
				offset = c * 3;
1990

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

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

1997
			}
1998 1999


2000
		} else {
2001

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

				}
2015 2016

			}
2017

A
alteredq 已提交
2018
			if ( dirtyColors ) {
2019

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

2030
				}
2031

A
alteredq 已提交
2032
			}
2033 2034

		}
2035

A
alteredq 已提交
2036
		if ( dirtyVertices || object.sortParticles ) {
2037

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

A
alteredq 已提交
2041
		}
2042

A
alteredq 已提交
2043
		if ( dirtyColors || object.sortParticles ) {
2044

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

A
alteredq 已提交
2048
		}
2049

2050
	};
M
Mr.doob 已提交
2051

2052
	function setMaterialShaders( material, shaders ) {
2053

2054
		material.uniforms = Uniforms.clone( shaders.uniforms );
2055 2056
		material.vertexShader = shaders.vertexShader;
		material.fragmentShader = shaders.fragmentShader;
2057

M
Mr.doob 已提交
2058
	};
2059

2060
	function refreshUniformsCommon( uniforms, material ) {
M
Mr.doob 已提交
2061

2062
		uniforms.diffuse.value.setRGB( material.color.r, material.color.g, material.color.b );
A
alteredq 已提交
2063 2064
		uniforms.opacity.value = material.opacity;
		uniforms.map.texture = material.map;
2065

2066
		uniforms.lightMap.texture = material.lightMap;
2067

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

2074
	};
2075

2076
	function refreshUniformsLine( uniforms, material ) {
2077

2078
		uniforms.diffuse.value.setRGB( material.color.r, material.color.g, material.color.b );
A
alteredq 已提交
2079
		uniforms.opacity.value = material.opacity;
2080 2081

	};
M
Mr.doob 已提交
2082

2083
	function refreshUniformsParticle( uniforms, material ) {
2084

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

A
alteredq 已提交
2091
	};
2092

2093
	function refreshUniformsFog( uniforms, fog ) {
2094

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

A
alteredq 已提交
2097
		if ( fog instanceof THREE.Fog ) {
2098

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

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

A
alteredq 已提交
2104
			uniforms.fogDensity.value = fog.density;
2105 2106

		}
2107

2108 2109
	};

2110
	function refreshUniformsPhong( uniforms, material ) {
M
Mr.doob 已提交
2111

A
alteredq 已提交
2112 2113 2114 2115 2116
		//uniforms.ambient.value.setHex( material.ambient.hex );
		//uniforms.specular.value.setHex( material.specular.hex );
		uniforms.ambient.value.setRGB( material.ambient.r, material.ambient.g, material.ambient.b );
		uniforms.specular.value.setRGB( material.specular.r, material.specular.g, material.specular.b );
		uniforms.shininess.value = material.shininess;
M
Mr.doob 已提交
2117

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


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

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

A
alteredq 已提交
2131
	};
M
Mr.doob 已提交
2132

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

2135
		var u, a, identifiers, i, parameters, maxLightCount, maxBones, shaderID;
2136

A
alteredq 已提交
2137
		if ( material instanceof THREE.MeshDepthMaterial ) {
2138

2139
			shaderID = 'depth';
2140

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

2143
			shaderID = 'shadowVolumeDynamic';
M
Mikael Emtinger 已提交
2144

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

2147
			shaderID = 'normal';
2148

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

2151
			shaderID = 'basic';
2152

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

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

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

2159
			shaderID = 'phong';
M
Mr.doob 已提交
2160

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

2163
			shaderID = 'basic';
2164

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

2167 2168 2169 2170 2171 2172 2173
			shaderID = 'particle_basic';

		}

		if ( shaderID ) {

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

A
alteredq 已提交
2175
		}
2176

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

2180
		maxLightCount = allocateLights( lights, 4 );
2181

2182
		maxBones = allocateBones( object );
M
Mr.doob 已提交
2183

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

2195
		material.program = buildProgram( shaderID, material.fragmentShader, material.vertexShader, material.uniforms, material.attributes, parameters );
2196

2197
		var attributes = material.program.attributes;
2198

2199
		_gl.enableVertexAttribArray( attributes.position );
2200

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

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

2209 2210 2211 2212
			_gl.enableVertexAttribArray( attributes.skinVertexA );
			_gl.enableVertexAttribArray( attributes.skinVertexB );
			_gl.enableVertexAttribArray( attributes.skinIndex );
			_gl.enableVertexAttribArray( attributes.skinWeight );
2213

2214
		}
2215

2216
		for ( a in material.attributes ) {
2217

2218
			if( attributes[ a ] >= 0 ) _gl.enableVertexAttribArray( attributes[ a ] );
2219

2220
		}
2221 2222


2223
		if ( material.morphTargets ) {
2224

2225
			material.numSupportedMorphTargets = 0;
2226

2227

2228
			if ( attributes.morphTarget0 >= 0 ) {
2229

2230 2231
				_gl.enableVertexAttribArray( attributes.morphTarget0 );
				material.numSupportedMorphTargets ++;
2232

2233
			}
2234

2235
			if ( attributes.morphTarget1 >= 0 ) {
2236

2237 2238
				_gl.enableVertexAttribArray( attributes.morphTarget1 );
				material.numSupportedMorphTargets ++;
2239

2240
			}
2241

2242
			if ( attributes.morphTarget2 >= 0 ) {
2243

2244 2245
				_gl.enableVertexAttribArray( attributes.morphTarget2 );
				material.numSupportedMorphTargets ++;
2246

2247
			}
2248

2249
			if ( attributes.morphTarget3 >= 0 ) {
2250

2251 2252
				_gl.enableVertexAttribArray( attributes.morphTarget3 );
				material.numSupportedMorphTargets ++;
2253

2254
			}
2255

2256
			if ( attributes.morphTarget4 >= 0 ) {
2257

2258 2259
				_gl.enableVertexAttribArray( attributes.morphTarget4 );
				material.numSupportedMorphTargets ++;
2260

2261
			}
2262

2263
			if ( attributes.morphTarget5 >= 0 ) {
2264

2265 2266
				_gl.enableVertexAttribArray( attributes.morphTarget5 );
				material.numSupportedMorphTargets ++;
2267

2268
			}
2269

2270
			if ( attributes.morphTarget6 >= 0 ) {
2271

2272 2273
				_gl.enableVertexAttribArray( attributes.morphTarget6 );
				material.numSupportedMorphTargets ++;
2274

2275
			}
2276

2277
			if ( attributes.morphTarget7 >= 0 ) {
2278

2279 2280
				_gl.enableVertexAttribArray( attributes.morphTarget7 );
				material.numSupportedMorphTargets ++;
2281

2282
			}
2283

2284
			object.__webglMorphTargetInfluences = new Float32Array( this.maxMorphTargets );
2285

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

2288
				object.__webglMorphTargetInfluences[ i ] = 0;
2289 2290 2291

			}

2292
		}
M
Mr.doob 已提交
2293

2294
	};
2295

2296
	function setProgram( camera, lights, fog, material, object ) {
2297

2298
		if ( ! material.program ) {
2299 2300 2301 2302

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

		}
M
Mr.doob 已提交
2303

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

2308
		if ( program != _currentProgram ) {
M
Mr.doob 已提交
2309

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

M
Mr.doob 已提交
2313
		}
2314

2315 2316
		_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, _projectionMatrixArray );

A
alteredq 已提交
2317
		// refresh uniforms common to several materials
2318 2319

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

A
alteredq 已提交
2328
			refreshUniformsFog( m_uniforms, fog );
2329 2330

		}
M
Mr.doob 已提交
2331

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

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

		}

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

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

A
alteredq 已提交
2347
		}
M
Mr.doob 已提交
2348

A
alteredq 已提交
2349
		// refresh single material specific uniforms
2350

2351
		if ( material instanceof THREE.LineBasicMaterial ) {
M
Mr.doob 已提交
2352

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

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

A
alteredq 已提交
2357
			refreshUniformsParticle( m_uniforms, material );
2358

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

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

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

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

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

A
alteredq 已提交
2371
			m_uniforms.opacity.value = material.opacity;
2372
		}
2373

A
alteredq 已提交
2374
		// load common uniforms
2375

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

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

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

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

2388
		}
2389

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

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

A
alteredq 已提交
2396
		}
2397

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

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

A
alteredq 已提交
2405
		}
2406

2407 2408
		if ( material instanceof THREE.ShadowVolumeDynamicMaterial ) {

M
Mikael Emtinger 已提交
2409
			var dirLight = m_uniforms.directionalLightDirection.value;
2410

M
Mikael Emtinger 已提交
2411 2412 2413
			dirLight[ 0 ] = -lights.position.x;
			dirLight[ 1 ] = -lights.position.y;
			dirLight[ 2 ] = -lights.position.z;
2414

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


2421
		if ( material.skinning ) {
2422

2423
			loadUniformsSkinning( p_uniforms, object );
2424

A
alteredq 已提交
2425
		}
2426

A
alteredq 已提交
2427
		return program;
2428

A
alteredq 已提交
2429
	};
2430

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

2433 2434
		if ( material.opacity == 0 ) return;

2435
		var program, attributes, linewidth, primitives, a, attribute;
A
alteredq 已提交
2436

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

2439
		attributes = program.attributes;
M
Mr.doob 已提交
2440

2441
		// vertices
M
Mr.doob 已提交
2442

2443
		if ( !material.morphTargets ) {
2444 2445

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

2448
		} else {
2449

M
Mikael Emtinger 已提交
2450
			setupMorphTargets( material, geometryGroup, object );
2451

2452 2453
		}

2454 2455 2456 2457

		// custom attributes

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

2459
			for( a in geometryGroup.__webglCustomAttributes ) {
M
Mr.doob 已提交
2460

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

2463
					attribute = geometryGroup.__webglCustomAttributes[ a ];
M
Mr.doob 已提交
2464

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

2468
				}
M
Mr.doob 已提交
2469

2470
			}
M
Mr.doob 已提交
2471

2472 2473 2474
		}


A
alteredq 已提交
2475 2476 2477 2478
		// colors

		if ( attributes.color >= 0 ) {

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

		}

2484
		// normals
M
Mr.doob 已提交
2485

2486
		if ( attributes.normal >= 0 ) {
2487

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

2491
		}
2492

2493 2494 2495
		// tangents

		if ( attributes.tangent >= 0 ) {
2496

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

2500
		}
2501

2502
		// uvs
M
Mr.doob 已提交
2503

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

2506
			if ( geometryGroup.__webglUVBuffer ) {
2507

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

2511
				_gl.enableVertexAttribArray( attributes.uv );
2512

2513
			} else {
2514

2515
				_gl.disableVertexAttribArray( attributes.uv );
M
Mr.doob 已提交
2516

2517
			}
2518 2519 2520

		}

2521 2522
		if ( attributes.uv2 >= 0 ) {

2523
			if ( geometryGroup.__webglUV2Buffer ) {
2524

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

				_gl.enableVertexAttribArray( attributes.uv2 );

			} else {

				_gl.disableVertexAttribArray( attributes.uv2 );

			}

		}

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

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

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

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

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

A
alteredq 已提交
2554
		}
2555

2556
		// render mesh
M
Mr.doob 已提交
2557

2558
		if ( object instanceof THREE.Mesh ) {
2559

2560
			// wireframe
2561

2562
			if ( material.wireframe ) {
M
Mr.doob 已提交
2563

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

2568
			// triangles
2569

2570
			} else {
2571

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

2575
			}
2576

2577
		// render lines
2578

2579
		} else if ( object instanceof THREE.Line ) {
2580

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

2583
			_gl.lineWidth( material.linewidth );
2584
			_gl.drawArrays( primitives, 0, geometryGroup.__webglLineCount );
2585

2586
		// render particles
2587

2588
		} else if ( object instanceof THREE.ParticleSystem ) {
2589

2590
			_gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webglParticleCount );
2591

A
alteredq 已提交
2592
		// render ribbon
2593

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

2596
			_gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webglVertexCount );
2597

2598 2599 2600 2601
		}

	};

M
Mikael Emtinger 已提交
2602

M
Mikael Emtinger 已提交
2603
	function setupMorphTargets( material, geometryGroup, object ) {
2604

M
Mikael Emtinger 已提交
2605
		// set base
2606

M
Mikael Emtinger 已提交
2607
		var attributes = material.program.attributes;
2608

2609
		if (  object.morphTargetBase !== - 1 ) {
2610 2611

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

M
Mikael Emtinger 已提交
2614
		} else {
2615 2616

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

M
Mikael Emtinger 已提交
2619
		}
2620

2621
		if ( object.morphTargetForcedOrder.length ) {
M
Mikael Emtinger 已提交
2622 2623

			// set forced order
2624

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

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

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

2634 2635 2636 2637
				object.__webglMorphTargetInfluences[ m ] = influences[ order[ m ]];

				m ++;
			}
2638

M
Mikael Emtinger 已提交
2639
		} else {
2640

M
Mikael Emtinger 已提交
2641
			// find most influencing
2642

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

2650
			if ( object.morphTargetBase !== - 1 ) {
2651

M
Mikael Emtinger 已提交
2652
				used[ object.morphTargetBase ] = true;
2653

M
Mikael Emtinger 已提交
2654
			}
2655 2656 2657

			while ( m < material.numSupportedMorphTargets ) {

2658
				for ( i = 0; i < il; i ++ ) {
2659 2660 2661

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

M
Mikael Emtinger 已提交
2662 2663
						candidate = i;
						candidateInfluence = influences[ candidate ];
2664

M
Mikael Emtinger 已提交
2665 2666
					}
				}
2667 2668

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

				object.__webglMorphTargetInfluences[ m ] = candidateInfluence;

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

		// load updated influences uniform
2680

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


2685
	function renderBufferImmediate( object, program, shading ) {
2686

2687 2688
		if ( ! object.__webglVertexBuffer ) object.__webglVertexBuffer = _gl.createBuffer();
		if ( ! object.__webglNormalBuffer ) object.__webglNormalBuffer = _gl.createBuffer();
2689

A
alteredq 已提交
2690
		if ( object.hasPos ) {
2691

2692 2693 2694 2695
			_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 );
2696

A
alteredq 已提交
2697
		}
2698

A
alteredq 已提交
2699
		if ( object.hasNormal ) {
2700

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

			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;

				}

			}

2746 2747 2748
			_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 );
2749

A
alteredq 已提交
2750
		}
2751

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

A
alteredq 已提交
2754
		object.count = 0;
2755

A
alteredq 已提交
2756
	};
2757

2758
	function setObjectFaces( object ) {
2759

2760
		if ( _oldDoubleSided != object.doubleSided ) {
2761

2762
			if( object.doubleSided ) {
2763

2764
				_gl.disable( _gl.CULL_FACE );
2765

2766
			} else {
2767

A
alteredq 已提交
2768
				_gl.enable( _gl.CULL_FACE );
2769

A
alteredq 已提交
2770
			}
2771

2772
			_oldDoubleSided = object.doubleSided;
2773

2774
		}
2775

2776
		if ( _oldFlipSided != object.flipSided ) {
2777

2778 2779 2780 2781
			if( object.flipSided ) {

				_gl.frontFace( _gl.CW );

2782
			} else {
2783 2784 2785 2786

				_gl.frontFace( _gl.CCW );

			}
2787

2788
			_oldFlipSided = object.flipSided;
2789 2790

		}
2791

2792
	};
2793

2794
	function setDepthTest( test ) {
2795

A
alteredq 已提交
2796 2797 2798
		if ( _oldDepth != test ) {

			if( test ) {
2799

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

A
alteredq 已提交
2802
			} else {
2803

A
alteredq 已提交
2804
				_gl.disable( _gl.DEPTH_TEST );
2805

A
alteredq 已提交
2806
			}
2807

A
alteredq 已提交
2808 2809 2810
			_oldDepth = test;

		}
2811

A
alteredq 已提交
2812
	};
2813

2814
	function computeFrustum( m ) {
2815 2816 2817 2818 2819 2820 2821 2822 2823

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

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

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

		}

	};
2833

2834
	function isInFrustum( object ) {
2835

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

	};
2849

2850
	function addToFixedArray( where, what ) {
2851

2852 2853
		where.list[ where.count ] = what;
		where.count += 1;
2854

2855
	};
2856

2857
	function unrollImmediateBufferMaterials( globject ) {
2858

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

		transparent.count = 0;
		opaque.count = 0;
2866

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

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

2872
		}
2873

2874
	};
2875

2876
	function unrollBufferMaterials( globject ) {
2877

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

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

				}

			} else {

				material = meshMaterial;
2903
				if ( material ) material.transparent ? addToFixedArray( transparent, material ) : addToFixedArray( opaque, material );
2904

2905 2906 2907
			}

		}
2908

2909
	};
2910 2911


2912
	function painterSort( a, b ) {
2913

2914
		return b.z - a.z;
2915 2916

	};
2917

2918
	this.render = function( scene, camera, renderTarget, forceClear ) {
2919

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

M
Mr.doob 已提交
2925
		camera.matrixAutoUpdate && camera.updateMatrix();
2926

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

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

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

A
alteredq 已提交
2935
		this.initWebGLObjects( scene );
M
Mr.doob 已提交
2936

A
alteredq 已提交
2937
		setRenderTarget( renderTarget );
M
Mr.doob 已提交
2938

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

2941
			this.clear();
M
Mr.doob 已提交
2942

2943 2944
		}

2945
		// set matrices
2946

2947
		ol = scene.__webglObjects.length;
2948

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

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

2954
			if ( object.visible ) {
2955 2956

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

2958
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
2959

2960
					setupMatrices( object, camera );
2961

2962
					unrollBufferMaterials( webglObject );
2963

2964
					webglObject.render = true;
2965

2966
					if ( this.sortObjects ) {
2967

2968 2969 2970
						_vector3.copy( object.position );
						_projScreenMatrix.multiplyVector3( _vector3 );

2971
						webglObject.z = _vector3.z;
2972

2973
					}
2974

2975
				} else {
2976

2977
					webglObject.render = false;
2978

2979
				}
2980

2981
			} else {
2982

2983
				webglObject.render = false;
2984

2985
			}
2986

2987
		}
2988

2989
		if ( this.sortObjects ) {
2990

2991
			scene.__webglObjects.sort( painterSort );
2992

2993
		}
2994

2995
		oil = scene.__webglObjectsImmediate.length;
2996

2997
		for ( o = 0; o < oil; o++ ) {
2998

2999 3000
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
3001

3002
			if ( object.visible ) {
3003 3004 3005

				if( object.matrixAutoUpdate ) {

3006
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
3007

A
alteredq 已提交
3008
				}
3009

3010
				setupMatrices( object, camera );
3011

3012
				unrollImmediateBufferMaterials( webglObject );
3013

3014
			}
3015

3016
		}
A
alteredq 已提交
3017

3018 3019
		// opaque pass

3020
		setBlending( THREE.NormalBlending );
3021

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

3024
			webglObject = scene.__webglObjects[ o ];
3025

3026
			if ( webglObject.render ) {
3027

3028 3029 3030
				object = webglObject.object;
				buffer = webglObject.buffer;
				opaque = webglObject.opaque;
3031

3032
				setObjectFaces( object );
3033

3034
				for ( i = 0; i < opaque.count; i ++ ) {
3035

3036
					material = opaque.list[ i ];
3037

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

3041
				}
3042 3043 3044 3045 3046

			}

		}

A
alteredq 已提交
3047
		// opaque pass (immediate simulator)
3048

3049
		for ( o = 0; o < oil; o++ ) {
3050

3051 3052
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
3053

A
alteredq 已提交
3054
			if ( object.visible ) {
3055

3056
				opaque = webglObject.opaque;
3057

3058
				setObjectFaces( object );
3059

3060
				for( i = 0; i < opaque.count; i++ ) {
3061

3062
					material = opaque.list[ i ];
3063

3064
					setDepthTest( material.depthTest );
3065

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

3069
				}
3070

A
alteredq 已提交
3071
			}
3072

A
alteredq 已提交
3073 3074
		}

3075 3076
		// transparent pass

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

3079
			webglObject = scene.__webglObjects[ o ];
3080

3081
			if ( webglObject.render ) {
3082

3083 3084 3085
				object = webglObject.object;
				buffer = webglObject.buffer;
				transparent = webglObject.transparent;
3086

3087
				setObjectFaces( object );
3088

3089
				for ( i = 0; i < transparent.count; i ++ ) {
3090

3091
					material = transparent.list[ i ];
3092

3093
					setBlending( material.blending );
3094
					setDepthTest( material.depthTest );
3095

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

3098
				}
3099

3100
			}
M
Mr.doob 已提交
3101

M
Mr.doob 已提交
3102
		}
M
Mr.doob 已提交
3103

3104
		// transparent pass (immediate simulator)
3105

3106
		for ( o = 0; o < oil; o++ ) {
3107

3108 3109
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
3110

3111
			if ( object.visible ) {
3112

3113
				transparent = webglObject.transparent;
3114

3115
				setObjectFaces( object );
3116

3117
				for ( i = 0; i < transparent.count; i ++ ) {
3118

3119
					material = transparent.list[ i ];
3120

3121
					setBlending( material.blending );
3122
					setDepthTest( material.depthTest );
3123

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

3127
				}
3128

3129
			}
3130

3131
		}
3132

M
Mikael Emtinger 已提交
3133 3134 3135 3136
		// render 2d
		
		if ( scene.__webglSprites.length ) {
			
3137
			renderSprites( scene, camera );
M
Mikael Emtinger 已提交
3138 3139 3140
			
		}

M
Mikael Emtinger 已提交
3141
		// render stencil shadows
M
Mikael Emtinger 已提交
3142

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

			renderStencilShadows( scene );
3146

M
Mikael Emtinger 已提交
3147 3148
		}

3149

3150
		// render lens flares
3151 3152 3153

		if ( scene.__webglLensFlares.length ) {

3154
			renderLensFlares( scene, camera );
3155

3156 3157
		}

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

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

M
Mikael Emtinger 已提交
3182 3183 3184 3185 3186
		// setup stencil

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

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

3195

M
Mikael Emtinger 已提交
3196
		// loop through all directional lights
3197

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

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

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

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

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

				// render all volumes
3220 3221 3222

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

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

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

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

3234
					if ( _currentProgram !== program ) {
3235

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

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


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


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

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

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

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

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

M
Mikael Emtinger 已提交
3263
				}
M
Mikael Emtinger 已提交
3264

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

M
Mikael Emtinger 已提交
3267 3268
		}

3269

M
Mikael Emtinger 已提交
3270
		// setup color+stencil
M
Mikael Emtinger 已提交
3271

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


3279
		// draw darkening polygon
M
Mr.doob 已提交
3280

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

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

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

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

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


		// disable stencil

3301 3302 3303 3304
		_gl.disable( _gl.STENCIL_TEST );
		_gl.enable( _gl.DEPTH_TEST );
		_gl.depthMask( _currentDepthMask );

M
Mikael Emtinger 已提交
3305
	}
3306

3307

3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333
	/*
	 * 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
		
		_gl.useProgram( _sprite.program );
		_currentProgram = _sprite.program;
		_oldBlending = "";

		_gl.disable( _gl.CULL_FACE );
3334
		_gl.enable( _gl.BLEND );
3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376

		_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 );
		
		_gl.uniformMatrix4fv( uniforms.projectionMatrix, false, _projectionMatrixArray );

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

		// render all non-custom shader sprites
				
		for( o = 0, ol = scene.__webglSprites.length; o < ol; o++ ) {

			object = scene.__webglSprites[ o ];

			if( object.material === undefined ) {

				if( object.map && object.map.image && object.map.image.width ) {
	
					if( object.useScreenCoordinates ) {
						
						_gl.uniform1i( uniforms.useScreenCoordinates, 1 );
						_gl.uniform3f( uniforms.screenPosition, ( object.position.x - halfViewportWidth  ) / halfViewportWidth, 
														        ( halfViewportHeight - object.position.y ) / halfViewportHeight,
														          object.position.z );
						
					} else {

						
						object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );

						_gl.uniform1i( uniforms.useScreenCoordinates, 0 );
						_gl.uniform1i( uniforms.affectedByDistance, object.affectedByDistance ? 1 : 0 );
						_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray );
						
					}
				
					size = object.map.image.width / ( object.affectedByDistance ? 1 : _viewportHeight );
3377 3378
					scale[ 0 ] = size * invAspect * object.scale.x;
					scale[ 1 ] = size * object.scale.y;
3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389
				
					_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 );

					if( object.mergeWith3D && !mergeWith3D ) {
						
						_gl.enable( _gl.DEPTH_TEST );
3390 3391
						_gl.depthMask( true );
						
3392 3393 3394 3395 3396
						mergeWith3D = true;
						
					} else if( !object.mergeWith3D && mergeWith3D ) {
						
						_gl.disable( _gl.DEPTH_TEST );
3397 3398
						_gl.depthMask( false );

3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434
						mergeWith3D = false;
						
					}
	
					setBlending( object.blending );
					setTexture( object.map, 0 );
			
					_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
				}
				
			} else {
				
				anyCustom = true;
				
			}
			
		}


		// loop through all custom

/*		if( anyCustom ) {
			
		}
*/

		// restore gl

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

	}



3435 3436 3437 3438 3439 3440 3441 3442 3443 3444
	/*
	 * 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 ) {
3445

3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467
		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 已提交
3468
		_currentProgram = _lensFlare.program;
3469 3470 3471 3472 3473 3474
		_oldBlending = "";


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

3475 3476
		_gl.uniform1i( uniforms.occlusionMap, 0 );
		_gl.uniform1i( uniforms.map, 1 );
3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487

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

3488 3489 3490 3491
		_gl.activeTexture( _gl.TEXTURE0 );
		_gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.occlusionTexture );

		_gl.activeTexture( _gl.TEXTURE1 );
3492

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

3495
			// calc object screen position
3496

3497
			object = scene.__webglLensFlares[ o ].object;
3498

3499
			tempPosition.set( object.matrixWorld.n14, object.matrixWorld.n24, object.matrixWorld.n34 );
3500

3501 3502 3503
			camera.matrixWorldInverse.multiplyVector3( tempPosition );
			objectZ = tempPosition.z;
			camera.projectionMatrix.multiplyVector3( tempPosition );
3504 3505


3506
			// setup arrays for gl programs
3507

3508 3509 3510
			screenPosition[ 0 ] = tempPosition.x;
			screenPosition[ 1 ] = tempPosition.y;
			screenPosition[ 2 ] = tempPosition.z;
3511

3512 3513
			screenPositionPixels[ 0 ] = screenPosition[ 0 ] * halfViewportWidth + halfViewportWidth;
			screenPositionPixels[ 1 ] = screenPosition[ 1 ] * halfViewportHeight + halfViewportHeight;
3514

3515

M
Mikael Emtinger 已提交
3516
			// screen cull 
3517
			
3518 3519
			if(	_lensFlare.hasVertexTexture ||
			  ( screenPositionPixels[ 0 ] > 0 &&
3520 3521
				screenPositionPixels[ 0 ] < _viewportWidth &&
				screenPositionPixels[ 1 ] > 0 &&
3522
				screenPositionPixels[ 1 ] < _viewportHeight )) {
3523 3524


3525 3526 3527
				// save current RGB to temp texture
	
				_gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.tempTexture );
3528 3529
				//_gl.copyTexSubImage2D( _gl.TEXTURE_2D, 0, 0, 0, screenPositionPixels[ 0 ] - 8, screenPositionPixels[ 1 ] - 8, 16, 16 );
				_gl.copyTexImage2D( _gl.TEXTURE_2D, 0, _gl.RGB, screenPositionPixels[ 0 ] - 8, screenPositionPixels[ 1 ] - 8, 16, 16, 0 );
M
Mikael Emtinger 已提交
3530

3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546
	
				// render pink quad
	
				_gl.uniform1i( uniforms.renderType, 0 );
				_gl.uniform2fv( uniforms.scale, scale );
				_gl.uniform3fv( uniforms.screenPosition, screenPosition );
	
				_gl.disable( _gl.BLEND );
				_gl.enable( _gl.DEPTH_TEST );
	
				_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
	
	
				// copy result to occlusionMap
	
				_gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.occlusionTexture );
3547 3548
				//_gl.copyTexSubImage2D( _gl.TEXTURE_2D, 0, 0, 0, screenPositionPixels[ 0 ] - 8, screenPositionPixels[ 1 ] - 8, 16, 16 );
				_gl.copyTexImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, screenPositionPixels[ 0 ] - 8, screenPositionPixels[ 1 ] - 8, 16, 16, 0 );
3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572
	
	
				// restore graphics
	
				_gl.uniform1i( uniforms.renderType, 1 );
				_gl.disable( _gl.DEPTH_TEST );
				_gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.tempTexture );
				_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
	
	
				// update object positions
	
				object.positionScreen.x = screenPosition[ 0 ];
				object.positionScreen.y = screenPosition[ 1 ];
				object.positionScreen.z = screenPosition[ 2 ];
	
				if ( object.customUpdateCallback ) {
	
					object.customUpdateCallback( object );
	
				} else {
	
					object.updateLensFlares();
	
3573
				}
3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608
	
	
				// render flares
	
				_gl.uniform1i( uniforms.renderType, 2 );
				_gl.enable( _gl.BLEND );
				
				for ( f = 0, fl = object.lensFlares.length; f < fl; f ++ ) {
	
					flare = object.lensFlares[ f ];
	
					if ( flare.opacity > 0.001 && flare.scale > 0.001 ) {
	
						screenPosition[ 0 ] = flare.x;
						screenPosition[ 1 ] = flare.y;
						screenPosition[ 2 ] = flare.z;
	
						size = flare.size * flare.scale / _viewportHeight;
						scale[ 0 ] = size * invAspect;
						scale[ 1 ] = size;
	
						_gl.uniform3fv( uniforms.screenPosition, screenPosition );
						_gl.uniform2fv( uniforms.scale, scale );
						_gl.uniform1f( uniforms.rotation, flare.rotation );
						_gl.uniform1f( uniforms.opacity, flare.opacity );
	
						setBlending( flare.blending );
						setTexture( flare.texture, 1 );
	
						_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
	
					}
	
				}
			
3609
			}
M
Mr.doob 已提交
3610

3611 3612 3613
		}

		// restore gl
3614

3615 3616
		_gl.enable( _gl.CULL_FACE );
		_gl.enable( _gl.DEPTH_TEST );
3617
		_gl.depthMask( _currentDepthMask );
3618

3619
	}
3620

M
Mr.doob 已提交
3621

3622 3623


3624
	function setupMatrices( object, camera ) {
3625

3626 3627
		object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
		THREE.Matrix4.makeInvert3x3( object._modelViewMatrix ).transposeIntoArray( object._normalMatrixArray );
3628

3629
	}
3630

A
alteredq 已提交
3631
	this.initWebGLObjects = function ( scene ) {
3632

3633
		if ( !scene.__webglObjects ) {
3634

3635 3636
			scene.__webglObjects = [];
			scene.__webglObjectsImmediate = [];
M
Mikael Emtinger 已提交
3637
			scene.__webglShadowVolumes = [];
M
Mikael Emtinger 已提交
3638
			scene.__webglLensFlares = [];
M
Mikael Emtinger 已提交
3639
			scene.__webglSprites = [];
3640 3641
		}

M
Mr.doob 已提交
3642
		while ( scene.__objectsAdded.length ) {
3643

M
Mr.doob 已提交
3644 3645
			addObject( scene.__objectsAdded[ 0 ], scene );
			scene.__objectsAdded.splice( 0, 1 );
3646 3647 3648

		}

M
Mr.doob 已提交
3649
		while ( scene.__objectsRemoved.length ) {
3650

M
Mr.doob 已提交
3651 3652
			removeObject( scene.__objectsRemoved[ 0 ], scene );
			scene.__objectsRemoved.splice( 0, 1 );
3653 3654

		}
3655

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

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

M
Mr.doob 已提交
3660
			updateObject( scene.__webglObjects[ o ].object, scene );
A
alteredq 已提交
3661 3662

		}
3663

M
Mikael Emtinger 已提交
3664 3665 3666 3667 3668
		for ( var o = 0, ol = scene.__webglShadowVolumes.length; o < ol; o ++ ) {

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

		}
3669

M
Mikael Emtinger 已提交
3670 3671 3672 3673 3674
		for ( var o = 0, ol = scene.__webglLensFlares.length; o < ol; o ++ ) {

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

		}
A
alteredq 已提交
3675

3676
/*		for ( var o = 0, ol = scene.__webglSprites.length; o < ol; o ++ ) {
M
Mikael Emtinger 已提交
3677 3678 3679

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

3680
		}*/
M
Mikael Emtinger 已提交
3681

3682
	};
3683

3684
	function addObject( object, scene ) {
3685

3686
		var g, geometry, geometryGroup;
M
Mr.doob 已提交
3687

3688
		if ( object._modelViewMatrix == undefined ) {
3689

3690
			object._modelViewMatrix = new THREE.Matrix4();
3691

3692 3693 3694
			object._normalMatrixArray = new Float32Array( 9 );
			object._modelViewMatrixArray = new Float32Array( 16 );
			object._objectMatrixArray = new Float32Array( 16 );
3695

3696
			object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
3697

3698
		}
A
alteredq 已提交
3699

3700
		if ( object instanceof THREE.Mesh ) {
A
alteredq 已提交
3701

3702 3703 3704 3705 3706 3707 3708 3709
			geometry = object.geometry;

			if ( geometry.geometryGroups == undefined ) {

				sortFacesByMaterial( geometry );

			}

3710
			// create separate VBOs per geometry chunk
A
alteredq 已提交
3711

3712
			for ( g in geometry.geometryGroups ) {
A
alteredq 已提交
3713

3714
				geometryGroup = geometry.geometryGroups[ g ];
M
Mr.doob 已提交
3715

3716
				// initialise VBO on the first access
M
Mr.doob 已提交
3717

3718
				if ( ! geometryGroup.__webglVertexBuffer ) {
M
Mr.doob 已提交
3719

3720 3721
					createMeshBuffers( geometryGroup );
					initMeshBuffers( geometryGroup, object );
A
alteredq 已提交
3722

3723
					geometry.__dirtyVertices = true;
3724
					geometry.__dirtyMorphTargets = true;
3725 3726 3727 3728 3729
					geometry.__dirtyElements = true;
					geometry.__dirtyUvs = true;
					geometry.__dirtyNormals = true;
					geometry.__dirtyTangents = true;
					geometry.__dirtyColors = true;
M
Mr.doob 已提交
3730

3731
				}
3732

3733
				// create separate wrapper per each use of VBO
3734

3735 3736
				if ( object instanceof THREE.ShadowVolume ) {

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

M
Mikael Emtinger 已提交
3739
				} else {
3740

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

M
Mikael Emtinger 已提交
3743
				}
3744

3745
			}
M
Mr.doob 已提交
3746

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

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

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

3753 3754
			geometry = object.geometry;

3755
			if( ! geometry.__webglVertexBuffer ) {
A
alteredq 已提交
3756 3757 3758 3759 3760 3761 3762 3763 3764

				createRibbonBuffers( geometry );
				initRibbonBuffers( geometry );

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

			}

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

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

3769 3770
			geometry = object.geometry;

3771
			if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
3772

3773 3774
				createLineBuffers( geometry );
				initLineBuffers( geometry );
M
Mr.doob 已提交
3775

3776 3777
				geometry.__dirtyVertices = true;
				geometry.__dirtyColors = true;
M
Mr.doob 已提交
3778

3779
			}
M
Mr.doob 已提交
3780

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

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

			geometry = object.geometry;

3787
			if ( ! geometry.__webglVertexBuffer ) {
A
alteredq 已提交
3788 3789 3790 3791 3792 3793

				createParticleBuffers( geometry );
				initParticleBuffers( geometry );

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

3795
			}
3796

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

A
alteredq 已提交
3799 3800 3801 3802
		} else if ( THREE.MarchingCubes !== undefined && object instanceof THREE.MarchingCubes ) {

			addBufferImmediate( scene.__webglObjectsImmediate, object );

3803 3804 3805 3806 3807 3808 3809
		} else if ( object instanceof THREE.Sprite ) {
			
			scene.__webglSprites.push( object );
		}
		
		
		/*else if ( object instanceof THREE.Particle ) {
A
alteredq 已提交
3810 3811 3812 3813 3814

		}*/

	};

3815
	function updateObject( object, scene ) {
A
alteredq 已提交
3816

3817
		var g, geometry, geometryGroup, a, customAttributeDirty;
A
alteredq 已提交
3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828

		if ( object instanceof THREE.Mesh ) {

			geometry = object.geometry;

			// check all geometry groups

			for ( g in geometry.geometryGroups ) {

				geometryGroup = geometry.geometryGroups[ g ];

3829 3830
				customAttributeDirty = false;

M
Mr.doob 已提交
3831 3832 3833 3834
				for ( a in geometryGroup.__webglCustomAttributes ) {

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

3835 3836 3837
						customAttributeDirty = true;
						break;
					}
M
Mr.doob 已提交
3838

3839 3840
				}

3841
				if ( geometry.__dirtyVertices || geometry.__dirtyMorphTargets || geometry.__dirtyElements ||
A
alteredq 已提交
3842
					geometry.__dirtyUvs || geometry.__dirtyNormals ||
3843
					geometry.__dirtyColors || geometry.__dirtyTangents || customAttributeDirty ) {
A
alteredq 已提交
3844 3845 3846 3847 3848 3849 3850

					setMeshBuffers( geometryGroup, object, _gl.DYNAMIC_DRAW );

				}

			}

3851
			geometry.__dirtyVertices = false;
3852
			geometry.__dirtyMorphTargets = false;
A
alteredq 已提交
3853 3854 3855 3856
			geometry.__dirtyElements = false;
			geometry.__dirtyUvs = false;
			geometry.__dirtyNormals = false;
			geometry.__dirtyTangents = false;
3857
			geometry.__dirtyColors = false;
M
Mr.doob 已提交
3858

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

3861 3862
			geometry = object.geometry;

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

A
alteredq 已提交
3865
				setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
3866

A
alteredq 已提交
3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878
			}

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

3880
			}
3881

A
alteredq 已提交
3882 3883 3884 3885 3886 3887 3888
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;

		} else if ( object instanceof THREE.ParticleSystem ) {

			geometry = object.geometry;

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

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

3893
			}
M
Mr.doob 已提交
3894

3895 3896
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
M
Mr.doob 已提交
3897

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

A
alteredq 已提交
3900
			// it updates itself in render callback
3901 3902

		} else if ( object instanceof THREE.Particle ) {
3903 3904

		}*/
3905

3906
	};
3907

3908
	function removeObject( object, scene ) {
M
Mr.doob 已提交
3909 3910 3911 3912 3913 3914 3915 3916 3917 3918

		var o, ol, zobject;

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

			zobject = scene.__webglObjects[ o ].object;

			if ( object == zobject ) {

				scene.__webglObjects.splice( o, 1 );
3919
				return;
M
Mr.doob 已提交
3920 3921 3922 3923

			}

		}
3924 3925
		
		// add shadwos/sprites etc.
M
Mr.doob 已提交
3926 3927 3928

	};

3929
	function sortFacesByMaterial( geometry ) {
3930 3931 3932 3933 3934 3935 3936

		// 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 = {};
3937
		var numMorphTargets = geometry.morphTargets !== undefined ? geometry.morphTargets.length : 0;
3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979

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

3980
				geometry.geometryGroups[ ghash ] = { 'faces': [], 'materials': materials, 'vertices': 0, 'numMorphTargets': numMorphTargets };
3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992

			}

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

3993
					geometry.geometryGroups[ ghash ] = { 'faces': [], 'materials': materials, 'vertices': 0, 'numMorphTargets': numMorphTargets };
3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005

				}

			}

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

		}

	};

4006
	function addBuffer( objlist, buffer, object ) {
4007

4008 4009 4010 4011 4012
		objlist.push( {
			buffer: buffer, object: object,
			opaque: { list: [], count: 0 },
			transparent: { list: [], count: 0 }
		} );
M
Mr.doob 已提交
4013

4014
	};
4015

4016
	function addBufferImmediate( objlist, object ) {
4017

4018 4019 4020 4021 4022
		objlist.push( {
			object: object,
			opaque: { list: [], count: 0 },
			transparent: { list: [], count: 0 }
		} );
4023

4024
	};
4025

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

4028
		if ( cullFace ) {
M
Mr.doob 已提交
4029

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

4032
				_gl.frontFace( _gl.CCW );
M
Mr.doob 已提交
4033

4034
			} else {
M
Mr.doob 已提交
4035

4036
				_gl.frontFace( _gl.CW );
M
Mr.doob 已提交
4037

4038
			}
M
Mr.doob 已提交
4039

4040
			if( cullFace == "back" ) {
M
Mr.doob 已提交
4041

4042
				_gl.cullFace( _gl.BACK );
M
Mr.doob 已提交
4043

4044
			} else if( cullFace == "front" ) {
M
Mr.doob 已提交
4045

4046
				_gl.cullFace( _gl.FRONT );
M
Mr.doob 已提交
4047

4048
			} else {
M
Mr.doob 已提交
4049

4050
				_gl.cullFace( _gl.FRONT_AND_BACK );
M
Mr.doob 已提交
4051

4052
			}
M
Mr.doob 已提交
4053

4054
			_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
4055

4056
		} else {
M
Mr.doob 已提交
4057

4058
			_gl.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
4059

4060 4061 4062
		}

	};
N
Nicolas Garcia Belmonte 已提交
4063

4064
	this.supportsVertexTextures = function () {
4065

4066
		return maxVertexTextures() > 0;
4067

4068
	};
4069

4070
	function maxVertexTextures() {
4071

4072 4073 4074
		return _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );

	};
4075

4076
	function initGL( antialias, clearColor, clearAlpha, stencil ) {
N
Nicolas Garcia Belmonte 已提交
4077 4078 4079

		try {

M
Mikael Emtinger 已提交
4080
			if ( ! ( _gl = _canvas.getContext( 'experimental-webgl', { antialias: antialias, stencil: stencil } ) ) ) {
N
Nicolas Garcia Belmonte 已提交
4081

4082
				throw 'Error creating WebGL context.';
N
Nicolas Garcia Belmonte 已提交
4083

4084 4085 4086
			}

		} catch ( e ) {
N
Nicolas Garcia Belmonte 已提交
4087

4088
			console.error( e );
N
Nicolas Garcia Belmonte 已提交
4089 4090 4091 4092 4093 4094 4095 4096 4097

		}

		_gl.clearColor( 0, 0, 0, 1 );
		_gl.clearDepth( 1 );

		_gl.enable( _gl.DEPTH_TEST );
		_gl.depthFunc( _gl.LEQUAL );

4098 4099
		_gl.frontFace( _gl.CCW );
		_gl.cullFace( _gl.BACK );
4100
		_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
4101

N
Nicolas Garcia Belmonte 已提交
4102
		_gl.enable( _gl.BLEND );
4103 4104 4105
		_gl.blendEquation( _gl.FUNC_ADD );
		_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA );

4106
		_gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearAlpha );
4107

4108 4109
		// _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, true );

A
alteredq 已提交
4110
		_cullEnabled = true;
N
Nicolas Garcia Belmonte 已提交
4111

4112
	};
M
Mr.doob 已提交
4113

4114
	function buildProgram( shaderID, fragmentShader, vertexShader, uniforms, attributes, parameters ) {
4115

4116
		var p, pl, program, code;
4117
		var chunks = [];
4118 4119 4120

		// Generate code

4121 4122 4123 4124 4125 4126 4127 4128 4129 4130
		if ( shaderID ) {

			chunks.push( shaderID );

		} else {

			chunks.push( fragmentShader );
			chunks.push( vertexShader );

		}
4131 4132 4133

		for ( p in parameters ) {

4134 4135
			chunks.push( p );
			chunks.push( parameters[ p ] );
4136 4137 4138

		}

4139 4140
		code = chunks.join();

4141 4142 4143 4144 4145 4146 4147
		// 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*/ );
4148

4149 4150 4151 4152 4153
				return _programs[ p ].program;

			}

		}
4154 4155
		
		//console.log( "building new program " );
4156 4157 4158 4159

		//

		program = _gl.createProgram(),
M
Mr.doob 已提交
4160

M
Mr.doob 已提交
4161 4162 4163 4164
		prefix_fragment = [
			"#ifdef GL_ES",
			"precision highp float;",
			"#endif",
M
Mr.doob 已提交
4165

4166 4167
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
A
alteredq 已提交
4168

4169 4170
			parameters.fog ? "#define USE_FOG" : "",
			parameters.fog instanceof THREE.FogExp2 ? "#define FOG_EXP2" : "",
4171

4172
			parameters.map ? "#define USE_MAP" : "",
4173 4174 4175
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
4176

4177
			"uniform mat4 viewMatrix;",
4178
			"uniform vec3 cameraPosition;",
M
Mr.doob 已提交
4179 4180
			""
		].join("\n"),
4181

M
Mr.doob 已提交
4182
		prefix_vertex = [
4183
			maxVertexTextures() > 0 ? "#define VERTEX_TEXTURES" : "",
4184

4185 4186 4187
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

4188 4189
			"#define MAX_BONES " + parameters.maxBones,

4190
			parameters.map ? "#define USE_MAP" : "",
4191 4192 4193
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
4194
			parameters.skinning ? "#define USE_SKINNING" : "",
4195
			parameters.morphTargets ? "#define USE_MORPHTARGETS" : "",
4196

4197

4198 4199
			parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",

M
Mr.doob 已提交
4200 4201 4202
			"uniform mat4 objectMatrix;",
			"uniform mat4 modelViewMatrix;",
			"uniform mat4 projectionMatrix;",
4203 4204
			"uniform mat4 viewMatrix;",
			"uniform mat3 normalMatrix;",
M
Mr.doob 已提交
4205
			"uniform vec3 cameraPosition;",
A
alteredq 已提交
4206 4207 4208

			"uniform mat4 cameraInverseMatrix;",

M
Mr.doob 已提交
4209 4210 4211
			"attribute vec3 position;",
			"attribute vec3 normal;",
			"attribute vec2 uv;",
4212
			"attribute vec2 uv2;",
4213

4214
			"#ifdef USE_COLOR",
4215

4216
				"attribute vec3 color;",
4217

4218 4219
			"#endif",

4220
			"#ifdef USE_MORPHTARGETS",
4221

4222 4223 4224 4225 4226 4227 4228 4229
				"attribute vec3 morphTarget0;",
				"attribute vec3 morphTarget1;",
				"attribute vec3 morphTarget2;",
				"attribute vec3 morphTarget3;",
				"attribute vec3 morphTarget4;",
				"attribute vec3 morphTarget5;",
				"attribute vec3 morphTarget6;",
				"attribute vec3 morphTarget7;",
4230

4231 4232 4233
			"#endif",

			"#ifdef USE_SKINNING",
4234

4235 4236 4237 4238
				"attribute vec4 skinVertexA;",
				"attribute vec4 skinVertexB;",
				"attribute vec4 skinIndex;",
				"attribute vec4 skinWeight;",
4239

4240
			"#endif",
4241

M
Mr.doob 已提交
4242 4243
			""
		].join("\n");
4244

4245 4246
		_gl.attachShader( program, getShader( "fragment", prefix_fragment + fragmentShader ) );
		_gl.attachShader( program, getShader( "vertex", prefix_vertex + vertexShader ) );
M
Mr.doob 已提交
4247

M
Mr.doob 已提交
4248
		_gl.linkProgram( program );
N
Nicolas Garcia Belmonte 已提交
4249

M
Mr.doob 已提交
4250
		if ( !_gl.getProgramParameter( program, _gl.LINK_STATUS ) ) {
N
Nicolas Garcia Belmonte 已提交
4251

4252
			console.error( "Could not initialise shader\n" + "VALIDATE_STATUS: " + _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) + ", gl error [" + _gl.getError() + "]" );
M
Mr.doob 已提交
4253

N
Nicolas Garcia Belmonte 已提交
4254
		}
4255

4256 4257
		//console.log( prefix_fragment + fragmentShader );
		//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
4258

M
Mr.doob 已提交
4259
		program.uniforms = {};
4260
		program.attributes = {};
M
Mr.doob 已提交
4261

4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303
		var identifiers, u, a, i;

		// cache uniform locations

		identifiers = [

			'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition',
			'cameraInverseMatrix', 'boneGlobalMatrices', 'morphTargetInfluences'

		];

		for ( u in uniforms ) {

			identifiers.push( u );

		}

		cacheUniformLocations( program, identifiers );
		
		// cache attributes locations

		identifiers = [

			"position", "normal", "uv", "uv2", "tangent", "color",
			"skinVertexA", "skinVertexB", "skinIndex", "skinWeight"

		];

		for ( i = 0; i < parameters.maxMorphTargets; i++ ) {

			identifiers.push( "morphTarget" + i );

		}

		for ( a in attributes ) {

			identifiers.push( a );

		}

		cacheAttributeLocations( program, identifiers );

4304 4305
		_programs.push( { program: program, code: code } );

M
Mr.doob 已提交
4306
		return program;
M
Mr.doob 已提交
4307

M
Mr.doob 已提交
4308
	};
M
Mr.doob 已提交
4309

4310
	function loadUniformsSkinning( uniforms, object ) {
4311

M
Mr.doob 已提交
4312
		_gl.uniformMatrix4fv( uniforms.cameraInverseMatrix, false, _viewMatrixArray );
A
alteredq 已提交
4313
		_gl.uniformMatrix4fv( uniforms.boneGlobalMatrices, false, object.boneMatrices );
4314

4315
	};
4316

4317

4318
	function loadUniformsMatrices( uniforms, object ) {
4319

A
alteredq 已提交
4320 4321 4322 4323
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray );
		_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrixArray );

	};
4324

4325
	function loadUniformsGeneric( program, uniforms ) {
M
Mr.doob 已提交
4326

4327
		var u, uniform, value, type, location, texture;
M
Mr.doob 已提交
4328

M
Mr.doob 已提交
4329
		for( u in uniforms ) {
M
Mr.doob 已提交
4330

4331 4332
			location = program.uniforms[u];
			if ( !location ) continue;
M
Mr.doob 已提交
4333

4334
			uniform = uniforms[u];
M
Mr.doob 已提交
4335

4336 4337
			type = uniform.type;
			value = uniform.value;
M
Mr.doob 已提交
4338

M
Mr.doob 已提交
4339
			if( type == "i" ) {
M
Mr.doob 已提交
4340

M
Mr.doob 已提交
4341
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
4342

M
Mr.doob 已提交
4343
			} else if( type == "f" ) {
M
Mr.doob 已提交
4344

M
Mr.doob 已提交
4345
				_gl.uniform1f( location, value );
4346

A
alteredq 已提交
4347 4348 4349
			} else if( type == "fv1" ) {

				_gl.uniform1fv( location, value );
M
Mr.doob 已提交
4350

4351 4352 4353 4354
			} else if( type == "fv" ) {

				_gl.uniform3fv( location, value );

4355 4356 4357 4358
			} else if( type == "v2" ) {

				_gl.uniform2f( location, value.x, value.y );

4359 4360 4361
			} else if( type == "v3" ) {

				_gl.uniform3f( location, value.x, value.y, value.z );
4362

4363 4364 4365 4366
			} else if( type == "v4" ) {

				_gl.uniform4f( location, value.x, value.y, value.z, value.w );

4367 4368 4369
			} else if( type == "c" ) {

				_gl.uniform3f( location, value.r, value.g, value.b );
M
Mr.doob 已提交
4370

M
Mr.doob 已提交
4371
			} else if( type == "t" ) {
M
Mr.doob 已提交
4372

M
Mr.doob 已提交
4373
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
4374

4375
				texture = uniform.texture;
M
Mr.doob 已提交
4376

4377
				if ( !texture ) continue;
M
Mr.doob 已提交
4378

4379
				if ( texture.image instanceof Array && texture.image.length == 6 ) {
M
Mr.doob 已提交
4380

4381
					setCubeTexture( texture, value );
M
Mr.doob 已提交
4382

4383
				} else {
M
Mr.doob 已提交
4384

4385
					setTexture( texture, value );
M
Mr.doob 已提交
4386

4387
				}
M
Mr.doob 已提交
4388

4389
			}
M
Mr.doob 已提交
4390

4391
		}
M
Mr.doob 已提交
4392

4393
	};
M
Mr.doob 已提交
4394

4395
	function setBlending( blending ) {
A
alteredq 已提交
4396 4397

		if ( blending != _oldBlending ) {
4398

A
alteredq 已提交
4399 4400 4401 4402 4403
			switch ( blending ) {

				case THREE.AdditiveBlending:

					_gl.blendEquation( _gl.FUNC_ADD );
4404
					_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE );
A
alteredq 已提交
4405 4406 4407 4408 4409

					break;

				case THREE.SubtractiveBlending:

4410 4411 4412 4413
					// TODO: Find blendFuncSeparate() combination

					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.ZERO, _gl.ONE_MINUS_SRC_COLOR );
A
alteredq 已提交
4414 4415 4416

					break;

4417 4418 4419
				case THREE.MultiplyBlending:

					// TODO: Find blendFuncSeparate() combination
A
alteredq 已提交
4420 4421

					_gl.blendEquation( _gl.FUNC_ADD );
4422
					_gl.blendFunc( _gl.ZERO, _gl.SRC_COLOR );
A
alteredq 已提交
4423 4424 4425 4426 4427

					break;

				default:

4428 4429
					_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 已提交
4430 4431

					break;
4432

A
alteredq 已提交
4433
			}
4434

A
alteredq 已提交
4435
			_oldBlending = blending;
4436

A
alteredq 已提交
4437 4438 4439
		}

	};
4440

4441
	function setTextureParameters( textureType, texture, image ) {
4442

4443
		if ( isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ) ) {
M
Mr.doob 已提交
4444

4445 4446
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
M
Mr.doob 已提交
4447

4448 4449
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
M
Mr.doob 已提交
4450

4451
			_gl.generateMipmap( textureType );
M
Mr.doob 已提交
4452

4453
		} else {
M
Mr.doob 已提交
4454

4455 4456
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
4457

4458 4459
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
M
Mr.doob 已提交
4460

4461
		}
M
Mr.doob 已提交
4462

4463
	};
4464

4465
	function setTexture( texture, slot ) {
4466

4467
		if ( texture.needsUpdate ) {
A
alteredq 已提交
4468

4469
			if ( !texture.__webglInit ) {
M
Mr.doob 已提交
4470

4471
				texture.__webglTexture = _gl.createTexture();
A
alteredq 已提交
4472

4473
				_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
4474
				_gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image );
M
Mr.doob 已提交
4475

4476
				texture.__webglInit = true;
M
Mr.doob 已提交
4477

A
alteredq 已提交
4478
			} else {
M
Mr.doob 已提交
4479

4480
				_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
A
alteredq 已提交
4481
				_gl.texSubImage2D( _gl.TEXTURE_2D, 0, 0, 0, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image );
M
Mr.doob 已提交
4482 4483 4484

			}

4485 4486
			setTextureParameters( _gl.TEXTURE_2D, texture, texture.image );
			_gl.bindTexture( _gl.TEXTURE_2D, null );
4487

A
alteredq 已提交
4488
			texture.needsUpdate = false;
4489 4490 4491 4492

		}

		_gl.activeTexture( _gl.TEXTURE0 + slot );
4493
		_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
M
Mr.doob 已提交
4494

4495
	};
M
Mr.doob 已提交
4496

4497
	function setCubeTexture( texture, slot ) {
4498 4499 4500 4501 4502

		if ( texture.image.length == 6 ) {

			if ( texture.needsUpdate ) {

4503 4504 4505
				if ( !texture.__webglInit ) {

					texture.image.__webglTextureCube = _gl.createTexture();
4506

4507
					_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
4508

4509
					for ( var i = 0; i < 6; ++i ) {
4510

4511
						_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image[ i ] );
4512

4513
					}
4514 4515

					texture.__webglInit = true;
4516 4517 4518

				} else {

4519
					_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
4520

4521
					for ( var i = 0; i < 6; ++i ) {
4522

4523
						_gl.texSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image[ i ] );
4524

4525
					}
4526 4527 4528

				}

4529
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, texture.image[0] );
4530 4531 4532
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );

				texture.needsUpdate = false;
4533

4534 4535 4536
			}

			_gl.activeTexture( _gl.TEXTURE0 + slot );
4537
			_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
4538 4539 4540 4541 4542

		}

	};

4543
	function setRenderTarget( renderTexture ) {
4544

4545
		if ( renderTexture && !renderTexture.__webglFramebuffer ) {
M
Mr.doob 已提交
4546

M
Mikael Emtinger 已提交
4547 4548 4549
			if( renderTexture.depthBuffer === undefined ) renderTexture.depthBuffer = true;
			if( renderTexture.stencilBuffer === undefined ) renderTexture.stencilBuffer = true;

4550 4551 4552
			renderTexture.__webglFramebuffer = _gl.createFramebuffer();
			renderTexture.__webglRenderbuffer = _gl.createRenderbuffer();
			renderTexture.__webglTexture = _gl.createTexture();
4553 4554 4555


			// Setup texture
M
Mr.doob 已提交
4556

4557
			_gl.bindTexture( _gl.TEXTURE_2D, renderTexture.__webglTexture );
4558 4559 4560 4561
			_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 ) );
4562
			_gl.texImage2D( _gl.TEXTURE_2D, 0, paramThreeToGL( renderTexture.format ), renderTexture.width, renderTexture.height, 0, paramThreeToGL( renderTexture.format ), paramThreeToGL( renderTexture.type ), null );
4563

M
Mikael Emtinger 已提交
4564
			// Setup render and frame buffer
M
Mr.doob 已提交
4565

M
Mikael Emtinger 已提交
4566
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderTexture.__webglRenderbuffer );
4567
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTexture.__webglFramebuffer );
M
Mikael Emtinger 已提交
4568

4569
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, renderTexture.__webglTexture, 0 );
M
Mikael Emtinger 已提交
4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592
			
			if( renderTexture.depthBuffer && !renderTexture.stencilBuffer ) {
				
				_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTexture.width, renderTexture.height );
				_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderTexture.__webglRenderbuffer );
		
		/* For some reason this is not working. Defaulting to RGBA4.	
			} else if( !renderTexture.depthBuffer && renderTexture.stencilBuffer ) {
			
				_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.STENCIL_INDEX8, renderTexture.width, renderTexture.height );
				_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderTexture.__webglRenderbuffer );
			*/
			} else if( renderTexture.depthBuffer && renderTexture.stencilBuffer ) {
				
				_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTexture.width, renderTexture.height );
				_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderTexture.__webglRenderbuffer );
				
			} else {
				
				_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTexture.width, renderTexture.height );
				
			}
			
4593 4594

			// Release everything
M
Mr.doob 已提交
4595

4596 4597 4598
			_gl.bindTexture( _gl.TEXTURE_2D, null );
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
M
Mr.doob 已提交
4599

4600 4601
		}

4602
		var framebuffer, width, height;
M
Mr.doob 已提交
4603

4604
		if ( renderTexture ) {
M
Mr.doob 已提交
4605

4606
			framebuffer = renderTexture.__webglFramebuffer;
4607 4608
			width = renderTexture.width;
			height = renderTexture.height;
M
Mr.doob 已提交
4609

4610
		} else {
M
Mr.doob 已提交
4611

4612
			framebuffer = null;
4613 4614
			width = _viewportWidth;
			height = _viewportHeight;
M
Mr.doob 已提交
4615

4616
		}
M
Mr.doob 已提交
4617

4618
		if ( framebuffer != _currentFramebuffer ) {
M
Mr.doob 已提交
4619

4620
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
4621
			_gl.viewport( _viewportX, _viewportY, width, height );
M
Mr.doob 已提交
4622

4623
			_currentFramebuffer = framebuffer;
M
Mr.doob 已提交
4624

4625
		}
4626

4627
	};
M
Mr.doob 已提交
4628

4629
	function updateRenderTargetMipmap( renderTarget ) {
M
Mr.doob 已提交
4630

4631
		_gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
4632 4633
		_gl.generateMipmap( _gl.TEXTURE_2D );
		_gl.bindTexture( _gl.TEXTURE_2D, null );
M
Mr.doob 已提交
4634 4635

	};
4636

4637
	function cacheUniformLocations( program, identifiers ) {
M
Mr.doob 已提交
4638

M
Mr.doob 已提交
4639
		var i, l, id;
M
Mr.doob 已提交
4640

M
Mr.doob 已提交
4641
		for( i = 0, l = identifiers.length; i < l; i++ ) {
M
Mr.doob 已提交
4642

4643 4644
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
4645

M
Mr.doob 已提交
4646
		}
M
Mr.doob 已提交
4647

M
Mr.doob 已提交
4648
	};
M
Mr.doob 已提交
4649

4650
	function cacheAttributeLocations( program, identifiers ) {
4651

4652
		var i, l, id;
M
Mr.doob 已提交
4653

4654
		for( i = 0, l = identifiers.length; i < l; i++ ) {
M
Mr.doob 已提交
4655

4656 4657
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
M
Mr.doob 已提交
4658

4659
		}
M
Mr.doob 已提交
4660

M
Mr.doob 已提交
4661
	};
M
Mr.doob 已提交
4662

4663
	function getShader( type, string ) {
N
Nicolas Garcia Belmonte 已提交
4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681

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

4682
			console.error( _gl.getShaderInfoLog( shader ) );
4683
			console.error( string );
N
Nicolas Garcia Belmonte 已提交
4684 4685 4686 4687 4688
			return null;

		}

		return shader;
M
Mr.doob 已提交
4689

4690
	};
N
Nicolas Garcia Belmonte 已提交
4691

4692
	// fallback filters for non-power-of-2 textures
4693

4694
	function filterFallback( f ) {
4695

4696 4697 4698 4699 4700 4701 4702 4703
		switch ( f ) {

			case THREE.NearestFilter:
			case THREE.NearestMipMapNearestFilter:
			case THREE.NearestMipMapLinearFilter: return _gl.NEAREST; break;

			case THREE.LinearFilter:
			case THREE.LinearMipMapNearestFilter:
M
Mikael Emtinger 已提交
4704 4705
			case THREE.LinearMipMapLinearFilter: 
			default:
4706

M
Mikael Emtinger 已提交
4707
				return _gl.LINEAR; break;
4708 4709

		}
4710

4711
	};
4712 4713

	function paramThreeToGL( p ) {
M
Mr.doob 已提交
4714

4715
		switch ( p ) {
M
Mr.doob 已提交
4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728

			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;

4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742
			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;

4743
		}
M
Mr.doob 已提交
4744

4745
		return 0;
M
Mr.doob 已提交
4746

4747 4748
	};

4749
	function isPowerOfTwo( value ) {
4750 4751 4752 4753 4754

		return ( value & ( value - 1 ) ) == 0;

	};

4755
	function materialNeedsSmoothNormals( material ) {
4756 4757 4758

		return material && material.shading != undefined && material.shading == THREE.SmoothShading;

4759
	};
M
Mr.doob 已提交
4760

4761
	function bufferNeedsSmoothNormals( geometryGroup, object ) {
M
Mr.doob 已提交
4762

4763
		var m, ml, i, l, meshMaterial, needsSmoothNormals = false;
M
Mr.doob 已提交
4764

M
Mr.doob 已提交
4765
		for ( m = 0, ml = object.materials.length; m < ml; m++ ) {
4766

M
Mr.doob 已提交
4767
			meshMaterial = object.materials[ m ];
4768 4769 4770

			if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {

4771
				for ( i = 0, l = geometryGroup.materials.length; i < l; i++ ) {
4772

4773
					if ( materialNeedsSmoothNormals( geometryGroup.materials[ i ] ) ) {
4774

4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795
						needsSmoothNormals = true;
						break;

					}

				}

			} else {

				if ( materialNeedsSmoothNormals( meshMaterial ) ) {

					needsSmoothNormals = true;
					break;

				}

			}

			if ( needsSmoothNormals ) break;

		}
M
Mr.doob 已提交
4796

4797
		return needsSmoothNormals;
M
Mr.doob 已提交
4798

4799
	};
M
Mr.doob 已提交
4800

4801
	function unrollGroupMaterials( geometryGroup, object ) {
4802

4803 4804 4805
		var m, ml, i, il,
			material, meshMaterial,
			materials = [];
4806

4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817
		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 ) {
4818

4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837
						materials.push( material );

					}

				}

			} else {

				material = meshMaterial;

				if ( material ) {

					materials.push( material );

				}

			}

		}
4838

4839 4840 4841
		return materials;

	};
4842

4843
	function bufferGuessVertexColorType( materials, geometryGroup, object ) {
4844

4845
		var i, m, ml = materials.length;
4846

4847
		// use vertexColor type from the first material in unrolled materials
4848

4849
		for ( i = 0; i < ml; i++ ) {
4850

4851
			m = materials[ i ];
4852

4853
			if ( m.vertexColors ) {
4854

4855 4856 4857
				return m.vertexColors;

			}
4858

4859
		}
4860

4861
		return false;
4862

4863 4864
	};

4865
	function bufferGuessNormalType( materials, geometryGroup, object ) {
4866

4867
		var i, m, ml = materials.length;
4868

4869
		// only MeshBasicMaterial and MeshDepthMaterial don't need normals
4870

4871
		for ( i = 0; i < ml; i++ ) {
4872

4873
			m = materials[ i ];
4874

A
alteredq 已提交
4875
			if ( ( m instanceof THREE.MeshBasicMaterial && !m.envMap ) || m instanceof THREE.MeshDepthMaterial ) continue;
4876

4877
			if ( materialNeedsSmoothNormals( m ) ) {
4878

4879 4880 4881 4882 4883 4884 4885 4886 4887
				return THREE.SmoothShading;

			} else {

				return THREE.FlatShading;

			}

		}
4888

4889
		return false;
4890

4891 4892
	};

4893
	function bufferGuessUVType( materials, geometryGroup, object ) {
4894

4895
		var i, m, ml = materials.length;
4896

4897
		// material must use some texture to require uvs
4898

4899
		for ( i = 0; i < ml; i++ ) {
4900

4901
			m = materials[ i ];
4902

A
alteredq 已提交
4903
			if ( m.map || m.lightMap || m instanceof THREE.MeshShaderMaterial ) {
4904

4905
				return true;
4906

4907
			}
4908

4909
		}
4910

4911
		return false;
4912

4913
	};
4914

4915
	function allocateBones( object ) {
4916

4917 4918 4919 4920 4921 4922 4923
		// 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)
4924

4925
		var maxBones = 50;
4926

4927
		if ( object !== undefined && object instanceof THREE.SkinnedMesh ) {
4928

4929 4930 4931 4932 4933
			maxBones = object.bones.length;

		}

		return maxBones;
4934

4935
	};
4936

4937
	function allocateLights( lights, maxLights ) {
4938

4939 4940
		var l, ll, light, dirLights, pointLights, maxDirLights, maxPointLights;
		dirLights = pointLights = maxDirLights = maxPointLights = 0;
4941

4942
		for ( l = 0, ll = lights.length; l < ll; l++ ) {
4943

4944
			light = lights[ l ];
4945

4946 4947
			if ( light instanceof THREE.DirectionalLight ) dirLights++;
			if ( light instanceof THREE.PointLight ) pointLights++;
4948

4949
		}
4950

4951
		if ( ( pointLights + dirLights ) <= maxLights ) {
4952

4953 4954
			maxDirLights = dirLights;
			maxPointLights = pointLights;
4955

4956
		} else {
4957

4958 4959
			maxDirLights = Math.ceil( maxLights * dirLights / ( pointLights + dirLights ) );
			maxPointLights = maxLights - maxDirLights;
4960 4961 4962

		}

4963
		return { 'directional' : maxDirLights, 'point' : maxPointLights };
4964 4965

	};
M
Mr.doob 已提交
4966

A
alteredq 已提交
4967
	/* DEBUG
4968
	function getGLParams() {
M
Mr.doob 已提交
4969

4970
		var params  = {
M
Mr.doob 已提交
4971

4972 4973
			'MAX_VARYING_VECTORS': _gl.getParameter( _gl.MAX_VARYING_VECTORS ),
			'MAX_VERTEX_ATTRIBS': _gl.getParameter( _gl.MAX_VERTEX_ATTRIBS ),
M
Mr.doob 已提交
4974

4975 4976 4977
			'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 已提交
4978

4979 4980 4981
			'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 已提交
4982

4983 4984
		return params;
	};
M
Mr.doob 已提交
4985

4986
	function dumpObject( obj ) {
M
Mr.doob 已提交
4987

4988 4989
		var p, str = "";
		for ( p in obj ) {
M
Mr.doob 已提交
4990

4991
			str += p + ": " + obj[p] + "\n";
M
Mr.doob 已提交
4992

4993
		}
M
Mr.doob 已提交
4994

4995 4996
		return str;
	}
A
alteredq 已提交
4997
	*/
4998
};
4999