WebGLRenderer.js 131.2 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
	var _this = this,
24
	_gl, _programs = [],
25 26
	_currentProgram = null,
	_currentFramebuffer = null,
27
	_currentDepthMask = true,
M
Mr.doob 已提交
28

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

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

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

42
	// camera matrices caches
43 44

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

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

57
	_vector3 = new THREE.Vector4(),
58

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

A
alteredq 已提交
61 62
	_lights = {

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

	},

69
	// parameters
70

71
	parameters = parameters || {},
M
Mr.doob 已提交
72

73 74 75 76 77
	_canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElement( 'canvas' ),
	_stencil = parameters.stencil !== undefined ? parameters.stencil : true,
	_antialias = parameters.antialias !== undefined ? parameters.antialias : false,
	_clearColor = parameters.clearColor !== undefined ? new THREE.Color( parameters.clearColor ) : new THREE.Color( 0x000000 ),
	_clearAlpha = parameters.clearAlpha !== undefined ? parameters.clearAlpha : 0;
M
Mr.doob 已提交
78

79 80 81
	this.data = {

		vertices: 0,
82 83
		faces: 0,
		drawCalls: 0
84

85
	};
M
Mr.doob 已提交
86

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

92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
	// Init GL

	try {

		if ( ! ( _gl = _canvas.getContext( 'experimental-webgl', { antialias: _antialias, stencil: _stencil } ) ) ) {

			throw 'Error creating WebGL context.';

		}

	} catch ( error ) {

		console.error( error );

	}

	console.log(
		navigator.userAgent + " | " +
		_gl.getParameter( _gl.VERSION ) + " | " +
		_gl.getParameter( _gl.VENDOR ) + " | " +
		_gl.getParameter( _gl.RENDERER ) + " | " +
		_gl.getParameter( _gl.SHADING_LANGUAGE_VERSION )
	);

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

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

	_gl.frontFace( _gl.CCW );
	_gl.cullFace( _gl.BACK );
	_gl.enable( _gl.CULL_FACE );

	_gl.enable( _gl.BLEND );
	_gl.blendEquation( _gl.FUNC_ADD );
	_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA );

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

	// _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, true );

	_cullEnabled = true;

	//
M
Mr.doob 已提交
137

138 139
	this.context = _gl;

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

M
Mikael Emtinger 已提交
142
	// prepare stencil shadow polygon
M
Mikael Emtinger 已提交
143

144
	if ( _stencil ) {
M
Mr.doob 已提交
145

M
Mikael Emtinger 已提交
146
		var _stencilShadow      = {};
M
Mr.doob 已提交
147

M
Mikael Emtinger 已提交
148 149 150
		_stencilShadow.vertices = new Float32Array( 12 );
		_stencilShadow.faces    = new Uint16Array( 6 );
		_stencilShadow.darkness = 0.5;
M
Mr.doob 已提交
151

152 153 154 155
		_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 已提交
156

M
Mikael Emtinger 已提交
157 158
		_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 已提交
159

M
Mikael Emtinger 已提交
160 161
		_stencilShadow.vertexBuffer  = _gl.createBuffer();
		_stencilShadow.elementBuffer = _gl.createBuffer();
M
Mr.doob 已提交
162

M
Mikael Emtinger 已提交
163 164
		_gl.bindBuffer( _gl.ARRAY_BUFFER, _stencilShadow.vertexBuffer );
		_gl.bufferData( _gl.ARRAY_BUFFER,  _stencilShadow.vertices, _gl.STATIC_DRAW );
M
Mr.doob 已提交
165

M
Mikael Emtinger 已提交
166 167
		_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _stencilShadow.elementBuffer );
		_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, _stencilShadow.faces, _gl.STATIC_DRAW );
M
Mr.doob 已提交
168

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

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

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

M
Mikael Emtinger 已提交
176 177 178 179
		_stencilShadow.vertexLocation     = _gl.getAttribLocation ( _stencilShadow.program, "position"         );
		_stencilShadow.projectionLocation = _gl.getUniformLocation( _stencilShadow.program, "projectionMatrix" );
		_stencilShadow.darknessLocation   = _gl.getUniformLocation( _stencilShadow.program, "darkness"         );
	}
M
Mr.doob 已提交
180 181


M
Mikael Emtinger 已提交
182
	// prepare lens flare
M
Mr.doob 已提交
183

M
Mikael Emtinger 已提交
184 185
	var _lensFlare = {};
	var i;
M
Mr.doob 已提交
186

M
Mikael Emtinger 已提交
187 188
	_lensFlare.vertices     = new Float32Array( 8 + 8 );
	_lensFlare.faces        = new Uint16Array( 6 );
M
Mr.doob 已提交
189

M
Mikael Emtinger 已提交
190 191 192 193 194 195 196 197 198 199 200 201 202 203
	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;

204 205 206 207
	_lensFlare.vertexBuffer     = _gl.createBuffer();
	_lensFlare.elementBuffer    = _gl.createBuffer();
	_lensFlare.tempTexture      = _gl.createTexture();
	_lensFlare.occlusionTexture = _gl.createTexture();
M
Mr.doob 已提交
208

M
Mikael Emtinger 已提交
209 210
	_gl.bindBuffer( _gl.ARRAY_BUFFER, _lensFlare.vertexBuffer );
	_gl.bufferData( _gl.ARRAY_BUFFER,  _lensFlare.vertices, _gl.STATIC_DRAW );
M
Mikael Emtinger 已提交
211

M
Mikael Emtinger 已提交
212 213 214 215 216 217 218 219 220 221
	_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 );

222 223 224 225 226 227 228 229
	_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 ) {
230

231 232 233 234 235 236 237
		_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 );

238

239 240 241
	} else {

		_lensFlare.hasVertexTexture = true;
242

243 244 245 246
		_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 );
247

248
	}
M
Mikael Emtinger 已提交
249 250 251 252 253

	_lensFlare.attributes = {};
	_lensFlare.uniforms = {};
	_lensFlare.attributes.vertex       = _gl.getAttribLocation ( _lensFlare.program, "position" );
	_lensFlare.attributes.uv           = _gl.getAttribLocation ( _lensFlare.program, "UV" );
254
	_lensFlare.uniforms.renderType     = _gl.getUniformLocation( _lensFlare.program, "renderType" );
M
Mikael Emtinger 已提交
255
	_lensFlare.uniforms.map            = _gl.getUniformLocation( _lensFlare.program, "map" );
256
	_lensFlare.uniforms.occlusionMap   = _gl.getUniformLocation( _lensFlare.program, "occlusionMap" );
M
Mikael Emtinger 已提交
257 258 259 260 261
	_lensFlare.uniforms.opacity        = _gl.getUniformLocation( _lensFlare.program, "opacity" );
	_lensFlare.uniforms.scale          = _gl.getUniformLocation( _lensFlare.program, "scale" );
	_lensFlare.uniforms.rotation       = _gl.getUniformLocation( _lensFlare.program, "rotation" );
	_lensFlare.uniforms.screenPosition = _gl.getUniformLocation( _lensFlare.program, "screenPosition" );

M
Mr.doob 已提交
262 263
	//_gl.enableVertexAttribArray( _lensFlare.attributes.vertex );
	//_gl.enableVertexAttribArray( _lensFlare.attributes.uv );
264

M
Mr.doob 已提交
265
	var _lensFlareAttributesEnabled = false;
M
Mikael Emtinger 已提交
266

M
Mikael Emtinger 已提交
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304
	// 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 = {};
305 306 307 308 309 310 311 312 313 314 315 316 317 318
	_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 已提交
319

M
Mr.doob 已提交
320 321
	//_gl.enableVertexAttribArray( _sprite.attributes.position );
	//_gl.enableVertexAttribArray( _sprite.attributes.uv );
M
Mikael Emtinger 已提交
322

M
Mr.doob 已提交
323
	var _spriteAttributesEnabled = false;
M
Mikael Emtinger 已提交
324

N
Nicolas Garcia Belmonte 已提交
325 326 327 328
	this.setSize = function ( width, height ) {

		_canvas.width = width;
		_canvas.height = height;
329

330 331 332
		this.setViewport( 0, 0, _canvas.width, _canvas.height );

	};
N
Nicolas Garcia Belmonte 已提交
333

334
	this.setViewport = function ( x, y, width, height ) {
335

336 337
		_viewportX = x;
		_viewportY = y;
338

339 340
		_viewportWidth = width;
		_viewportHeight = height;
341

342
		_gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight );
343

N
Nicolas Garcia Belmonte 已提交
344
	};
345

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

348
		_gl.scissor( x, y, width, height );
349

350
	};
351

352
	this.enableScissorTest = function ( enable ) {
353

354 355 356 357
		if ( enable )
			_gl.enable( _gl.SCISSOR_TEST );
		else
			_gl.disable( _gl.SCISSOR_TEST );
358

359
	};
360

361
	this.enableDepthBufferWrite = function ( enable ) {
362

363
		_currentDepthMask = enable;
364 365 366
		_gl.depthMask( enable );

	};
367

368
	this.setClearColorHex = function ( hex, alpha ) {
369

370 371 372 373
		_clearColor.setHex( hex );
		_clearAlpha = alpha;

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

375
	};
A
alteredq 已提交
376

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

379 380 381 382
		_clearColor.copy( color );
		_clearAlpha = alpha;

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

	};
385

N
Nicolas Garcia Belmonte 已提交
386 387
	this.clear = function () {

M
Mikael Emtinger 已提交
388
		_gl.clear( _gl.COLOR_BUFFER_BIT | _gl.DEPTH_BUFFER_BIT | _gl.STENCIL_BUFFER_BIT );
N
Nicolas Garcia Belmonte 已提交
389 390 391

	};

M
Mikael Emtinger 已提交
392
	this.setStencilShadowDarkness = function( value ) {
393

M
Mikael Emtinger 已提交
394 395 396
		_stencilShadow.darkness = value;
	};

397
	this.getContext = function() {
398

399
		return _gl;
400

401 402
	}

M
Mr.doob 已提交
403

A
alteredq 已提交
404
	function setupLights ( program, lights ) {
405

406
		var l, ll, light, r = 0, g = 0, b = 0,
407
		color, position, intensity, distance,
M
Mr.doob 已提交
408

409
		zlights = _lights,
M
Mr.doob 已提交
410

411
		dcolors = zlights.directional.colors,
412
		dpositions = zlights.directional.positions,
413

414
		pcolors = zlights.point.colors,
415
		ppositions = zlights.point.positions,
416
		pdistances = zlights.point.distances,
417

418 419
		dlength = 0,
		plength = 0,
420

421 422
		doffset = 0,
		poffset = 0;
M
Mr.doob 已提交
423

424
		for ( l = 0, ll = lights.length; l < ll; l++ ) {
425

426
			light = lights[ l ];
427
			color = light.color;
428

429 430
			position = light.position;
			intensity = light.intensity;
431
			distance = light.distance;
432 433 434

			if ( light instanceof THREE.AmbientLight ) {

435 436 437
				r += color.r;
				g += color.g;
				b += color.b;
M
Mr.doob 已提交
438

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

441
				doffset = dlength * 3;
442

443
				dcolors[ doffset ] = color.r * intensity;
444 445
				dcolors[ doffset + 1 ] = color.g * intensity;
				dcolors[ doffset + 2 ] = color.b * intensity;
446

447
				dpositions[ doffset ] = position.x;
448 449
				dpositions[ doffset + 1 ] = position.y;
				dpositions[ doffset + 2 ] = position.z;
450

451
				dlength += 1;
M
Mr.doob 已提交
452

453 454
			} else if( light instanceof THREE.PointLight ) {

455
				poffset = plength * 3;
456

457
				pcolors[ poffset ] = color.r * intensity;
458 459
				pcolors[ poffset + 1 ] = color.g * intensity;
				pcolors[ poffset + 2 ] = color.b * intensity;
460

461
				ppositions[ poffset ] = position.x;
462 463
				ppositions[ poffset + 1 ] = position.y;
				ppositions[ poffset + 2 ] = position.z;
M
Mr.doob 已提交
464

465 466
				pdistances[ plength ] = distance;

467
				plength += 1;
M
Mr.doob 已提交
468

469 470 471
			}

		}
472

473 474
		// null eventual remains from removed lights
		// (this is to avoid if in shader)
475

476 477
		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 已提交
478

479 480
		zlights.point.length = plength;
		zlights.directional.length = dlength;
M
Mr.doob 已提交
481

482 483 484
		zlights.ambient[ 0 ] = r;
		zlights.ambient[ 1 ] = g;
		zlights.ambient[ 2 ] = b;
M
Mr.doob 已提交
485

486
	};
M
Mr.doob 已提交
487

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

490 491
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
M
Mr.doob 已提交
492

493
	};
M
Mr.doob 已提交
494

495
	function createLineBuffers( geometry ) {
M
Mr.doob 已提交
496

497 498
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
M
Mr.doob 已提交
499

500
	};
501

502
	function createRibbonBuffers( geometry ) {
A
alteredq 已提交
503

504 505
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
A
alteredq 已提交
506 507 508

	};

509
	function createMeshBuffers( geometryGroup ) {
M
Mr.doob 已提交
510

511 512 513 514 515 516
		geometryGroup.__webglVertexBuffer = _gl.createBuffer();
		geometryGroup.__webglNormalBuffer = _gl.createBuffer();
		geometryGroup.__webglTangentBuffer = _gl.createBuffer();
		geometryGroup.__webglColorBuffer = _gl.createBuffer();
		geometryGroup.__webglUVBuffer = _gl.createBuffer();
		geometryGroup.__webglUV2Buffer = _gl.createBuffer();
517

518 519 520 521 522 523 524 525 526
		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 ) {
527

528
			var m, ml;
529 530 531 532 533 534
			geometryGroup.__webglMorphTargetsBuffers = []; 

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

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

535 536 537
			}

		}
M
Mr.doob 已提交
538

539
	};
540

541
	function initLineBuffers ( geometry ) {
M
Mr.doob 已提交
542

543 544 545
		var nvertices = geometry.vertices.length;

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

548
		geometry.__webglLineCount = nvertices;
M
Mr.doob 已提交
549

550
	};
M
Mr.doob 已提交
551

552
	function initRibbonBuffers ( geometry ) {
A
alteredq 已提交
553 554 555 556 557 558

		var nvertices = geometry.vertices.length;

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

559
		geometry.__webglVertexCount = nvertices;
A
alteredq 已提交
560 561

	};
562

563
	function initParticleBuffers ( geometry ) {
564 565 566 567

		var nvertices = geometry.vertices.length;

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

570
		geometry.__sortArray = [];
571

572
		geometry.__webglParticleCount = nvertices;
573 574 575

	};

576
	function initMeshBuffers ( geometryGroup, object ) {
M
Mr.doob 已提交
577

M
Mikael Emtinger 已提交
578
		var f, fl, fi, face,
579
		m, ml, size,
580 581 582 583 584 585
		nvertices = 0, ntris = 0, nlines = 0,

		uvType,
		vertexColorType,
		normalType,
		materials,
586
		attribute,
587 588 589 590

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

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

594 595
			fi = chunk_faces[ f ];
			face = obj_faces[ fi ];
M
Mr.doob 已提交
596

597
			if ( face instanceof THREE.Face3 ) {
M
Mr.doob 已提交
598

599 600 601
				nvertices += 3;
				ntris += 1;
				nlines += 3;
M
Mr.doob 已提交
602

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

605 606
				nvertices += 4;
				ntris += 2;
607
				nlines += 4;
M
Mr.doob 已提交
608

609
			}
M
Mr.doob 已提交
610

611
		}
612 613 614

		materials = unrollGroupMaterials( geometryGroup, object );

615 616
		uvType = bufferGuessUVType( materials, geometryGroup, object );
		normalType = bufferGuessNormalType( materials, geometryGroup, object );
A
alteredq 已提交
617 618
		vertexColorType = bufferGuessVertexColorType( materials, geometryGroup, object );

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

621
		geometryGroup.__vertexArray = new Float32Array( nvertices * 3 );
622

623
		if ( normalType ) {
M
Mr.doob 已提交
624

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

627
		}
628

629
		if ( geometry.hasTangents ) {
630

631
			geometryGroup.__tangentArray = new Float32Array( nvertices * 4 );
632

633
		}
634

635
		if ( vertexColorType ) {
636

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

639
		}
M
Mr.doob 已提交
640

641
		if ( uvType ) {
642

643
			if ( geometry.faceUvs.length > 0 || geometry.faceVertexUvs.length > 0 ) {
644

645 646 647 648 649
				geometryGroup.__uvArray = new Float32Array( nvertices * 2 );

			}

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

651 652 653 654 655 656 657 658 659 660 661 662 663 664 665
				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 已提交
666
		geometryGroup.__faceArray = new Uint16Array( ntris * 3 + ( object.geometry.edgeFaces ? object.geometry.edgeFaces.length * 2 * 3 : 0 ));
667
		geometryGroup.__lineArray = new Uint16Array( nlines * 2 );
M
Mr.doob 已提交
668

669 670
		if ( geometryGroup.numMorphTargets ) {

671
			geometryGroup.__morphTargetsArrays = []; 
672 673 674

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

675 676
				geometryGroup.__morphTargetsArrays.push( new Float32Array( nvertices * 3 ) );

677 678 679
			}

		}
680

681
		geometryGroup.__needsSmoothNormals = ( normalType == THREE.SmoothShading );
682

683 684 685 686
		geometryGroup.__uvType = uvType;
		geometryGroup.__vertexColorType = vertexColorType;
		geometryGroup.__normalType = normalType;

687 688
		geometryGroup.__webglFaceCount = ntris * 3 + ( object.geometry.edgeFaces ? object.geometry.edgeFaces.length * 2 * 3 : 0 );
		geometryGroup.__webglLineCount = nlines * 2;
689

M
Mr.doob 已提交
690

691
		// custom attributes
M
Mr.doob 已提交
692 693 694 695 696

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

			if ( materials[ m ].attributes ) {

697 698
				geometryGroup.__webglCustomAttributes = {};

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

701 702 703 704 705 706
                    // Do a shallow copy of the attribute object so different geometryGroup chunks use different
                    // attribute buffers which are correctly indexed in the setMeshBuffers function
					attribute = {};
					for (prop in materials[ m ].attributes[ a ] ) {
						attribute [ prop ] = materials[ m ].attributes[ a ][ prop ];
					}
M
Mr.doob 已提交
707

708
					if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
709

710
						attribute.__webglInitialized = true;
711

712
						size = 1;		// "f" and "i"
713

714 715 716 717
						if( attribute.type === "v2" ) size = 2;
						else if( attribute.type === "v3" ) size = 3;
						else if( attribute.type === "v4" ) size = 4;
						else if( attribute.type === "c"  ) size = 3;
718

719 720 721 722
						attribute.size = size;
						attribute.needsUpdate = true;
						attribute.array = new Float32Array( nvertices * size );
						attribute.buffer = _gl.createBuffer();
723
						attribute.buffer.belongsToAttribute = a;
724

725
					}
726 727 728 729 730 731

					geometryGroup.__webglCustomAttributes[ a ] = attribute;

				}

			}
M
Mr.doob 已提交
732

733
		}
734

735 736
		geometryGroup.__inittedArrays = true;

737
	};
M
Mr.doob 已提交
738

739

740
	function setMeshBuffers ( geometryGroup, object, hint ) {
741

742 743 744 745 746 747 748
		if ( ! geometryGroup.__inittedArrays ) {

			// console.log( object );
			return;

		}

M
Mr.doob 已提交
749
		var f, fl, fi, face,
750 751 752 753 754 755 756 757 758 759 760 761 762
		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,
763
		a,
M
Mr.doob 已提交
764

765
		vertexIndex = 0,
766

767 768
		offset = 0,
		offset_uv = 0,
769
		offset_uv2 = 0,
770 771 772 773
		offset_face = 0,
		offset_normal = 0,
		offset_tangent = 0,
		offset_line = 0,
774
		offset_color = 0,
A
alteredq 已提交
775
		offset_skin = 0,
776
		offset_morphTarget = 0,
777
		offset_custom = 0,
778
		offset_customSrc = 0,
M
Mr.doob 已提交
779

780 781 782 783 784 785
		vertexArray = geometryGroup.__vertexArray,
		uvArray = geometryGroup.__uvArray,
		uv2Array = geometryGroup.__uv2Array,
		normalArray = geometryGroup.__normalArray,
		tangentArray = geometryGroup.__tangentArray,
		colorArray = geometryGroup.__colorArray,
786

787 788 789 790
		skinVertexAArray = geometryGroup.__skinVertexAArray,
		skinVertexBArray = geometryGroup.__skinVertexBArray,
		skinIndexArray = geometryGroup.__skinIndexArray,
		skinWeightArray = geometryGroup.__skinWeightArray,
M
Mr.doob 已提交
791

792 793
		morphTargetsArrays = geometryGroup.__morphTargetsArrays,

794 795
		customAttributes = geometryGroup.__webglCustomAttributes,
		customAttribute,
796

797 798
		faceArray = geometryGroup.__faceArray,
		lineArray = geometryGroup.__lineArray,
M
Mr.doob 已提交
799

800
		needsSmoothNormals = geometryGroup.__needsSmoothNormals,
801

802
		vertexColorType = geometryGroup.__vertexColorType,
A
alteredq 已提交
803 804
		uvType = geometryGroup.__uvType,
		normalType = geometryGroup.__normalType,
805

806
		geometry = object.geometry, // this is shared for all chunks
807

808
		dirtyVertices = geometry.__dirtyVertices,
809 810 811
		dirtyElements = geometry.__dirtyElements,
		dirtyUvs = geometry.__dirtyUvs,
		dirtyNormals = geometry.__dirtyNormals,
812
		dirtyTangents = geometry.__dirtyTangents,
813
		dirtyColors = geometry.__dirtyColors,
814
		dirtyMorphTargets = geometry.__dirtyMorphTargets,
M
Mr.doob 已提交
815

816
		vertices = geometry.vertices,
817
		chunk_faces = geometryGroup.faces,
818
		obj_faces = geometry.faces,
819

820 821
		obj_uvs  = geometry.faceVertexUvs[ 0 ],
		obj_uvs2 = geometry.faceVertexUvs[ 1 ],
822

A
alteredq 已提交
823
		obj_colors = geometry.colors,
824

A
alteredq 已提交
825 826 827
		obj_skinVerticesA = geometry.skinVerticesA,
		obj_skinVerticesB = geometry.skinVerticesB,
		obj_skinIndices = geometry.skinIndices,
828
		obj_skinWeights = geometry.skinWeights,
829
		obj_edgeFaces = object instanceof THREE.ShadowVolume ? geometry.edgeFaces : undefined;
830 831

		morphTargets = geometry.morphTargets;
832

833
		if ( customAttributes ) {
M
Mr.doob 已提交
834

835
			for ( a in customAttributes ) {
M
Mr.doob 已提交
836

837
				customAttributes[ a ].offset = 0;
838
				customAttributes[ a ].offsetSrc = 0;
M
Mr.doob 已提交
839

840 841
			}

M
Mr.doob 已提交
842
		}
843 844


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

847 848
			fi = chunk_faces[ f ];
			face = obj_faces[ fi ];
849 850

			if ( obj_uvs ) {
A
alteredq 已提交
851 852 853 854

				uv = obj_uvs[ fi ];

			}
855 856 857

			if ( obj_uvs2 ) {

A
alteredq 已提交
858 859 860
				uv2 = obj_uvs2[ fi ];

			}
M
Mr.doob 已提交
861

862
			vertexNormals = face.vertexNormals;
863
			faceNormal = face.normal;
864

865 866
			vertexColors = face.vertexColors;
			faceColor = face.color;
867

868
			vertexTangents = face.vertexTangents;
869 870 871

			if ( face instanceof THREE.Face3 ) {

872
				if ( dirtyVertices ) {
M
Mr.doob 已提交
873

874 875 876
					v1 = vertices[ face.a ].position;
					v2 = vertices[ face.b ].position;
					v3 = vertices[ face.c ].position;
M
Mr.doob 已提交
877

878 879 880
					vertexArray[ offset ]     = v1.x;
					vertexArray[ offset + 1 ] = v1.y;
					vertexArray[ offset + 2 ] = v1.z;
M
Mr.doob 已提交
881

882 883 884
					vertexArray[ offset + 3 ] = v2.x;
					vertexArray[ offset + 4 ] = v2.y;
					vertexArray[ offset + 5 ] = v2.z;
885

886 887 888
					vertexArray[ offset + 6 ] = v3.x;
					vertexArray[ offset + 7 ] = v3.y;
					vertexArray[ offset + 8 ] = v3.z;
M
Mr.doob 已提交
889

890
					offset += 9;
M
Mr.doob 已提交
891

892
				}
893

894
				if ( customAttributes ) {
M
Mr.doob 已提交
895

896
					for ( a in customAttributes ) {
M
Mr.doob 已提交
897

898 899
						customAttribute = customAttributes[ a ];

M
Mr.doob 已提交
900 901
						if ( customAttribute.needsUpdate ) {

902
							offset_custom = customAttribute.offset;
903
							offset_customSrc = customAttribute.offsetSrc;
M
Mr.doob 已提交
904

905 906 907
							if ( customAttribute.size === 1 ) {

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

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

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

915 916 917 918
									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 ];

919 920 921 922
									customAttribute.offsetSrc ++;

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

923 924 925
									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 ];
926

927
									customAttribute.offsetSrc += 3;
928

929
								}
M
Mr.doob 已提交
930

931
								customAttribute.offset += 3;
M
Mr.doob 已提交
932

933
							} else {
M
Mr.doob 已提交
934

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

937 938 939
									v1 = customAttribute.value[ face.a ];
									v2 = customAttribute.value[ face.b ];
									v3 = customAttribute.value[ face.c ];
940 941 942

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

943 944 945 946
									v1 = customAttribute.value[ offset_customSrc ];
									v2 = customAttribute.value[ offset_customSrc ];
									v3 = customAttribute.value[ offset_customSrc ];

947 948 949 950
									customAttribute.offsetSrc ++;

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

951 952 953
									v1 = customAttribute.value[ offset_customSrc + 0 ];
									v2 = customAttribute.value[ offset_customSrc + 1 ];
									v3 = customAttribute.value[ offset_customSrc + 2 ];
954

955 956
									customAttribute.offsetSrc += 3;
								}
M
Mr.doob 已提交
957

958 959

								if ( customAttribute.size === 2 ) {
M
Mr.doob 已提交
960 961 962

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

M
Mr.doob 已提交
964 965
									customAttribute.array[ offset_custom + 2 ] = v2.x;
									customAttribute.array[ offset_custom + 3 ] = v2.y;
966

M
Mr.doob 已提交
967
									customAttribute.array[ offset_custom + 4 ] = v3.x;
968
									customAttribute.array[ offset_custom + 5 ] = v3.y;
M
Mr.doob 已提交
969

970
									customAttribute.offset += 6;
M
Mr.doob 已提交
971

972 973 974
								} else if ( customAttribute.size === 3 ) {

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

976 977 978
										customAttribute.array[ offset_custom + 0 ] = v1.r;
										customAttribute.array[ offset_custom + 1 ] = v1.g;
										customAttribute.array[ offset_custom + 2 ] = v1.b;
979

980 981 982
										customAttribute.array[ offset_custom + 3 ] = v2.r;
										customAttribute.array[ offset_custom + 4 ] = v2.g;
										customAttribute.array[ offset_custom + 5 ] = v2.b;
983

984 985 986
										customAttribute.array[ offset_custom + 6 ] = v3.r;
										customAttribute.array[ offset_custom + 7 ] = v3.g;
										customAttribute.array[ offset_custom + 8 ] = v3.b;
987

988
									} else {
989

990 991 992
										customAttribute.array[ offset_custom + 0 ] = v1.x;
										customAttribute.array[ offset_custom + 1 ] = v1.y;
										customAttribute.array[ offset_custom + 2 ] = v1.z;
993

994 995 996
										customAttribute.array[ offset_custom + 3 ] = v2.x;
										customAttribute.array[ offset_custom + 4 ] = v2.y;
										customAttribute.array[ offset_custom + 5 ] = v2.z;
997

998 999 1000
										customAttribute.array[ offset_custom + 6 ] = v3.x;
										customAttribute.array[ offset_custom + 7 ] = v3.y;
										customAttribute.array[ offset_custom + 8 ] = v3.z;
1001

1002
									}
M
Mr.doob 已提交
1003

1004
									customAttribute.offset += 9;
M
Mr.doob 已提交
1005

1006
								} else {
M
Mr.doob 已提交
1007 1008 1009 1010 1011

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

M
Mr.doob 已提交
1013 1014 1015 1016
									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;
1017

M
Mr.doob 已提交
1018
									customAttribute.array[ offset_custom + 8  ] = v3.x;
1019 1020 1021
									customAttribute.array[ offset_custom + 9  ] = v3.y;
									customAttribute.array[ offset_custom + 10 ] = v3.z;
									customAttribute.array[ offset_custom + 11 ] = v3.w;
M
Mr.doob 已提交
1022

1023
									customAttribute.offset += 12;
M
Mr.doob 已提交
1024

1025
								}
M
Mr.doob 已提交
1026

1027
							}
M
Mr.doob 已提交
1028

1029
						}
M
Mr.doob 已提交
1030

1031
					}
M
Mr.doob 已提交
1032

1033 1034 1035
				}


1036
				if ( dirtyMorphTargets ) {
1037 1038 1039

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

1040 1041 1042
						v1 = morphTargets[ vk ].vertices[ face.a ].position;
						v2 = morphTargets[ vk ].vertices[ face.b ].position;
						v3 = morphTargets[ vk ].vertices[ face.c ].position;
1043

1044
						vka = morphTargetsArrays[ vk ];
1045

1046 1047 1048
						vka[ offset_morphTarget + 0 ] = v1.x;
						vka[ offset_morphTarget + 1 ] = v1.y;
						vka[ offset_morphTarget + 2 ] = v1.z;
1049

1050 1051 1052
						vka[ offset_morphTarget + 3 ] = v2.x;
						vka[ offset_morphTarget + 4 ] = v2.y;
						vka[ offset_morphTarget + 5 ] = v2.z;
1053

1054 1055 1056
						vka[ offset_morphTarget + 6 ] = v3.x;
						vka[ offset_morphTarget + 7 ] = v3.y;
						vka[ offset_morphTarget + 8 ] = v3.z;
1057 1058
					}

1059
					offset_morphTarget += 9;
1060

1061 1062
				}

A
alteredq 已提交
1063 1064 1065
				if ( obj_skinWeights.length ) {

					// weights
1066

A
alteredq 已提交
1067 1068 1069
					sw1 = obj_skinWeights[ face.a ];
					sw2 = obj_skinWeights[ face.b ];
					sw3 = obj_skinWeights[ face.c ];
1070

A
alteredq 已提交
1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086
					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
1087

A
alteredq 已提交
1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107
					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
1108

A
alteredq 已提交
1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128
					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
1129

A
alteredq 已提交
1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149
					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;
1150

A
alteredq 已提交
1151
				}
1152

1153 1154 1155
				if ( dirtyColors && vertexColorType ) {

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

1157 1158 1159 1160 1161
						c1 = vertexColors[ 0 ];
						c2 = vertexColors[ 1 ];
						c3 = vertexColors[ 2 ];

					} else {
1162

1163 1164 1165 1166 1167
						c1 = faceColor;
						c2 = faceColor;
						c3 = faceColor;

					}
1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179

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

1181 1182 1183 1184
					offset_color += 9;

				}

1185
				if ( dirtyTangents && geometry.hasTangents ) {
1186

1187 1188 1189
					t1 = vertexTangents[ 0 ];
					t2 = vertexTangents[ 1 ];
					t3 = vertexTangents[ 2 ];
1190

1191 1192 1193 1194
					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 已提交
1195

1196 1197 1198 1199
					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 已提交
1200

1201 1202 1203 1204
					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 已提交
1205

1206
					offset_tangent += 12;
M
Mr.doob 已提交
1207

1208 1209
				}

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

1212 1213 1214
					if ( vertexNormals.length == 3 && needsSmoothNormals ) {

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

1216
							vn = vertexNormals[ i ];
M
Mr.doob 已提交
1217

1218 1219 1220
							normalArray[ offset_normal ]     = vn.x;
							normalArray[ offset_normal + 1 ] = vn.y;
							normalArray[ offset_normal + 2 ] = vn.z;
M
Mr.doob 已提交
1221

1222
							offset_normal += 3;
M
Mr.doob 已提交
1223

1224
						}
M
Mr.doob 已提交
1225

1226
					} else {
1227

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

1230 1231 1232
							normalArray[ offset_normal ]     = faceNormal.x;
							normalArray[ offset_normal + 1 ] = faceNormal.y;
							normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
1233

1234
							offset_normal += 3;
M
Mr.doob 已提交
1235

1236
						}
M
Mr.doob 已提交
1237 1238

					}
M
Mr.doob 已提交
1239

1240 1241
				}

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

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

1246
						uvi = uv[ i ];
M
Mr.doob 已提交
1247

1248 1249
						uvArray[ offset_uv ]     = uvi.u;
						uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
1250

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

M
Mr.doob 已提交
1253
					}
1254 1255 1256

				}

A
alteredq 已提交
1257
				if ( dirtyUvs && uv2 !== undefined && uvType ) {
1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271

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

						uv2i = uv2[ i ];

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

						offset_uv2 += 2;

					}

				}

1272
				if ( dirtyElements ) {
M
Mr.doob 已提交
1273

1274 1275 1276
					faceArray[ offset_face ] = vertexIndex;
					faceArray[ offset_face + 1 ] = vertexIndex + 1;
					faceArray[ offset_face + 2 ] = vertexIndex + 2;
M
Mr.doob 已提交
1277

1278
					offset_face += 3;
M
Mr.doob 已提交
1279

1280 1281
					lineArray[ offset_line ]     = vertexIndex;
					lineArray[ offset_line + 1 ] = vertexIndex + 1;
M
Mr.doob 已提交
1282

1283 1284
					lineArray[ offset_line + 2 ] = vertexIndex;
					lineArray[ offset_line + 3 ] = vertexIndex + 2;
M
Mr.doob 已提交
1285

1286 1287
					lineArray[ offset_line + 4 ] = vertexIndex + 1;
					lineArray[ offset_line + 5 ] = vertexIndex + 2;
M
Mr.doob 已提交
1288

1289
					offset_line += 6;
1290

1291
					vertexIndex += 3;
M
Mr.doob 已提交
1292

1293
				}
M
Mr.doob 已提交
1294

1295 1296 1297

			} else if ( face instanceof THREE.Face4 ) {

1298
				if ( dirtyVertices ) {
M
Mr.doob 已提交
1299

1300 1301 1302 1303
					v1 = vertices[ face.a ].position;
					v2 = vertices[ face.b ].position;
					v3 = vertices[ face.c ].position;
					v4 = vertices[ face.d ].position;
M
Mr.doob 已提交
1304

1305 1306 1307
					vertexArray[ offset ]     = v1.x;
					vertexArray[ offset + 1 ] = v1.y;
					vertexArray[ offset + 2 ] = v1.z;
M
Mr.doob 已提交
1308

1309 1310 1311
					vertexArray[ offset + 3 ] = v2.x;
					vertexArray[ offset + 4 ] = v2.y;
					vertexArray[ offset + 5 ] = v2.z;
1312

1313 1314 1315
					vertexArray[ offset + 6 ] = v3.x;
					vertexArray[ offset + 7 ] = v3.y;
					vertexArray[ offset + 8 ] = v3.z;
1316

1317
					vertexArray[ offset + 9 ]  = v4.x;
1318 1319
					vertexArray[ offset + 10 ] = v4.y;
					vertexArray[ offset + 11 ] = v4.z;
M
Mr.doob 已提交
1320

1321
					offset += 12;
M
Mr.doob 已提交
1322

1323
				}
1324

1325
				if ( customAttributes ) {
M
Mr.doob 已提交
1326

1327
					for ( a in customAttributes ) {
M
Mr.doob 已提交
1328

1329 1330
						customAttribute = customAttributes[ a ];

M
Mr.doob 已提交
1331
						if ( customAttribute.needsUpdate ) {
1332 1333

							offset_custom = customAttribute.offset;
1334
							offset_customSrc = customAttribute.offsetSrc;
M
Mr.doob 已提交
1335

1336 1337 1338
							if ( customAttribute.size === 1 ) {

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

1340 1341 1342
									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 ];
A
alteredq 已提交
1343
									customAttribute.array[ offset_custom + 3 ] = customAttribute.value[ face.d ];
1344 1345 1346

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

1347 1348 1349
									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 ];
A
alteredq 已提交
1350
									customAttribute.array[ offset_custom + 3 ] = customAttribute.value[ offset_customSrc ];
1351 1352

									customAttribute.offsetSrc++;
1353 1354 1355

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

1356 1357 1358
									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 ];
A
alteredq 已提交
1359
									customAttribute.array[ offset_custom + 3 ] = customAttribute.value[ offset_customSrc + 3 ];
1360

1361 1362
									customAttribute.offsetSrc += 4;
								}
M
Mr.doob 已提交
1363

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

1366
							} else {
M
Mr.doob 已提交
1367

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

1370 1371 1372 1373
									v1 = customAttribute.value[ face.a ];
									v2 = customAttribute.value[ face.b ];
									v3 = customAttribute.value[ face.c ];
									v4 = customAttribute.value[ face.d ];
1374 1375 1376

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

1377 1378 1379 1380 1381 1382
									v1 = customAttribute.value[ offset_customSrc ];
									v2 = customAttribute.value[ offset_customSrc ];
									v3 = customAttribute.value[ offset_customSrc ];
									v4 = customAttribute.value[ offset_customSrc ];

									customAttribute.offsetSrc++;
1383 1384 1385

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

1386 1387 1388 1389
									v1 = customAttribute.value[ offset_customSrc + 0 ];
									v2 = customAttribute.value[ offset_customSrc + 1 ];
									v3 = customAttribute.value[ offset_customSrc + 2 ];
									v4 = customAttribute.value[ offset_customSrc + 3 ];
1390

1391 1392 1393
									customAttribute.offsetSrc += 4;
								}

M
Mr.doob 已提交
1394

1395
								if ( customAttribute.size === 2 ) {
M
Mr.doob 已提交
1396 1397 1398

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

M
Mr.doob 已提交
1400 1401
									customAttribute.array[ offset_custom + 2 ] = v2.x;
									customAttribute.array[ offset_custom + 3 ] = v2.y;
1402

M
Mr.doob 已提交
1403
									customAttribute.array[ offset_custom + 4 ] = v3.x;
1404
									customAttribute.array[ offset_custom + 5 ] = v3.y;
1405

M
Mr.doob 已提交
1406
									customAttribute.array[ offset_custom + 6 ] = v4.x;
1407
									customAttribute.array[ offset_custom + 7 ] = v4.y;
M
Mr.doob 已提交
1408

1409
									customAttribute.offset += 8;
M
Mr.doob 已提交
1410

1411 1412 1413
								} else if ( customAttribute.size === 3 ) {

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

1415 1416 1417
										customAttribute.array[ offset_custom + 0  ] = v1.r;
										customAttribute.array[ offset_custom + 1  ] = v1.g;
										customAttribute.array[ offset_custom + 2  ] = v1.b;
1418

1419 1420 1421
										customAttribute.array[ offset_custom + 3  ] = v2.r;
										customAttribute.array[ offset_custom + 4  ] = v2.g;
										customAttribute.array[ offset_custom + 5  ] = v2.b;
1422

1423 1424 1425
										customAttribute.array[ offset_custom + 6  ] = v3.r;
										customAttribute.array[ offset_custom + 7  ] = v3.g;
										customAttribute.array[ offset_custom + 8  ] = v3.b;
1426

1427 1428 1429 1430 1431
										customAttribute.array[ offset_custom + 9  ] = v4.r;
										customAttribute.array[ offset_custom + 10 ] = v4.g;
										customAttribute.array[ offset_custom + 11 ] = v4.b;

									} else {
1432

1433 1434 1435
										customAttribute.array[ offset_custom + 0  ] = v1.x;
										customAttribute.array[ offset_custom + 1  ] = v1.y;
										customAttribute.array[ offset_custom + 2  ] = v1.z;
1436

1437 1438 1439
										customAttribute.array[ offset_custom + 3  ] = v2.x;
										customAttribute.array[ offset_custom + 4  ] = v2.y;
										customAttribute.array[ offset_custom + 5  ] = v2.z;
1440

1441 1442 1443
										customAttribute.array[ offset_custom + 6  ] = v3.x;
										customAttribute.array[ offset_custom + 7  ] = v3.y;
										customAttribute.array[ offset_custom + 8  ] = v3.z;
1444

1445 1446 1447
										customAttribute.array[ offset_custom + 9  ] = v4.x;
										customAttribute.array[ offset_custom + 10 ] = v4.y;
										customAttribute.array[ offset_custom + 11 ] = v4.z;
1448

1449
									}
M
Mr.doob 已提交
1450

1451
									customAttribute.offset += 12;
M
Mr.doob 已提交
1452

1453
								} else {
M
Mr.doob 已提交
1454 1455 1456 1457 1458

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

M
Mr.doob 已提交
1460 1461 1462 1463
									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;
1464

M
Mr.doob 已提交
1465
									customAttribute.array[ offset_custom + 8  ] = v3.x;
1466 1467 1468
									customAttribute.array[ offset_custom + 9  ] = v3.y;
									customAttribute.array[ offset_custom + 10 ] = v3.z;
									customAttribute.array[ offset_custom + 11 ] = v3.w;
1469

M
Mr.doob 已提交
1470
									customAttribute.array[ offset_custom + 12 ] = v4.x;
1471 1472 1473
									customAttribute.array[ offset_custom + 13 ] = v4.y;
									customAttribute.array[ offset_custom + 14 ] = v4.z;
									customAttribute.array[ offset_custom + 15 ] = v4.w;
M
Mr.doob 已提交
1474

1475
									customAttribute.offset += 16;
M
Mr.doob 已提交
1476

1477
								}
M
Mr.doob 已提交
1478

1479
							}
M
Mr.doob 已提交
1480

1481
						}
M
Mr.doob 已提交
1482

1483
					}
M
Mr.doob 已提交
1484

1485 1486 1487
				}


1488
				if ( dirtyMorphTargets ) {
1489 1490 1491

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

1492 1493 1494 1495
						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;
1496

1497
						vka = morphTargetsArrays[ vk ];
1498

1499 1500 1501
						vka[ offset_morphTarget + 0 ] = v1.x;
						vka[ offset_morphTarget + 1 ] = v1.y;
						vka[ offset_morphTarget + 2 ] = v1.z;
1502

1503 1504 1505
						vka[ offset_morphTarget + 3 ] = v2.x;
						vka[ offset_morphTarget + 4 ] = v2.y;
						vka[ offset_morphTarget + 5 ] = v2.z;
1506

1507 1508 1509
						vka[ offset_morphTarget + 6 ] = v3.x;
						vka[ offset_morphTarget + 7 ] = v3.y;
						vka[ offset_morphTarget + 8 ] = v3.z;
1510

1511 1512 1513
						vka[ offset_morphTarget + 9 ] = v4.x;
						vka[ offset_morphTarget + 10 ] = v4.y;
						vka[ offset_morphTarget + 11 ] = v4.z;
1514 1515
					}

1516
					offset_morphTarget += 12;
1517

1518 1519
				}

A
alteredq 已提交
1520 1521 1522
				if ( obj_skinWeights.length ) {

					// weights
1523

A
alteredq 已提交
1524 1525 1526 1527
					sw1 = obj_skinWeights[ face.a ];
					sw2 = obj_skinWeights[ face.b ];
					sw3 = obj_skinWeights[ face.c ];
					sw4 = obj_skinWeights[ face.d ];
1528

A
alteredq 已提交
1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549
					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
1550

A
alteredq 已提交
1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576
					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
1577

A
alteredq 已提交
1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603
					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
1604

A
alteredq 已提交
1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624
					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;

1625 1626
					skinVertexBArray[ offset_skin + 12 ] = sb4.x;
					skinVertexBArray[ offset_skin + 13 ] = sb4.y;
A
alteredq 已提交
1627 1628 1629
					skinVertexBArray[ offset_skin + 14 ] = sb4.z;
					skinVertexBArray[ offset_skin + 15 ] = 1;

1630 1631
					offset_skin += 16;

A
alteredq 已提交
1632
				}
1633

1634 1635 1636
				if ( dirtyColors && vertexColorType ) {

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

1638 1639 1640 1641 1642 1643
						c1 = vertexColors[ 0 ];
						c2 = vertexColors[ 1 ];
						c3 = vertexColors[ 2 ];
						c4 = vertexColors[ 3 ];

					} else {
1644

1645 1646 1647 1648 1649 1650
						c1 = faceColor;
						c2 = faceColor;
						c3 = faceColor;
						c4 = faceColor;

					}
1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662

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

1664 1665 1666
					colorArray[ offset_color + 9 ]  = c4.r;
					colorArray[ offset_color + 10 ] = c4.g;
					colorArray[ offset_color + 11 ] = c4.b;
1667

1668 1669
					offset_color += 12;

1670 1671
				}

1672
				if ( dirtyTangents && geometry.hasTangents ) {
1673

1674 1675 1676 1677
					t1 = vertexTangents[ 0 ];
					t2 = vertexTangents[ 1 ];
					t3 = vertexTangents[ 2 ];
					t4 = vertexTangents[ 3 ];
1678

1679 1680 1681 1682
					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 已提交
1683

1684 1685 1686 1687
					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 已提交
1688

1689 1690
					tangentArray[ offset_tangent + 8 ]  = t3.x;
					tangentArray[ offset_tangent + 9 ]  = t3.y;
1691 1692
					tangentArray[ offset_tangent + 10 ] = t3.z;
					tangentArray[ offset_tangent + 11 ] = t3.w;
M
Mr.doob 已提交
1693

1694 1695 1696 1697
					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 已提交
1698

1699
					offset_tangent += 16;
M
Mr.doob 已提交
1700

1701
				}
M
Mr.doob 已提交
1702

M
Mr.doob 已提交
1703
				if ( dirtyNormals && normalType ) {
M
Mr.doob 已提交
1704

1705
					if ( vertexNormals.length == 4 && needsSmoothNormals ) {
1706

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

1709
							vn = vertexNormals[ i ];
M
Mr.doob 已提交
1710

1711 1712 1713
							normalArray[ offset_normal ]     = vn.x;
							normalArray[ offset_normal + 1 ] = vn.y;
							normalArray[ offset_normal + 2 ] = vn.z;
M
Mr.doob 已提交
1714

1715
							offset_normal += 3;
M
Mr.doob 已提交
1716

1717
						}
M
Mr.doob 已提交
1718

1719
					} else {
1720

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

1723 1724 1725
							normalArray[ offset_normal ]     = faceNormal.x;
							normalArray[ offset_normal + 1 ] = faceNormal.y;
							normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
1726

1727
							offset_normal += 3;
M
Mr.doob 已提交
1728

1729
						}
M
Mr.doob 已提交
1730 1731

					}
M
Mr.doob 已提交
1732

1733 1734
				}

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

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

1739
						uvi = uv[ i ];
M
Mr.doob 已提交
1740

1741 1742
						uvArray[ offset_uv ]     = uvi.u;
						uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
1743

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

M
Mr.doob 已提交
1746
					}
1747 1748

				}
1749

A
alteredq 已提交
1750
				if ( dirtyUvs && uv2 !== undefined && uvType ) {
1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763

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

1765
				if ( dirtyElements ) {
M
Mr.doob 已提交
1766

1767
					faceArray[ offset_face ]     = vertexIndex;
1768 1769
					faceArray[ offset_face + 1 ] = vertexIndex + 1;
					faceArray[ offset_face + 2 ] = vertexIndex + 3;
M
Mr.doob 已提交
1770

1771 1772 1773
					faceArray[ offset_face + 3 ] = vertexIndex + 1;
					faceArray[ offset_face + 4 ] = vertexIndex + 2;
					faceArray[ offset_face + 5 ] = vertexIndex + 3;
M
Mr.doob 已提交
1774

1775
					offset_face += 6;
M
Mr.doob 已提交
1776

1777 1778
					lineArray[ offset_line ]     = vertexIndex;
					lineArray[ offset_line + 1 ] = vertexIndex + 1;
M
Mr.doob 已提交
1779

1780
					lineArray[ offset_line + 2 ] = vertexIndex;
1781
					lineArray[ offset_line + 3 ] = vertexIndex + 3;
M
Mr.doob 已提交
1782

1783 1784
					lineArray[ offset_line + 4 ] = vertexIndex + 1;
					lineArray[ offset_line + 5 ] = vertexIndex + 2;
M
Mr.doob 已提交
1785

1786 1787
					lineArray[ offset_line + 6 ] = vertexIndex + 2;
					lineArray[ offset_line + 7 ] = vertexIndex + 3;
M
Mr.doob 已提交
1788

1789
					offset_line += 8;
M
Mr.doob 已提交
1790

1791
					vertexIndex += 4;
M
Mr.doob 已提交
1792

1793
				}
M
Mr.doob 已提交
1794

1795
			}
M
Mr.doob 已提交
1796

1797 1798
		}

1799 1800 1801 1802
		if ( obj_edgeFaces ) {

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

M
Mikael Emtinger 已提交
1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813
				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;
			}

1814
		}
M
Mikael Emtinger 已提交
1815

1816
		if ( dirtyVertices ) {
M
Mr.doob 已提交
1817

1818
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
1819
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
M
Mr.doob 已提交
1820

1821
		}
M
Mr.doob 已提交
1822

1823
		if ( customAttributes ) {
M
Mr.doob 已提交
1824

1825
			for ( a in customAttributes ) {
M
Mr.doob 已提交
1826

1827 1828
				customAttribute = customAttributes[ a ];

M
Mr.doob 已提交
1829
				if ( customAttribute.needsUpdate ) {
1830 1831 1832 1833

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

M
Mr.doob 已提交
1834
					customAttribute.needsUpdate = false;
1835

1836 1837 1838 1839 1840 1841
				}

			}

		}

1842
		if ( dirtyMorphTargets ) {
1843 1844 1845 1846

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

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

1849 1850 1851
			}
		}

1852
		if ( dirtyColors && offset_color > 0 ) {
1853

1854
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
1855 1856 1857
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}
1858

1859
		if ( dirtyNormals ) {
M
Mr.doob 已提交
1860

1861
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
1862
			_gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
M
Mr.doob 已提交
1863

1864 1865
		}

1866
		if ( dirtyTangents && geometry.hasTangents ) {
1867

1868
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
1869
			_gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint );
M
Mr.doob 已提交
1870

1871
		}
1872

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

1875
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
1876
			_gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
M
Mr.doob 已提交
1877

1878
		}
M
Mr.doob 已提交
1879

1880 1881
		if ( dirtyUvs && offset_uv2 > 0 ) {

1882
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
1883 1884 1885 1886
			_gl.bufferData( _gl.ARRAY_BUFFER, uv2Array, hint );

		}

1887
		if ( dirtyElements ) {
M
Mr.doob 已提交
1888

1889
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
1890
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint );
1891

1892
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
1893
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
M
Mr.doob 已提交
1894

1895
		}
1896

1897
		if ( offset_skin > 0 ) {
1898

1899
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
A
alteredq 已提交
1900 1901
			_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexAArray, hint );

1902
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
A
alteredq 已提交
1903 1904
			_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexBArray, hint );

1905
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
A
alteredq 已提交
1906 1907
			_gl.bufferData( _gl.ARRAY_BUFFER, skinIndexArray, hint );

1908
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
A
alteredq 已提交
1909
			_gl.bufferData( _gl.ARRAY_BUFFER, skinWeightArray, hint );
1910

A
alteredq 已提交
1911
		}
1912

1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929
		if ( ! object.dynamic ) {

			delete geometryGroup.__inittedArrays;
			delete geometryGroup.__colorArray;
			delete geometryGroup.__normalArray;
			delete geometryGroup.__tangentArray;
			delete geometryGroup.__uvArray;
			delete geometryGroup.__uv2Array;
			delete geometryGroup.__faceArray;
			delete geometryGroup.__vertexArray;
			delete geometryGroup.__lineArray;
			delete geometryGroup.__skinVertexAArray;
			delete geometryGroup.__skinVertexBArray;
			delete geometryGroup.__skinIndexArray;
			delete geometryGroup.__skinWeightArray;

		}
1930

1931
	};
1932

1933
	function setLineBuffers ( geometry, hint ) {
M
Mr.doob 已提交
1934

1935
		var v, c, vertex, offset,
1936 1937 1938 1939
		vertices = geometry.vertices,
		colors = geometry.colors,
		vl = vertices.length,
		cl = colors.length,
M
Mr.doob 已提交
1940

1941 1942
		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,
1943

1944 1945
		dirtyVertices = geometry.__dirtyVertices,
		dirtyColors = geometry.__dirtyColors;
M
Mr.doob 已提交
1946

1947
		if ( dirtyVertices ) {
M
Mr.doob 已提交
1948

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

1951
				vertex = vertices[ v ].position;
M
Mr.doob 已提交
1952

1953
				offset = v * 3;
M
Mr.doob 已提交
1954

1955 1956 1957
				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;
M
Mr.doob 已提交
1958

1959 1960
			}

1961
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
A
alteredq 已提交
1962 1963
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );

1964
		}
M
Mr.doob 已提交
1965

1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979
		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;

			}

1980
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
1981 1982 1983 1984
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}

1985
	};
M
Mr.doob 已提交
1986

1987
	function setRibbonBuffers ( geometry, hint ) {
A
alteredq 已提交
1988 1989

		var v, c, vertex, offset,
1990 1991 1992 1993
		vertices = geometry.vertices,
		colors = geometry.colors,
		vl = vertices.length,
		cl = colors.length,
A
alteredq 已提交
1994

1995 1996
		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,
1997

1998 1999
		dirtyVertices = geometry.__dirtyVertices,
		dirtyColors = geometry.__dirtyColors;
A
alteredq 已提交
2000 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
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
A
alteredq 已提交
2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033
			_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;

			}

2034
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
A
alteredq 已提交
2035 2036 2037 2038 2039
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}

	};
2040

2041
	function setParticleBuffers ( geometry, hint, object ) {
2042

A
alteredq 已提交
2043
		var v, c, vertex, offset,
2044 2045
		vertices = geometry.vertices,
		vl = vertices.length,
2046

2047 2048
		colors = geometry.colors,
		cl = colors.length,
2049

2050 2051
		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,
2052

2053
		sortArray = geometry.__sortArray,
2054

2055 2056 2057
		dirtyVertices = geometry.__dirtyVertices,
		dirtyElements = geometry.__dirtyElements,
		dirtyColors = geometry.__dirtyColors;
2058

2059
		if ( object.sortParticles ) {
2060

2061
			_projScreenMatrix.multiplySelf( object.matrixWorld );
2062

2063 2064 2065
			for ( v = 0; v < vl; v++ ) {

				vertex = vertices[ v ].position;
2066

2067 2068
				_vector3.copy( vertex );
				_projScreenMatrix.multiplyVector3( _vector3 );
2069

2070
				sortArray[ v ] = [ _vector3.z, v ];
2071

2072
			}
2073

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

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

2078
				vertex = vertices[ sortArray[v][1] ].position;
2079

2080
				offset = v * 3;
2081

2082 2083 2084
				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;
2085

2086
			}
2087

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

A
alteredq 已提交
2090
				offset = c * 3;
2091

A
alteredq 已提交
2092 2093 2094 2095 2096
				color = colors[ sortArray[c][1] ];

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

2098
			}
2099 2100


2101
		} else {
2102

2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115
			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;

				}
2116 2117

			}
2118

A
alteredq 已提交
2119
			if ( dirtyColors ) {
2120

A
alteredq 已提交
2121 2122 2123 2124 2125 2126 2127 2128 2129 2130
				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;

2131
				}
2132

A
alteredq 已提交
2133
			}
2134 2135

		}
2136

A
alteredq 已提交
2137
		if ( dirtyVertices || object.sortParticles ) {
2138

2139
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
A
alteredq 已提交
2140
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
2141

A
alteredq 已提交
2142
		}
2143

A
alteredq 已提交
2144
		if ( dirtyColors || object.sortParticles ) {
2145

2146
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
A
alteredq 已提交
2147
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
2148

A
alteredq 已提交
2149
		}
2150

2151
	};
M
Mr.doob 已提交
2152

2153
	function setMaterialShaders( material, shaders ) {
2154

2155
		material.uniforms = THREE.UniformsUtils.clone( shaders.uniforms );
2156 2157
		material.vertexShader = shaders.vertexShader;
		material.fragmentShader = shaders.fragmentShader;
2158

M
Mr.doob 已提交
2159
	};
2160

2161
	function refreshUniformsCommon( uniforms, material ) {
M
Mr.doob 已提交
2162

M
Mr.doob 已提交
2163
		uniforms.diffuse.value = material.color;
A
alteredq 已提交
2164
		uniforms.opacity.value = material.opacity;
2165
		
A
alteredq 已提交
2166
		uniforms.map.texture = material.map;
2167 2168 2169 2170 2171
		if ( material.map ) {
			
			uniforms.offsetRepeat.value.set( material.map.offset.x, material.map.offset.y, material.map.repeat.x, material.map.repeat.y );

		}
2172

2173
		uniforms.lightMap.texture = material.lightMap;
2174

2175
		uniforms.envMap.texture = material.envMap;
A
alteredq 已提交
2176
		uniforms.reflectivity.value = material.reflectivity;
2177
		uniforms.refractionRatio.value = material.refractionRatio;
A
alteredq 已提交
2178
		uniforms.combine.value = material.combine;
2179
		uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
2180

2181
	};
2182

2183
	function refreshUniformsLine( uniforms, material ) {
2184

M
Mr.doob 已提交
2185
		uniforms.diffuse.value = material.color;
A
alteredq 已提交
2186
		uniforms.opacity.value = material.opacity;
2187 2188

	};
M
Mr.doob 已提交
2189

2190
	function refreshUniformsParticle( uniforms, material ) {
2191

M
Mr.doob 已提交
2192
		uniforms.psColor.value = material.color;
A
alteredq 已提交
2193 2194
		uniforms.opacity.value = material.opacity;
		uniforms.size.value = material.size;
M
Mr.doob 已提交
2195
		uniforms.scale.value = _canvas.height / 2.0; // TODO: Cache this.
2196

A
alteredq 已提交
2197
		uniforms.map.texture = material.map;
2198

A
alteredq 已提交
2199
	};
2200

2201
	function refreshUniformsFog( uniforms, fog ) {
2202

M
Mr.doob 已提交
2203
		uniforms.fogColor.value = fog.color;
2204

A
alteredq 已提交
2205
		if ( fog instanceof THREE.Fog ) {
2206

A
alteredq 已提交
2207 2208
			uniforms.fogNear.value = fog.near;
			uniforms.fogFar.value = fog.far;
2209

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

A
alteredq 已提交
2212
			uniforms.fogDensity.value = fog.density;
2213 2214

		}
2215

2216 2217
	};

2218
	function refreshUniformsPhong( uniforms, material ) {
M
Mr.doob 已提交
2219

M
Mr.doob 已提交
2220 2221
		uniforms.ambient.value = material.ambient;
		uniforms.specular.value = material.specular;
A
alteredq 已提交
2222
		uniforms.shininess.value = material.shininess;
M
Mr.doob 已提交
2223

2224
	};
M
Mr.doob 已提交
2225 2226


2227
	function refreshUniformsLights( uniforms, lights ) {
M
Mr.doob 已提交
2228

A
alteredq 已提交
2229 2230
		uniforms.enableLighting.value = lights.directional.length + lights.point.length;
		uniforms.ambientLightColor.value = lights.ambient;
2231

A
alteredq 已提交
2232 2233
		uniforms.directionalLightColor.value = lights.directional.colors;
		uniforms.directionalLightDirection.value = lights.directional.positions;
2234

A
alteredq 已提交
2235 2236
		uniforms.pointLightColor.value = lights.point.colors;
		uniforms.pointLightPosition.value = lights.point.positions;
2237
		uniforms.pointLightDistance.value = lights.point.distances;
M
Mr.doob 已提交
2238

A
alteredq 已提交
2239
	};
M
Mr.doob 已提交
2240

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

2243
		var u, a, identifiers, i, parameters, maxLightCount, maxBones, shaderID;
2244

A
alteredq 已提交
2245
		if ( material instanceof THREE.MeshDepthMaterial ) {
2246

2247
			shaderID = 'depth';
2248

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

2251
			shaderID = 'shadowVolumeDynamic';
M
Mikael Emtinger 已提交
2252

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

2255
			shaderID = 'normal';
2256

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

2259
			shaderID = 'basic';
2260

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

2263
			shaderID = 'lambert';
M
Mr.doob 已提交
2264

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

2267
			shaderID = 'phong';
M
Mr.doob 已提交
2268

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

2271
			shaderID = 'basic';
2272

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

2275 2276 2277 2278 2279 2280 2281
			shaderID = 'particle_basic';

		}

		if ( shaderID ) {

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

A
alteredq 已提交
2283
		}
2284

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

2288
		maxLightCount = allocateLights( lights, 4 );
2289

2290
		maxBones = allocateBones( object );
M
Mr.doob 已提交
2291

2292
		parameters = {
2293 2294
			map: !!material.map, envMap: !!material.envMap, lightMap: !!material.lightMap, 
			vertexColors: material.vertexColors,
2295 2296 2297
			fog: fog, sizeAttenuation: material.sizeAttenuation,
			skinning: material.skinning,
			morphTargets: material.morphTargets,
2298
			maxMorphTargets: this.maxMorphTargets,
2299 2300 2301
			maxDirLights: maxLightCount.directional, maxPointLights: maxLightCount.point,
			maxBones: maxBones
		};
M
Mikael Emtinger 已提交
2302

2303
		material.program = buildProgram( shaderID, material.fragmentShader, material.vertexShader, material.uniforms, material.attributes, parameters );
2304

2305
		var attributes = material.program.attributes;
2306

2307
		if ( attributes.position >= 0 ) _gl.enableVertexAttribArray( attributes.position );
2308 2309 2310
		if ( attributes.color >= 0 ) _gl.enableVertexAttribArray( attributes.color );
		if ( attributes.normal >= 0 ) _gl.enableVertexAttribArray( attributes.normal );
		if ( attributes.tangent >= 0 ) _gl.enableVertexAttribArray( attributes.tangent );
2311

2312 2313 2314
		if ( material.skinning &&
			 attributes.skinVertexA >=0 && attributes.skinVertexB >= 0 &&
			 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
2315

2316 2317 2318 2319
			_gl.enableVertexAttribArray( attributes.skinVertexA );
			_gl.enableVertexAttribArray( attributes.skinVertexB );
			_gl.enableVertexAttribArray( attributes.skinIndex );
			_gl.enableVertexAttribArray( attributes.skinWeight );
2320

2321
		}
2322

2323 2324 2325 2326 2327 2328 2329 2330
		if ( material.attributes ) {
			
			for ( a in material.attributes ) {
	
				if( attributes[ a ] !== undefined && attributes[ a ] >= 0 ) _gl.enableVertexAttribArray( attributes[ a ] );
	
			}
			
2331
		}
2332 2333


2334

2335
		if ( material.morphTargets ) {
2336

2337
			material.numSupportedMorphTargets = 0;
2338

2339

2340
			if ( attributes.morphTarget0 >= 0 ) {
2341

2342 2343
				_gl.enableVertexAttribArray( attributes.morphTarget0 );
				material.numSupportedMorphTargets ++;
2344

2345
			}
2346

2347
			if ( attributes.morphTarget1 >= 0 ) {
2348

2349 2350
				_gl.enableVertexAttribArray( attributes.morphTarget1 );
				material.numSupportedMorphTargets ++;
2351

2352
			}
2353

2354
			if ( attributes.morphTarget2 >= 0 ) {
2355

2356 2357
				_gl.enableVertexAttribArray( attributes.morphTarget2 );
				material.numSupportedMorphTargets ++;
2358

2359
			}
2360

2361
			if ( attributes.morphTarget3 >= 0 ) {
2362

2363 2364
				_gl.enableVertexAttribArray( attributes.morphTarget3 );
				material.numSupportedMorphTargets ++;
2365

2366
			}
2367

2368
			if ( attributes.morphTarget4 >= 0 ) {
2369

2370 2371
				_gl.enableVertexAttribArray( attributes.morphTarget4 );
				material.numSupportedMorphTargets ++;
2372

2373
			}
2374

2375
			if ( attributes.morphTarget5 >= 0 ) {
2376

2377 2378
				_gl.enableVertexAttribArray( attributes.morphTarget5 );
				material.numSupportedMorphTargets ++;
2379

2380
			}
2381

2382
			if ( attributes.morphTarget6 >= 0 ) {
2383

2384 2385
				_gl.enableVertexAttribArray( attributes.morphTarget6 );
				material.numSupportedMorphTargets ++;
2386

2387
			}
2388

2389
			if ( attributes.morphTarget7 >= 0 ) {
2390

2391 2392
				_gl.enableVertexAttribArray( attributes.morphTarget7 );
				material.numSupportedMorphTargets ++;
2393

2394
			}
2395

2396
			object.__webglMorphTargetInfluences = new Float32Array( this.maxMorphTargets );
2397

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

2400
				object.__webglMorphTargetInfluences[ i ] = 0;
2401 2402 2403

			}

2404
		}
M
Mr.doob 已提交
2405

2406
	};
2407

2408
	function setProgram( camera, lights, fog, material, object ) {
2409

2410
		if ( ! material.program ) {
2411 2412 2413 2414

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

		}
M
Mr.doob 已提交
2415

2416
		var program = material.program,
A
alteredq 已提交
2417 2418
			p_uniforms = program.uniforms,
			m_uniforms = material.uniforms;
2419

2420
		if ( program != _currentProgram ) {
M
Mr.doob 已提交
2421

M
Mr.doob 已提交
2422
			_gl.useProgram( program );
2423
			_currentProgram = program;
2424

M
Mr.doob 已提交
2425
		}
2426

2427 2428
		_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, _projectionMatrixArray );

A
alteredq 已提交
2429
		// refresh uniforms common to several materials
2430 2431

		if ( fog && (
A
alteredq 已提交
2432 2433
			 material instanceof THREE.MeshBasicMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
2434
			 material instanceof THREE.MeshPhongMaterial ||
A
alteredq 已提交
2435
			 material instanceof THREE.LineBasicMaterial ||
2436 2437
			 material instanceof THREE.ParticleBasicMaterial ||
			 material.fog )
A
alteredq 已提交
2438
			) {
2439

A
alteredq 已提交
2440
			refreshUniformsFog( m_uniforms, fog );
2441 2442

		}
M
Mr.doob 已提交
2443

M
Mr.doob 已提交
2444
		if ( material instanceof THREE.MeshPhongMaterial ||
2445 2446
			 material instanceof THREE.MeshLambertMaterial ||
			 material.lights ) {
2447

A
alteredq 已提交
2448
			setupLights( program, lights );
A
alteredq 已提交
2449
			refreshUniformsLights( m_uniforms, _lights );
M
Mr.doob 已提交
2450 2451 2452

		}

2453 2454 2455
		if ( material instanceof THREE.MeshBasicMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
			 material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
2456

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

A
alteredq 已提交
2459
		}
M
Mr.doob 已提交
2460

A
alteredq 已提交
2461
		// refresh single material specific uniforms
2462

2463
		if ( material instanceof THREE.LineBasicMaterial ) {
M
Mr.doob 已提交
2464

A
alteredq 已提交
2465
			refreshUniformsLine( m_uniforms, material );
2466

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

A
alteredq 已提交
2469
			refreshUniformsParticle( m_uniforms, material );
2470

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

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

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

2477 2478
			m_uniforms.mNear.value = camera.near;
			m_uniforms.mFar.value = camera.far;
A
alteredq 已提交
2479
			m_uniforms.opacity.value = material.opacity;
2480

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

A
alteredq 已提交
2483
			m_uniforms.opacity.value = material.opacity;
2484
		}
2485

A
alteredq 已提交
2486
		// load common uniforms
2487

A
alteredq 已提交
2488 2489
		loadUniformsGeneric( program, m_uniforms );
		loadUniformsMatrices( p_uniforms, object );
2490

A
alteredq 已提交
2491 2492
		// load material specific uniforms
		// (shader material also gets them for the sake of genericity)
2493

A
alteredq 已提交
2494 2495
		if ( material instanceof THREE.MeshShaderMaterial ||
			 material instanceof THREE.MeshPhongMaterial ||
2496
			 material.envMap ) {
2497

2498
			if( p_uniforms.cameraPosition !== null ) {
2499 2500 2501 2502
				
				_gl.uniform3f( p_uniforms.cameraPosition, camera.position.x, camera.position.y, camera.position.z );
				
			}
2503

2504
		}
2505

A
alteredq 已提交
2506
		if ( material instanceof THREE.MeshShaderMaterial ||
2507
			 material.envMap ||
2508
			 material.skinning ) {
2509

2510
			if ( p_uniforms.objectMatrix !== null ) {
2511 2512 2513 2514
				
				_gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object._objectMatrixArray );
				
			}
2515

A
alteredq 已提交
2516
		}
2517

A
alteredq 已提交
2518 2519
		if ( material instanceof THREE.MeshPhongMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
A
alteredq 已提交
2520
			 material instanceof THREE.MeshShaderMaterial ||
2521 2522
			 material.skinning ) {

2523
			if( p_uniforms.viewMatrix !== null ) {
2524 2525 2526 2527
				
				_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, _viewMatrixArray );
				
			} 
2528

A
alteredq 已提交
2529
		}
2530

2531 2532
		if ( material instanceof THREE.ShadowVolumeDynamicMaterial ) {

M
Mikael Emtinger 已提交
2533
			var dirLight = m_uniforms.directionalLightDirection.value;
2534

2535 2536 2537
			dirLight[ 0 ] = -lights[ 1 ].position.x;
			dirLight[ 1 ] = -lights[ 1 ].position.y;
			dirLight[ 2 ] = -lights[ 1 ].position.z;
2538

M
Mikael Emtinger 已提交
2539 2540 2541 2542 2543 2544
			_gl.uniform3fv( p_uniforms.directionalLightDirection, dirLight );
			_gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object._objectMatrixArray );
			_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, _viewMatrixArray );
		}


2545
		if ( material.skinning ) {
2546

2547
			loadUniformsSkinning( p_uniforms, object );
2548

A
alteredq 已提交
2549
		}
2550

A
alteredq 已提交
2551
		return program;
2552

A
alteredq 已提交
2553
	};
2554

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

2557 2558
		if ( material.opacity == 0 ) return;

2559
		var program, attributes, linewidth, primitives, a, attribute;
A
alteredq 已提交
2560

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

2563
		attributes = program.attributes;
M
Mr.doob 已提交
2564

2565
		// vertices
M
Mr.doob 已提交
2566

2567
		if ( !material.morphTargets && attributes.position >= 0 ) {
2568 2569

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

2572
		} else {
2573

M
Mikael Emtinger 已提交
2574
			setupMorphTargets( material, geometryGroup, object );
2575

2576 2577
		}

2578 2579 2580

		// custom attributes

2581 2582
        // Use the per-geometryGroup custom attribute arrays which are setup in initMeshBuffers
		if ( geometryGroup.__webglCustomAttributes ) {
M
Mr.doob 已提交
2583

2584
			for( a in geometryGroup.__webglCustomAttributes ) {
M
Mr.doob 已提交
2585

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

2588
					attribute = geometryGroup.__webglCustomAttributes[ a ];
M
Mr.doob 已提交
2589

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

2593
				}
M
Mr.doob 已提交
2594

2595
			}
M
Mr.doob 已提交
2596

2597
		}
2598 2599


2600
/*		if ( material.attributes ) {
2601 2602 2603

			for( a in material.attributes ) {

2604
				if( attributes[ a ] !== undefined && attributes[ a ] >= 0 ) {
2605 2606 2607

					attribute = material.attributes[ a ];

2608 2609 2610 2611 2612 2613
					if( attribute.buffer ) {
						
						_gl.bindBuffer( _gl.ARRAY_BUFFER, attribute.buffer );
						_gl.vertexAttribPointer( attributes[ a ], attribute.size, _gl.FLOAT, false, 0, 0 );

					}
2614 2615 2616 2617 2618

				}

			}

2619
		}*/
2620 2621


2622

A
alteredq 已提交
2623 2624 2625 2626
		// colors

		if ( attributes.color >= 0 ) {

2627
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
2628
			_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
2629 2630 2631

		}

2632
		// normals
M
Mr.doob 已提交
2633

2634
		if ( attributes.normal >= 0 ) {
2635

2636
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
2637
			_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
2638

2639
		}
2640

2641 2642 2643
		// tangents

		if ( attributes.tangent >= 0 ) {
2644

2645
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
2646
			_gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
2647

2648
		}
2649

2650
		// uvs
M
Mr.doob 已提交
2651

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

2654
			if ( geometryGroup.__webglUVBuffer ) {
2655

2656
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
2657
				_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
2658

2659
				_gl.enableVertexAttribArray( attributes.uv );
2660

2661
			} else {
2662

2663
				_gl.disableVertexAttribArray( attributes.uv );
M
Mr.doob 已提交
2664

2665
			}
2666 2667 2668

		}

2669 2670
		if ( attributes.uv2 >= 0 ) {

2671
			if ( geometryGroup.__webglUV2Buffer ) {
2672

2673
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685
				_gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );

				_gl.enableVertexAttribArray( attributes.uv2 );

			} else {

				_gl.disableVertexAttribArray( attributes.uv2 );

			}

		}

2686
		if ( material.skinning &&
2687
			 attributes.skinVertexA >= 0 && attributes.skinVertexB >= 0 &&
A
alteredq 已提交
2688
			 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
2689

2690
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
A
alteredq 已提交
2691 2692
			_gl.vertexAttribPointer( attributes.skinVertexA, 4, _gl.FLOAT, false, 0, 0 );

2693
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
A
alteredq 已提交
2694 2695
			_gl.vertexAttribPointer( attributes.skinVertexB, 4, _gl.FLOAT, false, 0, 0 );

2696
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
A
alteredq 已提交
2697 2698
			_gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 );

2699
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
A
alteredq 已提交
2700
			_gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 );
2701

A
alteredq 已提交
2702
		}
2703

2704
		// render mesh
M
Mr.doob 已提交
2705

2706
		if ( object instanceof THREE.Mesh ) {
2707

2708
			// wireframe
2709

2710
			if ( material.wireframe ) {
M
Mr.doob 已提交
2711

2712
				_gl.lineWidth( material.wireframeLinewidth );
2713 2714
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
				_gl.drawElements( _gl.LINES, geometryGroup.__webglLineCount, _gl.UNSIGNED_SHORT, 0 );
2715

2716
			// triangles
2717

2718
			} else {
2719

2720 2721 2722
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
				_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );

2723
			}
2724

2725 2726
			_this.data.vertices += geometryGroup.__webglFaceCount;
			_this.data.faces += geometryGroup.__webglFaceCount / 3;
2727
			_this.data.drawCalls ++;
2728

2729
		// render lines
2730

2731
		} else if ( object instanceof THREE.Line ) {
2732

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

2735
			_gl.lineWidth( material.linewidth );
2736
			_gl.drawArrays( primitives, 0, geometryGroup.__webglLineCount );
2737

2738 2739
			_this.data.drawCalls ++;

2740
		// render particles
2741

2742
		} else if ( object instanceof THREE.ParticleSystem ) {
2743

2744
			_gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webglParticleCount );
2745

2746 2747
			_this.data.drawCalls ++;

A
alteredq 已提交
2748
		// render ribbon
2749

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

2752
			_gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webglVertexCount );
2753

2754 2755
			_this.data.drawCalls ++;

2756 2757 2758 2759
		}

	};

M
Mikael Emtinger 已提交
2760

M
Mikael Emtinger 已提交
2761
	function setupMorphTargets( material, geometryGroup, object ) {
2762

M
Mikael Emtinger 已提交
2763
		// set base
2764

M
Mikael Emtinger 已提交
2765
		var attributes = material.program.attributes;
2766

2767
		if (  object.morphTargetBase !== - 1 ) {
2768 2769

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

2772
		} else if ( attributes.position >= 0 ) {
2773 2774

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

M
Mikael Emtinger 已提交
2777
		}
2778

2779
		if ( object.morphTargetForcedOrder.length ) {
M
Mikael Emtinger 已提交
2780 2781

			// set forced order
2782

M
Mikael Emtinger 已提交
2783 2784 2785
			var m = 0;
			var order = object.morphTargetForcedOrder;
			var influences = object.morphTargetInfluences;
2786 2787 2788 2789

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

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

2792 2793 2794 2795
				object.__webglMorphTargetInfluences[ m ] = influences[ order[ m ]];

				m ++;
			}
2796

M
Mikael Emtinger 已提交
2797
		} else {
2798

M
Mikael Emtinger 已提交
2799
			// find most influencing
2800

M
Mikael Emtinger 已提交
2801
			var used = [];
2802
			var candidateInfluence = - 1;
M
Mikael Emtinger 已提交
2803 2804 2805 2806
			var candidate = 0;
			var influences = object.morphTargetInfluences;
			var i, il = influences.length;
			var m = 0;
2807

2808
			if ( object.morphTargetBase !== - 1 ) {
2809

M
Mikael Emtinger 已提交
2810
				used[ object.morphTargetBase ] = true;
2811

M
Mikael Emtinger 已提交
2812
			}
2813 2814 2815

			while ( m < material.numSupportedMorphTargets ) {

2816
				for ( i = 0; i < il; i ++ ) {
2817 2818 2819

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

M
Mikael Emtinger 已提交
2820 2821
						candidate = i;
						candidateInfluence = influences[ candidate ];
2822

M
Mikael Emtinger 已提交
2823 2824
					}
				}
2825 2826

				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ candidate ] );
M
Mikael Emtinger 已提交
2827
				_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
2828 2829 2830

				object.__webglMorphTargetInfluences[ m ] = candidateInfluence;

M
Mikael Emtinger 已提交
2831 2832
				used[ candidate ] = 1;
				candidateInfluence = -1;
2833
				m ++;
M
Mikael Emtinger 已提交
2834 2835 2836 2837
			}
		}

		// load updated influences uniform
2838

2839 2840 2841 2842 2843 2844
		if( material.program.uniforms.morphTargetInfluences !== null ) {
			
			_gl.uniform1fv( material.program.uniforms.morphTargetInfluences, object.__webglMorphTargetInfluences );
			
		}

M
Mikael Emtinger 已提交
2845 2846 2847
	}


2848
	function renderBufferImmediate( object, program, shading ) {
2849

2850 2851
		if ( ! object.__webglVertexBuffer ) object.__webglVertexBuffer = _gl.createBuffer();
		if ( ! object.__webglNormalBuffer ) object.__webglNormalBuffer = _gl.createBuffer();
2852

A
alteredq 已提交
2853
		if ( object.hasPos ) {
2854

2855 2856 2857 2858
			_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 );
2859

A
alteredq 已提交
2860
		}
2861

A
alteredq 已提交
2862
		if ( object.hasNormal ) {
2863

2864
			_gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglNormalBuffer );
2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908

			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;

				}

			}

2909 2910 2911
			_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 );
2912

A
alteredq 已提交
2913
		}
2914

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

A
alteredq 已提交
2917
		object.count = 0;
2918

A
alteredq 已提交
2919
	};
2920

2921
	function setObjectFaces( object ) {
2922

2923
		if ( _oldDoubleSided != object.doubleSided ) {
2924

2925
			if( object.doubleSided ) {
2926

2927
				_gl.disable( _gl.CULL_FACE );
2928

2929
			} else {
2930

A
alteredq 已提交
2931
				_gl.enable( _gl.CULL_FACE );
2932

A
alteredq 已提交
2933
			}
2934

2935
			_oldDoubleSided = object.doubleSided;
2936

2937
		}
2938

2939
		if ( _oldFlipSided != object.flipSided ) {
2940

2941 2942 2943 2944
			if( object.flipSided ) {

				_gl.frontFace( _gl.CW );

2945
			} else {
2946 2947 2948 2949

				_gl.frontFace( _gl.CCW );

			}
2950

2951
			_oldFlipSided = object.flipSided;
2952 2953

		}
2954

2955
	};
2956

2957
	function setDepthTest( test ) {
2958

A
alteredq 已提交
2959 2960 2961
		if ( _oldDepth != test ) {

			if( test ) {
2962

A
alteredq 已提交
2963
				_gl.enable( _gl.DEPTH_TEST );
2964

A
alteredq 已提交
2965
			} else {
2966

A
alteredq 已提交
2967
				_gl.disable( _gl.DEPTH_TEST );
2968

A
alteredq 已提交
2969
			}
2970

A
alteredq 已提交
2971 2972 2973
			_oldDepth = test;

		}
2974

A
alteredq 已提交
2975
	};
2976

2977
	function computeFrustum( m ) {
2978 2979 2980 2981 2982 2983 2984 2985 2986

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

A
alteredq 已提交
2988
		for ( i = 0; i < 6; i ++ ) {
2989 2990 2991 2992 2993 2994 2995

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

		}

	};
2996

2997
	function isInFrustum( object ) {
2998

2999
		var distance, matrix = object.matrixWorld,
3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011
		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;

	};
3012

3013
	function addToFixedArray( where, what ) {
3014

3015 3016
		where.list[ where.count ] = what;
		where.count += 1;
3017

3018
	};
3019

3020
	function unrollImmediateBufferMaterials( globject ) {
3021

3022 3023 3024 3025 3026 3027 3028
		var i, l, m, ml, material,
			object = globject.object,
			opaque = globject.opaque,
			transparent = globject.transparent;

		transparent.count = 0;
		opaque.count = 0;
3029

3030 3031 3032
		for ( m = 0, ml = object.materials.length; m < ml; m++ ) {

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

3035
		}
3036

3037
	};
3038

3039
	function unrollBufferMaterials( globject ) {
3040

3041 3042 3043 3044 3045 3046 3047 3048
		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;
3049

3050 3051 3052 3053 3054 3055 3056 3057 3058
		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 ];
3059
					if ( material ) material.transparent ? addToFixedArray( transparent, material ) : addToFixedArray( opaque, material );
3060 3061 3062 3063 3064 3065

				}

			} else {

				material = meshMaterial;
3066
				if ( material ) material.transparent ? addToFixedArray( transparent, material ) : addToFixedArray( opaque, material );
3067

3068 3069 3070
			}

		}
3071

3072
	};
3073 3074


3075
	function painterSort( a, b ) {
3076

3077
		return b.z - a.z;
3078 3079

	};
3080

3081
	this.render = function( scene, camera, renderTarget, forceClear ) {
3082

A
alteredq 已提交
3083
		var i, program, opaque, transparent, material,
3084
			o, ol, oil, webglObject, object, buffer,
A
alteredq 已提交
3085
			lights = scene.lights,
N
Nicholas Kinsey 已提交
3086
			fog = scene.fog;
3087

3088 3089
		_this.data.vertices = 0;
		_this.data.faces = 0;
3090
		_this.data.drawCalls = 0;
3091

3092
		camera.matrixAutoUpdate && camera.update( undefined, true );
3093

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

M
Mr.doob 已提交
3096
		camera.matrixWorldInverse.flattenToArray( _viewMatrixArray );
3097
		camera.projectionMatrix.flattenToArray( _projectionMatrixArray );
M
Mr.doob 已提交
3098

M
Mr.doob 已提交
3099
		_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
3100
		computeFrustum( _projScreenMatrix );
3101

A
alteredq 已提交
3102
		this.initWebGLObjects( scene );
M
Mr.doob 已提交
3103

A
alteredq 已提交
3104
		setRenderTarget( renderTarget );
M
Mr.doob 已提交
3105

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

3108
			this.clear();
M
Mr.doob 已提交
3109

3110 3111
		}

3112
		// set matrices
3113

3114
		ol = scene.__webglObjects.length;
3115

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

3118 3119
			webglObject = scene.__webglObjects[ o ];
			object = webglObject.object;
M
Mr.doob 已提交
3120

3121
			if ( object.visible ) {
3122 3123

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

3125
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
3126

3127
					setupMatrices( object, camera );
3128

3129
					unrollBufferMaterials( webglObject );
3130

3131
					webglObject.render = true;
3132

3133
					if ( this.sortObjects ) {
3134

3135 3136 3137
						_vector3.copy( object.position );
						_projScreenMatrix.multiplyVector3( _vector3 );

3138
						webglObject.z = _vector3.z;
3139

3140
					}
3141

3142
				} else {
3143

3144
					webglObject.render = false;
3145

3146
				}
3147

3148
			} else {
3149

3150
				webglObject.render = false;
3151

3152
			}
3153

3154
		}
3155

3156
		if ( this.sortObjects ) {
3157

3158
			scene.__webglObjects.sort( painterSort );
3159

3160
		}
3161

3162
		oil = scene.__webglObjectsImmediate.length;
3163

3164
		for ( o = 0; o < oil; o++ ) {
3165

3166 3167
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
3168

3169
			if ( object.visible ) {
3170 3171 3172

				if( object.matrixAutoUpdate ) {

3173
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
3174

A
alteredq 已提交
3175
				}
3176

3177
				setupMatrices( object, camera );
3178

3179
				unrollImmediateBufferMaterials( webglObject );
3180

3181
			}
3182

3183
		}
A
alteredq 已提交
3184

3185 3186
		// opaque pass

3187
		setBlending( THREE.NormalBlending );
3188

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

3191
			webglObject = scene.__webglObjects[ o ];
3192

3193
			if ( webglObject.render ) {
3194

3195 3196 3197
				object = webglObject.object;
				buffer = webglObject.buffer;
				opaque = webglObject.opaque;
3198

3199
				setObjectFaces( object );
3200

3201
				for ( i = 0; i < opaque.count; i ++ ) {
3202

3203
					material = opaque.list[ i ];
3204

3205
					setDepthTest( material.depthTest );
A
alteredq 已提交
3206
					renderBuffer( camera, lights, fog, material, buffer, object );
3207

3208
				}
3209 3210 3211 3212 3213

			}

		}

A
alteredq 已提交
3214
		// opaque pass (immediate simulator)
3215

3216
		for ( o = 0; o < oil; o++ ) {
3217

3218 3219
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
3220

A
alteredq 已提交
3221
			if ( object.visible ) {
3222

3223
				opaque = webglObject.opaque;
3224

3225
				setObjectFaces( object );
3226

3227
				for( i = 0; i < opaque.count; i++ ) {
3228

3229
					material = opaque.list[ i ];
3230

3231
					setDepthTest( material.depthTest );
3232

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

3236
				}
3237

A
alteredq 已提交
3238
			}
3239

A
alteredq 已提交
3240 3241
		}

3242 3243
		// transparent pass

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

3246
			webglObject = scene.__webglObjects[ o ];
3247

3248
			if ( webglObject.render ) {
3249

3250 3251 3252
				object = webglObject.object;
				buffer = webglObject.buffer;
				transparent = webglObject.transparent;
3253

3254
				setObjectFaces( object );
3255

3256
				for ( i = 0; i < transparent.count; i ++ ) {
3257

3258
					material = transparent.list[ i ];
3259

3260
					setBlending( material.blending );
3261
					setDepthTest( material.depthTest );
3262

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

3265
				}
3266

3267
			}
M
Mr.doob 已提交
3268

M
Mr.doob 已提交
3269
		}
M
Mr.doob 已提交
3270

3271
		// transparent pass (immediate simulator)
3272

3273
		for ( o = 0; o < oil; o++ ) {
3274

3275 3276
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
3277

3278
			if ( object.visible ) {
3279

3280
				transparent = webglObject.transparent;
3281

3282
				setObjectFaces( object );
3283

3284
				for ( i = 0; i < transparent.count; i ++ ) {
3285

3286
					material = transparent.list[ i ];
3287

3288
					setBlending( material.blending );
3289
					setDepthTest( material.depthTest );
3290

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

3294
				}
3295

3296
			}
3297

3298
		}
3299

M
Mikael Emtinger 已提交
3300
		// render 2d
3301

M
Mikael Emtinger 已提交
3302
		if ( scene.__webglSprites.length ) {
3303

3304
			renderSprites( scene, camera );
3305

M
Mikael Emtinger 已提交
3306 3307
		}

M
Mikael Emtinger 已提交
3308
		// render stencil shadows
M
Mikael Emtinger 已提交
3309

3310
		if ( _stencil && scene.__webglShadowVolumes.length && scene.lights.length ) {
M
Mikael Emtinger 已提交
3311 3312

			renderStencilShadows( scene );
3313

M
Mikael Emtinger 已提交
3314 3315
		}

3316

3317
		// render lens flares
3318 3319 3320

		if ( scene.__webglLensFlares.length ) {

3321
			renderLensFlares( scene, camera );
3322

3323 3324
		}

M
Mikael Emtinger 已提交
3325 3326 3327 3328 3329 3330 3331 3332 3333

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

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

			updateRenderTargetMipmap( renderTarget );

		}

3334
		//_gl.finish();
3335

M
Mikael Emtinger 已提交
3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349
	};



	/*
	 * 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 ) {
3350

M
Mikael Emtinger 已提交
3351 3352 3353 3354 3355
		// setup stencil

		_gl.enable( _gl.POLYGON_OFFSET_FILL );
		_gl.polygonOffset( 0.1, 1.0 );
		_gl.enable( _gl.STENCIL_TEST );
3356
		_gl.enable( _gl.DEPTH_TEST );
M
Mikael Emtinger 已提交
3357 3358
		_gl.depthMask( false );
		_gl.colorMask( false, false, false, false );
3359

M
Mikael Emtinger 已提交
3360 3361 3362 3363
		_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 );

3364

M
Mikael Emtinger 已提交
3365
		// loop through all directional lights
3366

M
Mikael Emtinger 已提交
3367 3368
		var l, ll = scene.lights.length;
		var p;
M
Mikael Emtinger 已提交
3369
		var light, lights = scene.lights;
3370
		var dirLight = [];
M
Mikael Emtinger 已提交
3371
		var object, geometryGroup, material;
3372
		var program;
M
Mikael Emtinger 已提交
3373
		var p_uniforms;
3374 3375
		var m_uniforms;
		var attributes;
M
Mikael Emtinger 已提交
3376
		var o, ol = scene.__webglShadowVolumes.length;
3377 3378 3379

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

M
Mikael Emtinger 已提交
3380
			light = scene.lights[ l ];
3381

3382
			if ( light instanceof THREE.DirectionalLight && light.castShadow ) {
M
Mikael Emtinger 已提交
3383 3384 3385 3386 3387 3388

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

				// render all volumes
3389 3390 3391

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

M
Mikael Emtinger 已提交
3392 3393 3394
					object        = scene.__webglShadowVolumes[ o ].object;
					geometryGroup = scene.__webglShadowVolumes[ o ].buffer;
					material      = object.materials[ 0 ];
3395

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

M
Mikael Emtinger 已提交
3398 3399
					program = material.program,
		  			p_uniforms = program.uniforms,
3400 3401
					m_uniforms = material.uniforms,
					attributes = program.attributes;
3402

3403
					if ( _currentProgram !== program ) {
3404

M
Mikael Emtinger 已提交
3405
						_gl.useProgram( program );
M
Mikael Emtinger 已提交
3406
						_currentProgram = program;
3407

M
Mikael Emtinger 已提交
3408 3409 3410 3411
						_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, _projectionMatrixArray );
						_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, _viewMatrixArray );
						_gl.uniform3fv( p_uniforms.directionalLightDirection, dirLight );
					}
3412 3413


M
Mikael Emtinger 已提交
3414 3415
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
					_gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object._objectMatrixArray );
3416 3417


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

M
Mikael Emtinger 已提交
3421
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
M
Mikael Emtinger 已提交
3422
					_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
3423

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

M
Mikael Emtinger 已提交
3426
					_gl.cullFace( _gl.FRONT );
M
Mikael Emtinger 已提交
3427
					_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );
3428

M
Mikael Emtinger 已提交
3429
					_gl.cullFace( _gl.BACK );
M
Mikael Emtinger 已提交
3430
					_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );
3431

M
Mikael Emtinger 已提交
3432
				}
M
Mikael Emtinger 已提交
3433

M
Mikael Emtinger 已提交
3434
			}
M
Mikael Emtinger 已提交
3435

M
Mikael Emtinger 已提交
3436 3437
		}

3438

M
Mikael Emtinger 已提交
3439
		// setup color+stencil
M
Mikael Emtinger 已提交
3440

M
Mikael Emtinger 已提交
3441 3442 3443 3444
		_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 );
3445
		_gl.disable( _gl.DEPTH_TEST );
M
Mikael Emtinger 已提交
3446 3447


3448
		// draw darkening polygon
M
Mr.doob 已提交
3449

3450
		_oldBlending = -1;
M
Mikael Emtinger 已提交
3451
		_currentProgram = _stencilShadow.program;
M
Mr.doob 已提交
3452

M
Mikael Emtinger 已提交
3453 3454 3455
		_gl.useProgram( _stencilShadow.program );
		_gl.uniformMatrix4fv( _stencilShadow.projectionLocation, false, _projectionMatrixArray );
		_gl.uniform1f( _stencilShadow.darknessLocation, _stencilShadow.darkness );
3456

M
Mikael Emtinger 已提交
3457 3458 3459
		_gl.bindBuffer( _gl.ARRAY_BUFFER, _stencilShadow.vertexBuffer );
		_gl.vertexAttribPointer( _stencilShadow.vertexLocation, 3, _gl.FLOAT, false, 0, 0 );
		_gl.enableVertexAttribArray( _stencilShadow.vertexLocation );
M
Mr.doob 已提交
3460

M
Mikael Emtinger 已提交
3461 3462
		_gl.blendFunc( _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
		_gl.blendEquation( _gl.FUNC_ADD );
3463

M
Mikael Emtinger 已提交
3464
		_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _stencilShadow.elementBuffer );
M
Mikael Emtinger 已提交
3465 3466 3467 3468 3469
		_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );


		// disable stencil

3470 3471 3472 3473
		_gl.disable( _gl.STENCIL_TEST );
		_gl.enable( _gl.DEPTH_TEST );
		_gl.depthMask( _currentDepthMask );

M
Mikael Emtinger 已提交
3474
	}
3475

3476

3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495
	/*
	 * 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
3496

3497 3498
		_gl.useProgram( _sprite.program );
		_currentProgram = _sprite.program;
3499
		_oldBlending = -1;
3500

M
Mr.doob 已提交
3501
		if ( !_spriteAttributesEnabled ) {
3502

M
Mr.doob 已提交
3503 3504
			_gl.enableVertexAttribArray( _sprite.attributes.position );
			_gl.enableVertexAttribArray( _sprite.attributes.uv );
3505

M
Mr.doob 已提交
3506 3507 3508
			_spriteAttributesEnabled = true;

		}
3509

3510
		_gl.disable( _gl.CULL_FACE );
3511
		_gl.enable( _gl.BLEND );
3512
		_gl.depthMask( true );
3513 3514 3515 3516 3517 3518

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

3520 3521 3522 3523
		_gl.uniformMatrix4fv( uniforms.projectionMatrix, false, _projectionMatrixArray );

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

3525
		// update positions and sort
3526

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

3529
			object = scene.__webglSprites[ o ];
3530

3531
			if( !object.useScreenCoordinates ) {
3532

3533 3534
				object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
				object.z = -object._modelViewMatrix.n34;
3535

3536
			} else {
3537

3538
				object.z = -object.position.z;
3539

3540
			}
3541

3542 3543 3544
		}

		scene.__webglSprites.sort( painterSort );
3545 3546

		// render all non-custom shader sprites
3547 3548

		for ( o = 0, ol = scene.__webglSprites.length; o < ol; o++ ) {
3549 3550 3551

			object = scene.__webglSprites[ o ];

3552 3553 3554 3555 3556
			if ( object.material === undefined ) {

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

					if ( object.useScreenCoordinates ) {
3557 3558 3559 3560

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

3563 3564
					} else {

3565

3566 3567 3568 3569

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

3571
					}
3572

3573
					size = object.map.image.width / ( object.affectedByDistance ? 1 : _viewportHeight );
3574
					scale[ 0 ] = size * invAspect * object.scale.x;
3575
					scale[ 1 ] = size * object.scale.y;
3576

3577 3578 3579 3580 3581 3582 3583
					_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 );

3584 3585
					if ( object.mergeWith3D && !mergeWith3D ) {

3586 3587
						_gl.enable( _gl.DEPTH_TEST );
						mergeWith3D = true;
3588 3589 3590

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

3591 3592
						_gl.disable( _gl.DEPTH_TEST );
						mergeWith3D = false;
3593

3594
					}
3595

3596 3597
					setBlending( object.blending );
					setTexture( object.map, 0 );
3598

3599 3600
					_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
				}
3601

3602
			} else {
3603

3604
				anyCustom = true;
3605

3606
			}
3607

3608 3609 3610 3611 3612
		}


		// loop through all custom

3613 3614 3615
		/*
		if( anyCustom ) {

3616
		}
3617
		*/
3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628

		// restore gl

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

	}



3629 3630 3631 3632 3633 3634 3635 3636 3637 3638
	/*
	 * 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 ) {
3639

3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661
		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 已提交
3662
		_currentProgram = _lensFlare.program;
3663
		_oldBlending = -1;
3664 3665


M
Mr.doob 已提交
3666 3667 3668 3669 3670 3671 3672 3673 3674
		if ( ! _lensFlareAttributesEnabled ) {
		
			_gl.enableVertexAttribArray( _lensFlare.attributes.vertex );
			_gl.enableVertexAttribArray( _lensFlare.attributes.uv );
			
			_lensFlareAttributesEnabled = true;

		}

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

3678 3679
		_gl.uniform1i( uniforms.occlusionMap, 0 );
		_gl.uniform1i( uniforms.map, 1 );
3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690

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

3691 3692 3693 3694
		_gl.activeTexture( _gl.TEXTURE0 );
		_gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.occlusionTexture );

		_gl.activeTexture( _gl.TEXTURE1 );
3695

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

3698
			// calc object screen position
3699

3700
			object = scene.__webglLensFlares[ o ].object;
3701

3702
			tempPosition.set( object.matrixWorld.n14, object.matrixWorld.n24, object.matrixWorld.n34 );
3703

3704 3705 3706
			camera.matrixWorldInverse.multiplyVector3( tempPosition );
			objectZ = tempPosition.z;
			camera.projectionMatrix.multiplyVector3( tempPosition );
3707 3708


3709
			// setup arrays for gl programs
3710

3711 3712 3713
			screenPosition[ 0 ] = tempPosition.x;
			screenPosition[ 1 ] = tempPosition.y;
			screenPosition[ 2 ] = tempPosition.z;
3714

3715 3716
			screenPositionPixels[ 0 ] = screenPosition[ 0 ] * halfViewportWidth + halfViewportWidth;
			screenPositionPixels[ 1 ] = screenPosition[ 1 ] * halfViewportHeight + halfViewportHeight;
3717

3718

M
Mikael Emtinger 已提交
3719
			// screen cull 
3720 3721

			if ( _lensFlare.hasVertexTexture || ( screenPositionPixels[ 0 ] > 0 &&
3722 3723
				screenPositionPixels[ 0 ] < _viewportWidth &&
				screenPositionPixels[ 1 ] > 0 &&
3724
				screenPositionPixels[ 1 ] < _viewportHeight )) {
3725 3726


3727
				// save current RGB to temp texture
3728

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

3732

3733
				// render pink quad
3734

3735 3736 3737
				_gl.uniform1i( uniforms.renderType, 0 );
				_gl.uniform2fv( uniforms.scale, scale );
				_gl.uniform3fv( uniforms.screenPosition, screenPosition );
3738

3739 3740
				_gl.disable( _gl.BLEND );
				_gl.enable( _gl.DEPTH_TEST );
3741

3742
				_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
3743 3744


3745
				// copy result to occlusionMap
3746

3747
				_gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.occlusionTexture );
3748
				_gl.copyTexImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, screenPositionPixels[ 0 ] - 8, screenPositionPixels[ 1 ] - 8, 16, 16, 0 );
3749 3750


3751
				// restore graphics
3752

3753 3754 3755 3756
				_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 );
3757 3758


3759
				// update object positions
3760

3761 3762 3763
				object.positionScreen.x = screenPosition[ 0 ];
				object.positionScreen.y = screenPosition[ 1 ];
				object.positionScreen.z = screenPosition[ 2 ];
3764

3765
				if ( object.customUpdateCallback ) {
3766

3767
					object.customUpdateCallback( object );
3768

3769
				} else {
3770

3771
					object.updateLensFlares();
3772

3773
				}
3774 3775


3776
				// render flares
3777

3778 3779
				_gl.uniform1i( uniforms.renderType, 2 );
				_gl.enable( _gl.BLEND );
3780

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

3783
					flare = object.lensFlares[ f ];
3784

3785
					if ( flare.opacity > 0.001 && flare.scale > 0.001 ) {
3786

3787 3788 3789
						screenPosition[ 0 ] = flare.x;
						screenPosition[ 1 ] = flare.y;
						screenPosition[ 2 ] = flare.z;
3790

3791 3792 3793
						size = flare.size * flare.scale / _viewportHeight;
						scale[ 0 ] = size * invAspect;
						scale[ 1 ] = size;
3794

3795 3796 3797 3798
						_gl.uniform3fv( uniforms.screenPosition, screenPosition );
						_gl.uniform2fv( uniforms.scale, scale );
						_gl.uniform1f( uniforms.rotation, flare.rotation );
						_gl.uniform1f( uniforms.opacity, flare.opacity );
3799

3800 3801
						setBlending( flare.blending );
						setTexture( flare.texture, 1 );
3802

3803
						_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
3804

3805
					}
3806

3807
				}
3808

3809
			}
M
Mr.doob 已提交
3810

3811 3812 3813
		}

		// restore gl
3814

3815 3816
		_gl.enable( _gl.CULL_FACE );
		_gl.enable( _gl.DEPTH_TEST );
3817
		_gl.depthMask( _currentDepthMask );
3818

3819
	};
3820 3821


3822
	function setupMatrices( object, camera ) {
3823

3824 3825
		object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
		THREE.Matrix4.makeInvert3x3( object._modelViewMatrix ).transposeIntoArray( object._normalMatrixArray );
3826

3827
	};
3828

A
alteredq 已提交
3829
	this.initWebGLObjects = function ( scene ) {
3830

3831
		if ( !scene.__webglObjects ) {
3832

3833 3834
			scene.__webglObjects = [];
			scene.__webglObjectsImmediate = [];
M
Mikael Emtinger 已提交
3835
			scene.__webglShadowVolumes = [];
M
Mikael Emtinger 已提交
3836
			scene.__webglLensFlares = [];
M
Mikael Emtinger 已提交
3837
			scene.__webglSprites = [];
3838 3839
		}

M
Mr.doob 已提交
3840
		while ( scene.__objectsAdded.length ) {
3841

M
Mr.doob 已提交
3842 3843
			addObject( scene.__objectsAdded[ 0 ], scene );
			scene.__objectsAdded.splice( 0, 1 );
3844 3845 3846

		}

M
Mr.doob 已提交
3847
		while ( scene.__objectsRemoved.length ) {
3848

M
Mr.doob 已提交
3849 3850
			removeObject( scene.__objectsRemoved[ 0 ], scene );
			scene.__objectsRemoved.splice( 0, 1 );
3851 3852

		}
3853

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

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

M
Mr.doob 已提交
3858
			updateObject( scene.__webglObjects[ o ].object, scene );
A
alteredq 已提交
3859 3860

		}
3861

M
Mikael Emtinger 已提交
3862 3863 3864 3865 3866
		for ( var o = 0, ol = scene.__webglShadowVolumes.length; o < ol; o ++ ) {

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

		}
3867

M
Mikael Emtinger 已提交
3868 3869 3870 3871 3872
		for ( var o = 0, ol = scene.__webglLensFlares.length; o < ol; o ++ ) {

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

		}
A
alteredq 已提交
3873

3874 3875
		/*
		for ( var o = 0, ol = scene.__webglSprites.length; o < ol; o ++ ) {
M
Mikael Emtinger 已提交
3876 3877 3878

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

3879 3880
		}
		*/
M
Mikael Emtinger 已提交
3881

3882
	};
3883

3884
	function addObject( object, scene ) {
3885

3886
		var g, geometry, geometryGroup;
M
Mr.doob 已提交
3887

3888
		if ( object._modelViewMatrix == undefined ) {
3889

3890
			object._modelViewMatrix = new THREE.Matrix4();
3891

3892 3893 3894
			object._normalMatrixArray = new Float32Array( 9 );
			object._modelViewMatrixArray = new Float32Array( 16 );
			object._objectMatrixArray = new Float32Array( 16 );
3895

3896
			object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
3897

3898
		}
A
alteredq 已提交
3899

3900
		if ( object instanceof THREE.Mesh ) {
A
alteredq 已提交
3901

3902 3903 3904 3905 3906 3907 3908 3909
			geometry = object.geometry;

			if ( geometry.geometryGroups == undefined ) {

				sortFacesByMaterial( geometry );

			}

3910
			// create separate VBOs per geometry chunk
A
alteredq 已提交
3911

3912
			for ( g in geometry.geometryGroups ) {
A
alteredq 已提交
3913

3914
				geometryGroup = geometry.geometryGroups[ g ];
M
Mr.doob 已提交
3915

3916
				// initialise VBO on the first access
M
Mr.doob 已提交
3917

3918
				if ( ! geometryGroup.__webglVertexBuffer ) {
M
Mr.doob 已提交
3919

3920 3921
					createMeshBuffers( geometryGroup );
					initMeshBuffers( geometryGroup, object );
A
alteredq 已提交
3922

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

3931
				}
3932

3933
				// create separate wrapper per each use of VBO
3934

3935 3936
				if ( object instanceof THREE.ShadowVolume ) {

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

M
Mikael Emtinger 已提交
3939
				} else {
3940

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

M
Mikael Emtinger 已提交
3943
				}
3944

3945
			}
M
Mr.doob 已提交
3946

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

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

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

3953 3954
			geometry = object.geometry;

3955
			if( ! geometry.__webglVertexBuffer ) {
A
alteredq 已提交
3956 3957 3958 3959 3960 3961 3962 3963 3964

				createRibbonBuffers( geometry );
				initRibbonBuffers( geometry );

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

			}

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

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

3969 3970
			geometry = object.geometry;

3971
			if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
3972

3973 3974
				createLineBuffers( geometry );
				initLineBuffers( geometry );
M
Mr.doob 已提交
3975

3976 3977
				geometry.__dirtyVertices = true;
				geometry.__dirtyColors = true;
M
Mr.doob 已提交
3978

3979
			}
M
Mr.doob 已提交
3980

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

A
alteredq 已提交
3983 3984 3985 3986
		} else if ( object instanceof THREE.ParticleSystem ) {

			geometry = object.geometry;

3987
			if ( ! geometry.__webglVertexBuffer ) {
A
alteredq 已提交
3988 3989 3990 3991 3992 3993

				createParticleBuffers( geometry );
				initParticleBuffers( geometry );

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

3995
			}
3996

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

A
alteredq 已提交
3999 4000 4001 4002
		} else if ( THREE.MarchingCubes !== undefined && object instanceof THREE.MarchingCubes ) {

			addBufferImmediate( scene.__webglObjectsImmediate, object );

4003
		} else if ( object instanceof THREE.Sprite ) {
4004

4005 4006
			scene.__webglSprites.push( object );
		}
4007

4008
		/*else if ( object instanceof THREE.Particle ) {
A
alteredq 已提交
4009 4010 4011 4012 4013

		}*/

	};

4014
	function updateObject( object, scene ) {
A
alteredq 已提交
4015

4016
		var g, geometry, geometryGroup, a, customAttributeDirty;
A
alteredq 已提交
4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027

		if ( object instanceof THREE.Mesh ) {

			geometry = object.geometry;

			// check all geometry groups

			for ( g in geometry.geometryGroups ) {

				geometryGroup = geometry.geometryGroups[ g ];

4028 4029
				customAttributeDirty = false;

M
Mr.doob 已提交
4030 4031 4032 4033
				for ( a in geometryGroup.__webglCustomAttributes ) {

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

4034 4035
						customAttributeDirty = true;
						break;
A
alteredq 已提交
4036

4037
					}
M
Mr.doob 已提交
4038

4039 4040
				}

4041
				if ( geometry.__dirtyVertices || geometry.__dirtyMorphTargets || geometry.__dirtyElements ||
A
alteredq 已提交
4042
					geometry.__dirtyUvs || geometry.__dirtyNormals ||
4043
					geometry.__dirtyColors || geometry.__dirtyTangents || customAttributeDirty ) {
A
alteredq 已提交
4044 4045 4046 4047 4048 4049 4050

					setMeshBuffers( geometryGroup, object, _gl.DYNAMIC_DRAW );

				}

			}

4051
			geometry.__dirtyVertices = false;
4052
			geometry.__dirtyMorphTargets = false;
A
alteredq 已提交
4053 4054 4055 4056
			geometry.__dirtyElements = false;
			geometry.__dirtyUvs = false;
			geometry.__dirtyNormals = false;
			geometry.__dirtyTangents = false;
4057
			geometry.__dirtyColors = false;
M
Mr.doob 已提交
4058

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

4061 4062
			geometry = object.geometry;

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

A
alteredq 已提交
4065
				setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
4066

A
alteredq 已提交
4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078
			}

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

4080
			}
4081

A
alteredq 已提交
4082 4083 4084 4085 4086 4087 4088
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;

		} else if ( object instanceof THREE.ParticleSystem ) {

			geometry = object.geometry;

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

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

4093
			}
M
Mr.doob 已提交
4094

4095 4096
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
M
Mr.doob 已提交
4097

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

A
alteredq 已提交
4100
			// it updates itself in render callback
4101 4102

		} else if ( object instanceof THREE.Particle ) {
4103 4104

		}*/
4105

4106 4107 4108 4109 4110 4111
		/*
		delete geometry.vertices;
		delete geometry.faces;
		delete geometryGroup.faces;
		*/

4112
	};
4113

4114
	function removeObject( object, scene ) {
M
Mr.doob 已提交
4115 4116 4117

		var o, ol, zobject;

4118 4119 4120 4121 4122 4123 4124 4125 4126 4127
		if ( object instanceof THREE.Mesh ) {

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

				zobject = scene.__webglObjects[ o ].object;

				if ( object == zobject ) {

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

4129 4130 4131 4132 4133 4134 4135
				}

			}

		} else if ( object instanceof THREE.Sprite ) {

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

4137
				zobject = scene.__webglSprites[ o ];
M
Mr.doob 已提交
4138

4139 4140 4141 4142 4143 4144
				if ( object == zobject ) {

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

				}
M
Mr.doob 已提交
4145 4146 4147 4148

			}

		}
4149 4150

		// add shadows, etc
M
Mr.doob 已提交
4151 4152 4153

	};

4154
	function sortFacesByMaterial( geometry ) {
4155 4156 4157 4158 4159 4160 4161

		// 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 = {};
4162
		var numMorphTargets = geometry.morphTargets !== undefined ? geometry.morphTargets.length : 0;
4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204

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

4205
				geometry.geometryGroups[ ghash ] = { 'faces': [], 'materials': materials, 'vertices': 0, 'numMorphTargets': numMorphTargets };
4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217

			}

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

4218
					geometry.geometryGroups[ ghash ] = { 'faces': [], 'materials': materials, 'vertices': 0, 'numMorphTargets': numMorphTargets };
4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230

				}

			}

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

		}

	};

4231
	function addBuffer( objlist, buffer, object ) {
4232

4233 4234 4235 4236 4237
		objlist.push( {
			buffer: buffer, object: object,
			opaque: { list: [], count: 0 },
			transparent: { list: [], count: 0 }
		} );
M
Mr.doob 已提交
4238

4239
	};
4240

4241
	function addBufferImmediate( objlist, object ) {
4242

4243 4244 4245 4246 4247
		objlist.push( {
			object: object,
			opaque: { list: [], count: 0 },
			transparent: { list: [], count: 0 }
		} );
4248

4249
	};
4250

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

4253
		if ( cullFace ) {
M
Mr.doob 已提交
4254

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

4257
				_gl.frontFace( _gl.CCW );
M
Mr.doob 已提交
4258

4259
			} else {
M
Mr.doob 已提交
4260

4261
				_gl.frontFace( _gl.CW );
M
Mr.doob 已提交
4262

4263
			}
M
Mr.doob 已提交
4264

4265
			if( cullFace == "back" ) {
M
Mr.doob 已提交
4266

4267
				_gl.cullFace( _gl.BACK );
M
Mr.doob 已提交
4268

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

4271
				_gl.cullFace( _gl.FRONT );
M
Mr.doob 已提交
4272

4273
			} else {
M
Mr.doob 已提交
4274

4275
				_gl.cullFace( _gl.FRONT_AND_BACK );
M
Mr.doob 已提交
4276

4277
			}
M
Mr.doob 已提交
4278

4279
			_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
4280

4281
		} else {
M
Mr.doob 已提交
4282

4283
			_gl.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
4284

4285 4286 4287
		}

	};
N
Nicolas Garcia Belmonte 已提交
4288

4289
	this.supportsVertexTextures = function () {
4290

A
alteredq 已提交
4291
		return _supportsVertexTextures;
4292

4293
	};
4294

4295
	function maxVertexTextures() {
4296

4297 4298 4299
		return _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );

	};
4300

4301
	function buildProgram( shaderID, fragmentShader, vertexShader, uniforms, attributes, parameters ) {
4302

4303
		var p, pl, program, code;
4304
		var chunks = [];
4305 4306 4307

		// Generate code

4308 4309 4310 4311 4312 4313 4314 4315 4316 4317
		if ( shaderID ) {

			chunks.push( shaderID );

		} else {

			chunks.push( fragmentShader );
			chunks.push( vertexShader );

		}
4318 4319 4320

		for ( p in parameters ) {

4321 4322
			chunks.push( p );
			chunks.push( parameters[ p ] );
4323 4324 4325

		}

4326 4327
		code = chunks.join();

4328 4329 4330 4331 4332 4333 4334
		// 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*/ );
4335

4336 4337 4338 4339 4340
				return _programs[ p ].program;

			}

		}
4341

4342
		//console.log( "building new program " );
4343 4344 4345 4346

		//

		program = _gl.createProgram(),
M
Mr.doob 已提交
4347

M
Mr.doob 已提交
4348
		prefix_fragment = [
A
alteredq 已提交
4349

M
Mr.doob 已提交
4350 4351 4352
			"#ifdef GL_ES",
			"precision highp float;",
			"#endif",
M
Mr.doob 已提交
4353

4354 4355
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
A
alteredq 已提交
4356

4357 4358
			parameters.fog ? "#define USE_FOG" : "",
			parameters.fog instanceof THREE.FogExp2 ? "#define FOG_EXP2" : "",
4359

4360
			parameters.map ? "#define USE_MAP" : "",
4361 4362 4363
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
4364

4365
			"uniform mat4 viewMatrix;",
4366
			"uniform vec3 cameraPosition;",
M
Mr.doob 已提交
4367
			""
A
alteredq 已提交
4368

M
Mr.doob 已提交
4369
		].join("\n"),
4370

M
Mr.doob 已提交
4371
		prefix_vertex = [
A
alteredq 已提交
4372 4373
			
			_supportsVertexTextures ? "#define VERTEX_TEXTURES" : "",
4374

4375 4376 4377
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

4378 4379
			"#define MAX_BONES " + parameters.maxBones,

4380
			parameters.map ? "#define USE_MAP" : "",
4381 4382 4383
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
4384
			parameters.skinning ? "#define USE_SKINNING" : "",
4385
			parameters.morphTargets ? "#define USE_MORPHTARGETS" : "",
4386

4387 4388
			parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",

M
Mr.doob 已提交
4389 4390 4391
			"uniform mat4 objectMatrix;",
			"uniform mat4 modelViewMatrix;",
			"uniform mat4 projectionMatrix;",
4392 4393
			"uniform mat4 viewMatrix;",
			"uniform mat3 normalMatrix;",
M
Mr.doob 已提交
4394
			"uniform vec3 cameraPosition;",
A
alteredq 已提交
4395 4396 4397

			"uniform mat4 cameraInverseMatrix;",

M
Mr.doob 已提交
4398 4399 4400
			"attribute vec3 position;",
			"attribute vec3 normal;",
			"attribute vec2 uv;",
4401
			"attribute vec2 uv2;",
4402

4403
			"#ifdef USE_COLOR",
4404

4405
				"attribute vec3 color;",
4406

4407 4408
			"#endif",

4409
			"#ifdef USE_MORPHTARGETS",
4410

4411 4412 4413 4414 4415 4416 4417 4418
				"attribute vec3 morphTarget0;",
				"attribute vec3 morphTarget1;",
				"attribute vec3 morphTarget2;",
				"attribute vec3 morphTarget3;",
				"attribute vec3 morphTarget4;",
				"attribute vec3 morphTarget5;",
				"attribute vec3 morphTarget6;",
				"attribute vec3 morphTarget7;",
4419

4420 4421 4422
			"#endif",

			"#ifdef USE_SKINNING",
4423

4424 4425 4426 4427
				"attribute vec4 skinVertexA;",
				"attribute vec4 skinVertexB;",
				"attribute vec4 skinIndex;",
				"attribute vec4 skinWeight;",
4428

4429
			"#endif",
4430

M
Mr.doob 已提交
4431
			""
A
alteredq 已提交
4432

M
Mr.doob 已提交
4433
		].join("\n");
4434

4435 4436
		_gl.attachShader( program, getShader( "fragment", prefix_fragment + fragmentShader ) );
		_gl.attachShader( program, getShader( "vertex", prefix_vertex + vertexShader ) );
M
Mr.doob 已提交
4437

M
Mr.doob 已提交
4438
		_gl.linkProgram( program );
N
Nicolas Garcia Belmonte 已提交
4439

M
Mr.doob 已提交
4440
		if ( !_gl.getProgramParameter( program, _gl.LINK_STATUS ) ) {
N
Nicolas Garcia Belmonte 已提交
4441

4442
			console.error( "Could not initialise shader\n" + "VALIDATE_STATUS: " + _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) + ", gl error [" + _gl.getError() + "]" );
M
Mr.doob 已提交
4443

N
Nicolas Garcia Belmonte 已提交
4444
		}
4445

4446 4447
		//console.log( prefix_fragment + fragmentShader );
		//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
4448

M
Mr.doob 已提交
4449
		program.uniforms = {};
4450
		program.attributes = {};
M
Mr.doob 已提交
4451

4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469
		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 );
4470

4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493
		// 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 );

4494 4495
		_programs.push( { program: program, code: code } );

M
Mr.doob 已提交
4496
		return program;
M
Mr.doob 已提交
4497

M
Mr.doob 已提交
4498
	};
M
Mr.doob 已提交
4499

4500
	function loadUniformsSkinning( uniforms, object ) {
4501

M
Mr.doob 已提交
4502
		_gl.uniformMatrix4fv( uniforms.cameraInverseMatrix, false, _viewMatrixArray );
A
alteredq 已提交
4503
		_gl.uniformMatrix4fv( uniforms.boneGlobalMatrices, false, object.boneMatrices );
4504

4505
	};
4506

4507

4508
	function loadUniformsMatrices( uniforms, object ) {
4509

A
alteredq 已提交
4510 4511 4512 4513
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray );
		_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrixArray );

	};
4514

4515
	function loadUniformsGeneric( program, uniforms ) {
M
Mr.doob 已提交
4516

4517
		var u, uniform, value, type, location, texture;
M
Mr.doob 已提交
4518

M
Mr.doob 已提交
4519
		for( u in uniforms ) {
M
Mr.doob 已提交
4520

4521 4522
			location = program.uniforms[u];
			if ( !location ) continue;
M
Mr.doob 已提交
4523

4524
			uniform = uniforms[u];
M
Mr.doob 已提交
4525

4526 4527
			type = uniform.type;
			value = uniform.value;
M
Mr.doob 已提交
4528

M
Mr.doob 已提交
4529
			if( type == "i" ) {
M
Mr.doob 已提交
4530

M
Mr.doob 已提交
4531
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
4532

M
Mr.doob 已提交
4533
			} else if( type == "f" ) {
M
Mr.doob 已提交
4534

M
Mr.doob 已提交
4535
				_gl.uniform1f( location, value );
4536

A
alteredq 已提交
4537 4538 4539
			} else if( type == "fv1" ) {

				_gl.uniform1fv( location, value );
M
Mr.doob 已提交
4540

4541 4542 4543 4544
			} else if( type == "fv" ) {

				_gl.uniform3fv( location, value );

4545 4546 4547 4548
			} else if( type == "v2" ) {

				_gl.uniform2f( location, value.x, value.y );

4549 4550 4551
			} else if( type == "v3" ) {

				_gl.uniform3f( location, value.x, value.y, value.z );
4552

4553 4554 4555 4556
			} else if( type == "v4" ) {

				_gl.uniform4f( location, value.x, value.y, value.z, value.w );

4557 4558 4559
			} else if( type == "c" ) {

				_gl.uniform3f( location, value.r, value.g, value.b );
M
Mr.doob 已提交
4560

M
Mr.doob 已提交
4561
			} else if( type == "t" ) {
M
Mr.doob 已提交
4562

M
Mr.doob 已提交
4563
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
4564

4565
				texture = uniform.texture;
M
Mr.doob 已提交
4566

4567
				if ( !texture ) continue;
M
Mr.doob 已提交
4568

4569
				if ( texture.image instanceof Array && texture.image.length == 6 ) {
M
Mr.doob 已提交
4570

4571
					setCubeTexture( texture, value );
M
Mr.doob 已提交
4572

4573
				} else {
M
Mr.doob 已提交
4574

4575
					setTexture( texture, value );
M
Mr.doob 已提交
4576

4577
				}
M
Mr.doob 已提交
4578

4579
			}
M
Mr.doob 已提交
4580

4581
		}
M
Mr.doob 已提交
4582

4583
	};
M
Mr.doob 已提交
4584

4585
	function setBlending( blending ) {
A
alteredq 已提交
4586 4587

		if ( blending != _oldBlending ) {
4588

A
alteredq 已提交
4589 4590 4591 4592 4593
			switch ( blending ) {

				case THREE.AdditiveBlending:

					_gl.blendEquation( _gl.FUNC_ADD );
4594
					_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE );
A
alteredq 已提交
4595 4596 4597 4598 4599

					break;

				case THREE.SubtractiveBlending:

4600 4601 4602 4603
					// TODO: Find blendFuncSeparate() combination

					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.ZERO, _gl.ONE_MINUS_SRC_COLOR );
A
alteredq 已提交
4604 4605 4606

					break;

4607 4608 4609
				case THREE.MultiplyBlending:

					// TODO: Find blendFuncSeparate() combination
A
alteredq 已提交
4610 4611

					_gl.blendEquation( _gl.FUNC_ADD );
4612
					_gl.blendFunc( _gl.ZERO, _gl.SRC_COLOR );
A
alteredq 已提交
4613 4614 4615 4616 4617

					break;

				default:

4618 4619
					_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 已提交
4620 4621

					break;
4622

A
alteredq 已提交
4623
			}
4624

A
alteredq 已提交
4625
			_oldBlending = blending;
4626

A
alteredq 已提交
4627 4628 4629
		}

	};
4630

4631
	function setTextureParameters( textureType, texture, image ) {
4632

4633
		if ( isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ) ) {
M
Mr.doob 已提交
4634

4635 4636
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
M
Mr.doob 已提交
4637

4638 4639
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
M
Mr.doob 已提交
4640

4641
			_gl.generateMipmap( textureType );
M
Mr.doob 已提交
4642

4643
		} else {
M
Mr.doob 已提交
4644

4645 4646
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
4647

4648 4649
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
M
Mr.doob 已提交
4650

4651
		}
M
Mr.doob 已提交
4652

4653
	};
4654

4655
	function setTexture( texture, slot ) {
4656

4657
		/*
4658
		if ( texture.needsUpdate ) {
A
alteredq 已提交
4659

4660
			if ( !texture.__webglInit ) {
M
Mr.doob 已提交
4661

4662
				texture.__webglTexture = _gl.createTexture();
A
alteredq 已提交
4663

4664
				_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
4665
				_gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image );
M
Mr.doob 已提交
4666

4667
				texture.__webglInit = true;
M
Mr.doob 已提交
4668

A
alteredq 已提交
4669
			} else {
M
Mr.doob 已提交
4670

4671
				_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
4672 4673
				// _gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image );
				_gl.texSubImage2D( _gl.TEXTURE_2D, 0, 0, 0, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image );
M
Mr.doob 已提交
4674 4675 4676

			}

4677 4678
			setTextureParameters( _gl.TEXTURE_2D, texture, texture.image );
			_gl.bindTexture( _gl.TEXTURE_2D, null );
4679

A
alteredq 已提交
4680
			texture.needsUpdate = false;
4681 4682 4683 4684

		}

		_gl.activeTexture( _gl.TEXTURE0 + slot );
4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709
		_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
		*/

		if ( texture.needsUpdate ) {

			if ( texture.__webglTexture ) {

				texture.__webglTexture = _gl.deleteTexture( texture.__webglTexture );

			}

			texture.__webglTexture = _gl.createTexture();

			_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
			_gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image );

			setTextureParameters( _gl.TEXTURE_2D, texture, texture.image );

			_gl.bindTexture( _gl.TEXTURE_2D, null );

			texture.needsUpdate = false;

		}

		_gl.activeTexture( _gl.TEXTURE0 + slot );
4710
		_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
M
Mr.doob 已提交
4711

4712
	};
M
Mr.doob 已提交
4713

4714
	function setCubeTexture( texture, slot ) {
4715 4716 4717 4718 4719

		if ( texture.image.length == 6 ) {

			if ( texture.needsUpdate ) {

4720 4721 4722
				if ( !texture.__webglInit ) {

					texture.image.__webglTextureCube = _gl.createTexture();
4723

4724
					_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
4725

4726
					for ( var i = 0; i < 6; ++i ) {
4727

4728
						_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image[ i ] );
4729

4730
					}
4731 4732

					texture.__webglInit = true;
4733 4734 4735

				} else {

4736
					_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
4737

4738
					for ( var i = 0; i < 6; ++i ) {
4739

M
Mr.doob 已提交
4740
						// _gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image[ i ] );
4741
						_gl.texSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image[ i ] );
4742

4743
					}
4744 4745 4746

				}

4747
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, texture.image[0] );
4748 4749 4750
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );

				texture.needsUpdate = false;
4751

4752 4753 4754
			}

			_gl.activeTexture( _gl.TEXTURE0 + slot );
4755
			_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
4756 4757 4758 4759 4760

		}

	};

4761
	function setRenderTarget( renderTexture ) {
4762

4763
		if ( renderTexture && !renderTexture.__webglFramebuffer ) {
M
Mr.doob 已提交
4764

M
Mikael Emtinger 已提交
4765 4766 4767
			if( renderTexture.depthBuffer === undefined ) renderTexture.depthBuffer = true;
			if( renderTexture.stencilBuffer === undefined ) renderTexture.stencilBuffer = true;

4768 4769 4770
			renderTexture.__webglFramebuffer = _gl.createFramebuffer();
			renderTexture.__webglRenderbuffer = _gl.createRenderbuffer();
			renderTexture.__webglTexture = _gl.createTexture();
4771 4772 4773


			// Setup texture
M
Mr.doob 已提交
4774

4775
			_gl.bindTexture( _gl.TEXTURE_2D, renderTexture.__webglTexture );
4776 4777 4778 4779
			_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 ) );
4780
			_gl.texImage2D( _gl.TEXTURE_2D, 0, paramThreeToGL( renderTexture.format ), renderTexture.width, renderTexture.height, 0, paramThreeToGL( renderTexture.format ), paramThreeToGL( renderTexture.type ), null );
4781

M
Mikael Emtinger 已提交
4782
			// Setup render and frame buffer
M
Mr.doob 已提交
4783

M
Mikael Emtinger 已提交
4784
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderTexture.__webglRenderbuffer );
4785
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTexture.__webglFramebuffer );
M
Mikael Emtinger 已提交
4786

4787
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, renderTexture.__webglTexture, 0 );
4788 4789 4790

			if ( renderTexture.depthBuffer && !renderTexture.stencilBuffer ) {

M
Mikael Emtinger 已提交
4791 4792
				_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTexture.width, renderTexture.height );
				_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderTexture.__webglRenderbuffer );
4793 4794

			/* For some reason this is not working. Defaulting to RGBA4.	
M
Mikael Emtinger 已提交
4795
			} else if( !renderTexture.depthBuffer && renderTexture.stencilBuffer ) {
4796

M
Mikael Emtinger 已提交
4797 4798 4799 4800
				_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 ) {
4801

M
Mikael Emtinger 已提交
4802 4803
				_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTexture.width, renderTexture.height );
				_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderTexture.__webglRenderbuffer );
4804

M
Mikael Emtinger 已提交
4805
			} else {
4806

M
Mikael Emtinger 已提交
4807
				_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTexture.width, renderTexture.height );
4808

M
Mikael Emtinger 已提交
4809
			}
4810

4811 4812

			// Release everything
M
Mr.doob 已提交
4813

4814 4815 4816
			_gl.bindTexture( _gl.TEXTURE_2D, null );
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
M
Mr.doob 已提交
4817

4818 4819
		}

4820
		var framebuffer, width, height;
M
Mr.doob 已提交
4821

4822
		if ( renderTexture ) {
M
Mr.doob 已提交
4823

4824
			framebuffer = renderTexture.__webglFramebuffer;
4825 4826
			width = renderTexture.width;
			height = renderTexture.height;
M
Mr.doob 已提交
4827

4828
		} else {
M
Mr.doob 已提交
4829

4830
			framebuffer = null;
4831 4832
			width = _viewportWidth;
			height = _viewportHeight;
M
Mr.doob 已提交
4833

4834
		}
M
Mr.doob 已提交
4835

4836
		if ( framebuffer != _currentFramebuffer ) {
M
Mr.doob 已提交
4837

4838
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
4839
			_gl.viewport( _viewportX, _viewportY, width, height );
M
Mr.doob 已提交
4840

4841
			_currentFramebuffer = framebuffer;
M
Mr.doob 已提交
4842

4843
		}
4844

4845
	};
M
Mr.doob 已提交
4846

4847
	function updateRenderTargetMipmap( renderTarget ) {
M
Mr.doob 已提交
4848

4849
		_gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
4850 4851
		_gl.generateMipmap( _gl.TEXTURE_2D );
		_gl.bindTexture( _gl.TEXTURE_2D, null );
M
Mr.doob 已提交
4852 4853

	};
4854

4855
	function cacheUniformLocations( program, identifiers ) {
M
Mr.doob 已提交
4856

M
Mr.doob 已提交
4857
		var i, l, id;
M
Mr.doob 已提交
4858

M
Mr.doob 已提交
4859
		for( i = 0, l = identifiers.length; i < l; i++ ) {
M
Mr.doob 已提交
4860

4861 4862
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
4863

M
Mr.doob 已提交
4864
		}
M
Mr.doob 已提交
4865

M
Mr.doob 已提交
4866
	};
M
Mr.doob 已提交
4867

4868
	function cacheAttributeLocations( program, identifiers ) {
4869

4870
		var i, l, id;
M
Mr.doob 已提交
4871

4872
		for( i = 0, l = identifiers.length; i < l; i++ ) {
M
Mr.doob 已提交
4873

4874 4875
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
M
Mr.doob 已提交
4876

4877
		}
M
Mr.doob 已提交
4878

M
Mr.doob 已提交
4879
	};
M
Mr.doob 已提交
4880

4881
	function getShader( type, string ) {
N
Nicolas Garcia Belmonte 已提交
4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899

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

4900
			console.error( _gl.getShaderInfoLog( shader ) );
4901
			console.error( string );
N
Nicolas Garcia Belmonte 已提交
4902 4903 4904 4905 4906
			return null;

		}

		return shader;
M
Mr.doob 已提交
4907

4908
	};
N
Nicolas Garcia Belmonte 已提交
4909

4910
	// fallback filters for non-power-of-2 textures
4911

4912
	function filterFallback( f ) {
4913

4914 4915 4916 4917 4918 4919 4920 4921
		switch ( f ) {

			case THREE.NearestFilter:
			case THREE.NearestMipMapNearestFilter:
			case THREE.NearestMipMapLinearFilter: return _gl.NEAREST; break;

			case THREE.LinearFilter:
			case THREE.LinearMipMapNearestFilter:
M
Mikael Emtinger 已提交
4922 4923
			case THREE.LinearMipMapLinearFilter: 
			default:
4924

M
Mikael Emtinger 已提交
4925
				return _gl.LINEAR; break;
4926 4927

		}
4928

4929
	};
4930 4931

	function paramThreeToGL( p ) {
M
Mr.doob 已提交
4932

4933
		switch ( p ) {
M
Mr.doob 已提交
4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946

			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;

4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960
			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;

4961
		}
M
Mr.doob 已提交
4962

4963
		return 0;
M
Mr.doob 已提交
4964

4965 4966
	};

4967
	function isPowerOfTwo( value ) {
4968 4969 4970 4971 4972

		return ( value & ( value - 1 ) ) == 0;

	};

4973
	function materialNeedsSmoothNormals( material ) {
4974 4975 4976

		return material && material.shading != undefined && material.shading == THREE.SmoothShading;

4977
	};
M
Mr.doob 已提交
4978

4979
	function bufferNeedsSmoothNormals( geometryGroup, object ) {
M
Mr.doob 已提交
4980

4981
		var m, ml, i, l, meshMaterial, needsSmoothNormals = false;
M
Mr.doob 已提交
4982

M
Mr.doob 已提交
4983
		for ( m = 0, ml = object.materials.length; m < ml; m++ ) {
4984

M
Mr.doob 已提交
4985
			meshMaterial = object.materials[ m ];
4986 4987 4988

			if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {

4989
				for ( i = 0, l = geometryGroup.materials.length; i < l; i++ ) {
4990

4991
					if ( materialNeedsSmoothNormals( geometryGroup.materials[ i ] ) ) {
4992

4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013
						needsSmoothNormals = true;
						break;

					}

				}

			} else {

				if ( materialNeedsSmoothNormals( meshMaterial ) ) {

					needsSmoothNormals = true;
					break;

				}

			}

			if ( needsSmoothNormals ) break;

		}
M
Mr.doob 已提交
5014

5015
		return needsSmoothNormals;
M
Mr.doob 已提交
5016

5017
	};
M
Mr.doob 已提交
5018

5019
	function unrollGroupMaterials( geometryGroup, object ) {
5020

5021 5022 5023
		var m, ml, i, il,
			material, meshMaterial,
			materials = [];
5024

5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035
		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 ) {
5036

5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055
						materials.push( material );

					}

				}

			} else {

				material = meshMaterial;

				if ( material ) {

					materials.push( material );

				}

			}

		}
5056

5057 5058 5059
		return materials;

	};
5060

5061
	function bufferGuessVertexColorType( materials, geometryGroup, object ) {
5062

5063
		var i, m, ml = materials.length;
5064

5065
		// use vertexColor type from the first material in unrolled materials
5066

5067
		for ( i = 0; i < ml; i++ ) {
5068

5069
			m = materials[ i ];
5070

5071
			if ( m.vertexColors ) {
5072

5073 5074 5075
				return m.vertexColors;

			}
5076

5077
		}
5078

5079
		return false;
5080

5081 5082
	};

5083
	function bufferGuessNormalType( materials, geometryGroup, object ) {
5084

5085
		var i, m, ml = materials.length;
5086

5087
		// only MeshBasicMaterial and MeshDepthMaterial don't need normals
5088

5089
		for ( i = 0; i < ml; i++ ) {
5090

5091
			m = materials[ i ];
5092

A
alteredq 已提交
5093
			if ( ( m instanceof THREE.MeshBasicMaterial && !m.envMap ) || m instanceof THREE.MeshDepthMaterial ) continue;
5094

5095
			if ( materialNeedsSmoothNormals( m ) ) {
5096

5097 5098 5099 5100 5101 5102 5103 5104 5105
				return THREE.SmoothShading;

			} else {

				return THREE.FlatShading;

			}

		}
5106

5107
		return false;
5108

5109 5110
	};

5111
	function bufferGuessUVType( materials, geometryGroup, object ) {
5112

5113
		var i, m, ml = materials.length;
5114

5115
		// material must use some texture to require uvs
5116

5117
		for ( i = 0; i < ml; i++ ) {
5118

5119
			m = materials[ i ];
5120

A
alteredq 已提交
5121
			if ( m.map || m.lightMap || m instanceof THREE.MeshShaderMaterial ) {
5122

5123
				return true;
5124

5125
			}
5126

5127
		}
5128

5129
		return false;
5130

5131
	};
5132

5133
	function allocateBones( object ) {
5134

5135 5136 5137 5138 5139 5140 5141
		// 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)
5142

5143
		var maxBones = 50;
5144

5145
		if ( object !== undefined && object instanceof THREE.SkinnedMesh ) {
5146

5147 5148 5149 5150 5151
			maxBones = object.bones.length;

		}

		return maxBones;
5152

5153
	};
5154

5155
	function allocateLights( lights, maxLights ) {
5156

5157 5158
		var l, ll, light, dirLights, pointLights, maxDirLights, maxPointLights;
		dirLights = pointLights = maxDirLights = maxPointLights = 0;
5159

5160
		for ( l = 0, ll = lights.length; l < ll; l++ ) {
5161

5162
			light = lights[ l ];
5163

5164 5165
			if ( light instanceof THREE.DirectionalLight ) dirLights++;
			if ( light instanceof THREE.PointLight ) pointLights++;
5166

5167
		}
5168

5169
		if ( ( pointLights + dirLights ) <= maxLights ) {
5170

5171 5172
			maxDirLights = dirLights;
			maxPointLights = pointLights;
5173

5174
		} else {
5175

5176 5177
			maxDirLights = Math.ceil( maxLights * dirLights / ( pointLights + dirLights ) );
			maxPointLights = maxLights - maxDirLights;
5178 5179 5180

		}

5181
		return { 'directional' : maxDirLights, 'point' : maxPointLights };
5182 5183

	};
M
Mr.doob 已提交
5184

A
alteredq 已提交
5185
	/* DEBUG
5186
	function getGLParams() {
M
Mr.doob 已提交
5187

5188
		var params  = {
M
Mr.doob 已提交
5189

5190 5191
			'MAX_VARYING_VECTORS': _gl.getParameter( _gl.MAX_VARYING_VECTORS ),
			'MAX_VERTEX_ATTRIBS': _gl.getParameter( _gl.MAX_VERTEX_ATTRIBS ),
M
Mr.doob 已提交
5192

5193 5194 5195
			'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 已提交
5196

5197 5198 5199
			'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 已提交
5200

5201 5202
		return params;
	};
M
Mr.doob 已提交
5203

5204
	function dumpObject( obj ) {
M
Mr.doob 已提交
5205

5206 5207
		var p, str = "";
		for ( p in obj ) {
M
Mr.doob 已提交
5208

5209
			str += p + ": " + obj[p] + "\n";
M
Mr.doob 已提交
5210

5211
		}
M
Mr.doob 已提交
5212

5213 5214
		return str;
	}
A
alteredq 已提交
5215
	*/
5216
};
5217