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

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

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

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

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

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

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

23
	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,
35 36 37
	_oldPolygonOffset = null,
	_oldPolygonOffsetFactor = null,
	_oldPolygonOffsetUnits = null,
M
Mikael Emtinger 已提交
38
	_cullEnabled = true,
39

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

45
	// camera matrices caches
46 47

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

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

60
	_vector3 = new THREE.Vector4(),
61

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

A
alteredq 已提交
64 65
	_lights = {

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

	},

72
	// parameters
73

74
	parameters = parameters || {},
M
Mr.doob 已提交
75

76 77 78 79 80
	_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 已提交
81

82 83 84
	this.data = {

		vertices: 0,
85 86
		faces: 0,
		drawCalls: 0
87

88
	};
M
Mr.doob 已提交
89

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

95 96 97 98 99 100 101 102 103 104 105
	// shadow map

	this.shadowMapBias = 0.0039;
	this.shadowMapDarkness = 0.5;
	this.shadowMapWidth = 512;
	this.shadowMapHeight = 512;

	this.shadowCameraNear = 1;
	this.shadowCameraFar = 5000;
	this.shadowCameraFov = 50;

106
	this.shadowMap = [];
107
	this.shadowMapEnabled = false;
108
	this.shadowMapSoft = true;
109 110

	var _cameraLight,
111
		_shadowMatrix = [];
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128

	var depthShader = THREE.ShaderLib[ "depthRGBA" ];
	var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms );

	var _depthMaterial = new THREE.MeshShaderMaterial( { fragmentShader: depthShader.fragmentShader,
														 vertexShader: depthShader.vertexShader,
														 uniforms: depthUniforms } );

	var _depthMaterialMorph = new THREE.MeshShaderMaterial( { fragmentShader: depthShader.fragmentShader,
															  vertexShader: depthShader.vertexShader,
															  uniforms: depthUniforms,
															  morphTargets: true
															} );

	_depthMaterial._shadowPass = true;
	_depthMaterialMorph._shadowPass = true;

129 130 131 132 133 134 135 136 137 138
	// Init GL

	try {

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

			throw 'Error creating WebGL context.';

		}

M
Mr.doob 已提交
139 140 141 142 143 144 145 146
		console.log(
			navigator.userAgent + " | " +
			_gl.getParameter( _gl.VERSION ) + " | " +
			_gl.getParameter( _gl.VENDOR ) + " | " +
			_gl.getParameter( _gl.RENDERER ) + " | " +
			_gl.getParameter( _gl.SHADING_LANGUAGE_VERSION )
		);

147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
	} catch ( error ) {

		console.error( error );

	}

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

	_cullEnabled = true;

	//
M
Mr.doob 已提交
172

173 174
	this.context = _gl;

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

M
Mikael Emtinger 已提交
177
	// prepare stencil shadow polygon
M
Mikael Emtinger 已提交
178

179
	if ( _stencil ) {
M
Mr.doob 已提交
180

M
Mikael Emtinger 已提交
181
		var _stencilShadow      = {};
M
Mr.doob 已提交
182

M
Mikael Emtinger 已提交
183 184 185
		_stencilShadow.vertices = new Float32Array( 12 );
		_stencilShadow.faces    = new Uint16Array( 6 );
		_stencilShadow.darkness = 0.5;
M
Mr.doob 已提交
186

187 188 189 190
		_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 已提交
191

M
Mikael Emtinger 已提交
192 193
		_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 已提交
194

M
Mikael Emtinger 已提交
195 196
		_stencilShadow.vertexBuffer  = _gl.createBuffer();
		_stencilShadow.elementBuffer = _gl.createBuffer();
M
Mr.doob 已提交
197

M
Mikael Emtinger 已提交
198 199
		_gl.bindBuffer( _gl.ARRAY_BUFFER, _stencilShadow.vertexBuffer );
		_gl.bufferData( _gl.ARRAY_BUFFER,  _stencilShadow.vertices, _gl.STATIC_DRAW );
M
Mr.doob 已提交
200

M
Mikael Emtinger 已提交
201 202
		_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _stencilShadow.elementBuffer );
		_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, _stencilShadow.faces, _gl.STATIC_DRAW );
M
Mr.doob 已提交
203

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

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

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

M
Mikael Emtinger 已提交
211 212 213
		_stencilShadow.vertexLocation     = _gl.getAttribLocation ( _stencilShadow.program, "position"         );
		_stencilShadow.projectionLocation = _gl.getUniformLocation( _stencilShadow.program, "projectionMatrix" );
		_stencilShadow.darknessLocation   = _gl.getUniformLocation( _stencilShadow.program, "darkness"         );
M
Mr.doob 已提交
214

M
Mikael Emtinger 已提交
215
	}
M
Mr.doob 已提交
216 217


M
Mikael Emtinger 已提交
218
	// prepare lens flare
M
Mr.doob 已提交
219

M
Mikael Emtinger 已提交
220 221
	var _lensFlare = {};
	var i;
M
Mr.doob 已提交
222

M
Mikael Emtinger 已提交
223 224
	_lensFlare.vertices     = new Float32Array( 8 + 8 );
	_lensFlare.faces        = new Uint16Array( 6 );
M
Mr.doob 已提交
225

M
Mikael Emtinger 已提交
226 227 228
	i = 0;
	_lensFlare.vertices[ i++ ] = -1; _lensFlare.vertices[ i++ ] = -1;	// vertex
	_lensFlare.vertices[ i++ ] = 0;  _lensFlare.vertices[ i++ ] = 0;	// uv... etc.
M
Mr.doob 已提交
229

M
Mikael Emtinger 已提交
230 231
	_lensFlare.vertices[ i++ ] = 1;  _lensFlare.vertices[ i++ ] = -1;
	_lensFlare.vertices[ i++ ] = 1;  _lensFlare.vertices[ i++ ] = 0;
M
Mr.doob 已提交
232

M
Mikael Emtinger 已提交
233 234
	_lensFlare.vertices[ i++ ] = 1;  _lensFlare.vertices[ i++ ] = 1;
	_lensFlare.vertices[ i++ ] = 1;  _lensFlare.vertices[ i++ ] = 1;
M
Mr.doob 已提交
235

M
Mikael Emtinger 已提交
236 237 238 239 240 241 242
	_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;

243 244 245 246
	_lensFlare.vertexBuffer     = _gl.createBuffer();
	_lensFlare.elementBuffer    = _gl.createBuffer();
	_lensFlare.tempTexture      = _gl.createTexture();
	_lensFlare.occlusionTexture = _gl.createTexture();
M
Mr.doob 已提交
247

M
Mikael Emtinger 已提交
248 249
	_gl.bindBuffer( _gl.ARRAY_BUFFER, _lensFlare.vertexBuffer );
	_gl.bufferData( _gl.ARRAY_BUFFER,  _lensFlare.vertices, _gl.STATIC_DRAW );
M
Mikael Emtinger 已提交
250

M
Mikael Emtinger 已提交
251 252 253 254 255 256 257 258 259 260
	_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 );

261 262 263 264 265 266 267 268
	_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 ) {
269

270 271 272 273 274 275 276
		_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 );

277

278 279 280
	} else {

		_lensFlare.hasVertexTexture = true;
281

282 283 284 285
		_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 );
286

287
	}
M
Mikael Emtinger 已提交
288 289 290 291 292

	_lensFlare.attributes = {};
	_lensFlare.uniforms = {};
	_lensFlare.attributes.vertex       = _gl.getAttribLocation ( _lensFlare.program, "position" );
	_lensFlare.attributes.uv           = _gl.getAttribLocation ( _lensFlare.program, "UV" );
293
	_lensFlare.uniforms.renderType     = _gl.getUniformLocation( _lensFlare.program, "renderType" );
M
Mikael Emtinger 已提交
294
	_lensFlare.uniforms.map            = _gl.getUniformLocation( _lensFlare.program, "map" );
295
	_lensFlare.uniforms.occlusionMap   = _gl.getUniformLocation( _lensFlare.program, "occlusionMap" );
M
Mikael Emtinger 已提交
296 297 298 299 300
	_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 已提交
301 302
	//_gl.enableVertexAttribArray( _lensFlare.attributes.vertex );
	//_gl.enableVertexAttribArray( _lensFlare.attributes.uv );
303

M
Mr.doob 已提交
304
	var _lensFlareAttributesEnabled = false;
M
Mikael Emtinger 已提交
305

M
Mikael Emtinger 已提交
306
	// prepare sprites
M
Mr.doob 已提交
307 308

	var _sprite = {};
M
Mikael Emtinger 已提交
309 310 311 312 313

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

	i = 0;
M
Mr.doob 已提交
314 315 316 317 318 319 320 321 322 323 324 325

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

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

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

	_sprite.vertices[ i++ ] = -1; _sprite.vertices[ i++ ] = 1;	// vertex 3
	_sprite.vertices[ i++ ] = 0;  _sprite.vertices[ i++ ] = 0;	// uv 3
M
Mikael Emtinger 已提交
326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347

	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 = {};
348 349 350 351 352 353 354 355 356 357 358 359 360 361
	_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 已提交
362

M
Mr.doob 已提交
363 364
	//_gl.enableVertexAttribArray( _sprite.attributes.position );
	//_gl.enableVertexAttribArray( _sprite.attributes.uv );
M
Mikael Emtinger 已提交
365

M
Mr.doob 已提交
366
	var _spriteAttributesEnabled = false;
M
Mikael Emtinger 已提交
367

N
Nicolas Garcia Belmonte 已提交
368 369 370 371
	this.setSize = function ( width, height ) {

		_canvas.width = width;
		_canvas.height = height;
372

373 374 375
		this.setViewport( 0, 0, _canvas.width, _canvas.height );

	};
N
Nicolas Garcia Belmonte 已提交
376

377
	this.setViewport = function ( x, y, width, height ) {
378

379 380
		_viewportX = x;
		_viewportY = y;
381

382 383
		_viewportWidth = width;
		_viewportHeight = height;
384

385
		_gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight );
386

N
Nicolas Garcia Belmonte 已提交
387
	};
388

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

391
		_gl.scissor( x, y, width, height );
392

393
	};
394

395
	this.enableScissorTest = function ( enable ) {
396

397 398 399 400
		if ( enable )
			_gl.enable( _gl.SCISSOR_TEST );
		else
			_gl.disable( _gl.SCISSOR_TEST );
401

402
	};
403

404
	this.enableDepthBufferWrite = function ( enable ) {
405

406
		_currentDepthMask = enable;
407 408 409
		_gl.depthMask( enable );

	};
410

411
	this.setClearColorHex = function ( hex, alpha ) {
412

413 414 415 416
		_clearColor.setHex( hex );
		_clearAlpha = alpha;

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

418
	};
A
alteredq 已提交
419

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

422 423 424 425
		_clearColor.copy( color );
		_clearAlpha = alpha;

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

	};
428

N
Nicolas Garcia Belmonte 已提交
429 430
	this.clear = function () {

M
Mikael Emtinger 已提交
431
		_gl.clear( _gl.COLOR_BUFFER_BIT | _gl.DEPTH_BUFFER_BIT | _gl.STENCIL_BUFFER_BIT );
N
Nicolas Garcia Belmonte 已提交
432 433 434

	};

M
Mikael Emtinger 已提交
435
	this.setStencilShadowDarkness = function( value ) {
436

M
Mikael Emtinger 已提交
437
		_stencilShadow.darkness = value;
438

M
Mikael Emtinger 已提交
439 440
	};

441
	this.getContext = function() {
442

443
		return _gl;
444

445
	};
M
Mr.doob 已提交
446

A
alteredq 已提交
447
	function setupLights ( program, lights ) {
448

449 450
		var l, ll, light, n,
		r = 0, g = 0, b = 0,
451
		color, position, intensity, distance,
M
Mr.doob 已提交
452

453
		zlights = _lights,
M
Mr.doob 已提交
454

455
		dcolors = zlights.directional.colors,
456
		dpositions = zlights.directional.positions,
457

458
		pcolors = zlights.point.colors,
459
		ppositions = zlights.point.positions,
460
		pdistances = zlights.point.distances,
461

462 463
		dlength = 0,
		plength = 0,
464

465 466
		doffset = 0,
		poffset = 0;
M
Mr.doob 已提交
467

468
		for ( l = 0, ll = lights.length; l < ll; l++ ) {
469

470
			light = lights[ l ];
471
			color = light.color;
472

473 474
			position = light.position;
			intensity = light.intensity;
475
			distance = light.distance;
476 477 478

			if ( light instanceof THREE.AmbientLight ) {

479 480 481
				r += color.r;
				g += color.g;
				b += color.b;
M
Mr.doob 已提交
482

483
			} else if ( light instanceof THREE.DirectionalLight ) {
484

485
				doffset = dlength * 3;
486

487
				dcolors[ doffset ]     = color.r * intensity;
488 489
				dcolors[ doffset + 1 ] = color.g * intensity;
				dcolors[ doffset + 2 ] = color.b * intensity;
490

491
				dpositions[ doffset ]     = position.x;
492 493
				dpositions[ doffset + 1 ] = position.y;
				dpositions[ doffset + 2 ] = position.z;
494

495
				dlength += 1;
M
Mr.doob 已提交
496

497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512
			} else if ( light instanceof THREE.SpotLight ) { // hack, not a proper spotlight

				doffset = dlength * 3;

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

				n = 1 / position.length();

				dpositions[ doffset ]     = position.x * n;
				dpositions[ doffset + 1 ] = position.y * n;
				dpositions[ doffset + 2 ] = position.z * n;

				dlength += 1;

513 514
			} else if( light instanceof THREE.PointLight ) {

515
				poffset = plength * 3;
516

517
				pcolors[ poffset ]     = color.r * intensity;
518 519
				pcolors[ poffset + 1 ] = color.g * intensity;
				pcolors[ poffset + 2 ] = color.b * intensity;
520

521
				ppositions[ poffset ]     = position.x;
522 523
				ppositions[ poffset + 1 ] = position.y;
				ppositions[ poffset + 2 ] = position.z;
M
Mr.doob 已提交
524

525 526
				pdistances[ plength ] = distance;

527
				plength += 1;
M
Mr.doob 已提交
528

529 530 531
			}

		}
532

533 534
		// null eventual remains from removed lights
		// (this is to avoid if in shader)
535

536 537
		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 已提交
538

539 540
		zlights.point.length = plength;
		zlights.directional.length = dlength;
M
Mr.doob 已提交
541

542 543 544
		zlights.ambient[ 0 ] = r;
		zlights.ambient[ 1 ] = g;
		zlights.ambient[ 2 ] = b;
M
Mr.doob 已提交
545

546
	};
M
Mr.doob 已提交
547

548
	function createParticleBuffers ( geometry ) {
M
Mr.doob 已提交
549

550 551
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
M
Mr.doob 已提交
552

553
	};
M
Mr.doob 已提交
554

555
	function createLineBuffers( geometry ) {
M
Mr.doob 已提交
556

557 558
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
M
Mr.doob 已提交
559

560
	};
561

562
	function createRibbonBuffers( geometry ) {
A
alteredq 已提交
563

564 565
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
A
alteredq 已提交
566 567 568

	};

569
	function createMeshBuffers( geometryGroup ) {
M
Mr.doob 已提交
570

571 572 573 574 575 576
		geometryGroup.__webglVertexBuffer = _gl.createBuffer();
		geometryGroup.__webglNormalBuffer = _gl.createBuffer();
		geometryGroup.__webglTangentBuffer = _gl.createBuffer();
		geometryGroup.__webglColorBuffer = _gl.createBuffer();
		geometryGroup.__webglUVBuffer = _gl.createBuffer();
		geometryGroup.__webglUV2Buffer = _gl.createBuffer();
577

578 579 580 581 582 583 584 585 586
		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 ) {
587

588
			var m, ml;
M
Mr.doob 已提交
589
			geometryGroup.__webglMorphTargetsBuffers = [];
590 591 592 593 594

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

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

595 596 597
			}

		}
M
Mr.doob 已提交
598

599
	};
600

601
	function initLineBuffers ( geometry ) {
M
Mr.doob 已提交
602

603 604 605
		var nvertices = geometry.vertices.length;

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

608
		geometry.__webglLineCount = nvertices;
M
Mr.doob 已提交
609

610
	};
M
Mr.doob 已提交
611

612
	function initRibbonBuffers ( geometry ) {
A
alteredq 已提交
613 614 615 616 617 618

		var nvertices = geometry.vertices.length;

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

619
		geometry.__webglVertexCount = nvertices;
A
alteredq 已提交
620 621

	};
622

623
	function initParticleBuffers ( geometry, object ) {
624 625 626 627

		var nvertices = geometry.vertices.length;

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

630
		geometry.__sortArray = [];
631

632
		geometry.__webglParticleCount = nvertices;
633

634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699
		geometry.__materials = object.materials;

		// custom attributes

		var m, ml, material;

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

			material = object.materials[ m ];

			if ( material.attributes ) {

				if ( geometry.__webglCustomAttributes === undefined ) {

					geometry.__webglCustomAttributes = {};

				}

				for ( a in material.attributes ) {

					// Do a shallow copy of the attribute object so different geometryGroup chunks use different
					// attribute buffers which are correctly indexed in the setMeshBuffers function

					// Not sure how to best translate this into non-indexed arrays
					// used for particles, as there are no geometry chunks here
					// Probably could be simplified

					originalAttribute = material.attributes[ a ];

					attribute = {};

					for ( property in originalAttribute ) {

						attribute[ property ] = originalAttribute[ property ];

					}

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

						attribute.__webglInitialized = true;

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

						if( attribute.type === "v2" ) size = 2;
						else if( attribute.type === "v3" ) size = 3;
						else if( attribute.type === "v4" ) size = 4;
						else if( attribute.type === "c"  ) size = 3;

						attribute.size = size;
						attribute.array = new Float32Array( nvertices * size );
						attribute.buffer = _gl.createBuffer();
						attribute.buffer.belongsToAttribute = a;

						originalAttribute.needsUpdate = true;
						attribute.__original = originalAttribute;

					}

					geometry.__webglCustomAttributes[ a ] = attribute;

				}

			}

		}

700 701
	};

702
	function initMeshBuffers ( geometryGroup, object ) {
M
Mr.doob 已提交
703

M
Mikael Emtinger 已提交
704
		var f, fl, fi, face,
705
		m, ml, size,
706 707 708 709 710
		nvertices = 0, ntris = 0, nlines = 0,

		uvType,
		vertexColorType,
		normalType,
711 712
		materials, material,
		attribute, property, originalAttribute,
713 714 715 716

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

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

720 721
			fi = chunk_faces[ f ];
			face = obj_faces[ fi ];
M
Mr.doob 已提交
722

723
			if ( face instanceof THREE.Face3 ) {
M
Mr.doob 已提交
724

725 726 727
				nvertices += 3;
				ntris += 1;
				nlines += 3;
M
Mr.doob 已提交
728

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

731 732
				nvertices += 4;
				ntris += 2;
733
				nlines += 4;
M
Mr.doob 已提交
734

735
			}
M
Mr.doob 已提交
736

737
		}
738 739

		materials = unrollGroupMaterials( geometryGroup, object );
M
Mr.doob 已提交
740

741 742 743 744 745 746 747
		// this will not work if materials would change in run-time
		// it should be refreshed every frame
		// but need to do unrollGroupMaterials
		// more properly without push to array
		// like unrollBufferMaterials

		geometryGroup.__materials = materials;
748

749 750
		uvType = bufferGuessUVType( materials, geometryGroup, object );
		normalType = bufferGuessNormalType( materials, geometryGroup, object );
A
alteredq 已提交
751 752
		vertexColorType = bufferGuessVertexColorType( materials, geometryGroup, object );

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

755
		geometryGroup.__vertexArray = new Float32Array( nvertices * 3 );
756

757
		if ( normalType ) {
M
Mr.doob 已提交
758

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

761
		}
762

763
		if ( geometry.hasTangents ) {
764

765
			geometryGroup.__tangentArray = new Float32Array( nvertices * 4 );
766

767
		}
768

769
		if ( vertexColorType ) {
770

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

773
		}
M
Mr.doob 已提交
774

775
		if ( uvType ) {
776

777
			if ( geometry.faceUvs.length > 0 || geometry.faceVertexUvs.length > 0 ) {
778

779 780 781 782 783
				geometryGroup.__uvArray = new Float32Array( nvertices * 2 );

			}

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

785 786 787 788 789 790 791 792 793 794 795 796 797 798 799
				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 已提交
800
		geometryGroup.__faceArray = new Uint16Array( ntris * 3 + ( object.geometry.edgeFaces ? object.geometry.edgeFaces.length * 2 * 3 : 0 ));
801
		geometryGroup.__lineArray = new Uint16Array( nlines * 2 );
M
Mr.doob 已提交
802

803 804
		if ( geometryGroup.numMorphTargets ) {

M
Mr.doob 已提交
805
			geometryGroup.__morphTargetsArrays = [];
806 807 808

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

809 810
				geometryGroup.__morphTargetsArrays.push( new Float32Array( nvertices * 3 ) );

811 812 813
			}

		}
814

815
		geometryGroup.__needsSmoothNormals = ( normalType == THREE.SmoothShading );
816

817 818 819 820
		geometryGroup.__uvType = uvType;
		geometryGroup.__vertexColorType = vertexColorType;
		geometryGroup.__normalType = normalType;

821 822
		geometryGroup.__webglFaceCount = ntris * 3 + ( object.geometry.edgeFaces ? object.geometry.edgeFaces.length * 2 * 3 : 0 );
		geometryGroup.__webglLineCount = nlines * 2;
823

M
Mr.doob 已提交
824

825
		// custom attributes
M
Mr.doob 已提交
826 827 828

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

829 830 831
			material = materials[ m ];

			if ( material.attributes ) {
M
Mr.doob 已提交
832

833 834 835 836 837
				if ( geometryGroup.__webglCustomAttributes === undefined ) {

					geometryGroup.__webglCustomAttributes = {};

				}
838

839 840 841 842 843 844
				for ( a in material.attributes ) {

					// Do a shallow copy of the attribute object so different geometryGroup chunks use different
					// attribute buffers which are correctly indexed in the setMeshBuffers function

					originalAttribute = material.attributes[ a ];
M
Mr.doob 已提交
845

846
					attribute = {};
847 848 849 850 851

					for ( property in originalAttribute ) {

						attribute[ property ] = originalAttribute[ property ];

852
					}
M
Mr.doob 已提交
853

854
					if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
855

856
						attribute.__webglInitialized = true;
857

858
						size = 1;		// "f" and "i"
859

860 861 862 863
						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;
864

865 866 867
						attribute.size = size;
						attribute.array = new Float32Array( nvertices * size );
						attribute.buffer = _gl.createBuffer();
868
						attribute.buffer.belongsToAttribute = a;
M
Mr.doob 已提交
869

870 871
						originalAttribute.needsUpdate = true;
						attribute.__original = originalAttribute;
872

873
					}
874 875 876 877 878 879

					geometryGroup.__webglCustomAttributes[ a ] = attribute;

				}

			}
M
Mr.doob 已提交
880

881
		}
882

883 884
		geometryGroup.__inittedArrays = true;

885
	};
M
Mr.doob 已提交
886

887

888
	function setMeshBuffers ( geometryGroup, object, hint ) {
889

890 891 892 893 894 895 896
		if ( ! geometryGroup.__inittedArrays ) {

			// console.log( object );
			return;

		}

M
Mr.doob 已提交
897
		var f, fl, fi, face,
898 899 900 901 902 903 904 905 906 907 908 909 910
		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,
911
		a,
M
Mr.doob 已提交
912

913
		vertexIndex = 0,
914

915 916
		offset = 0,
		offset_uv = 0,
917
		offset_uv2 = 0,
918 919 920 921
		offset_face = 0,
		offset_normal = 0,
		offset_tangent = 0,
		offset_line = 0,
922
		offset_color = 0,
A
alteredq 已提交
923
		offset_skin = 0,
924
		offset_morphTarget = 0,
925
		offset_custom = 0,
926
		offset_customSrc = 0,
M
Mr.doob 已提交
927

928 929 930 931 932 933
		vertexArray = geometryGroup.__vertexArray,
		uvArray = geometryGroup.__uvArray,
		uv2Array = geometryGroup.__uv2Array,
		normalArray = geometryGroup.__normalArray,
		tangentArray = geometryGroup.__tangentArray,
		colorArray = geometryGroup.__colorArray,
934

935 936 937 938
		skinVertexAArray = geometryGroup.__skinVertexAArray,
		skinVertexBArray = geometryGroup.__skinVertexBArray,
		skinIndexArray = geometryGroup.__skinIndexArray,
		skinWeightArray = geometryGroup.__skinWeightArray,
M
Mr.doob 已提交
939

940 941
		morphTargetsArrays = geometryGroup.__morphTargetsArrays,

942 943
		customAttributes = geometryGroup.__webglCustomAttributes,
		customAttribute,
944

945 946
		faceArray = geometryGroup.__faceArray,
		lineArray = geometryGroup.__lineArray,
M
Mr.doob 已提交
947

948
		needsSmoothNormals = geometryGroup.__needsSmoothNormals,
949

950
		vertexColorType = geometryGroup.__vertexColorType,
A
alteredq 已提交
951 952
		uvType = geometryGroup.__uvType,
		normalType = geometryGroup.__normalType,
953

954
		geometry = object.geometry, // this is shared for all chunks
955

956
		dirtyVertices = geometry.__dirtyVertices,
957 958 959
		dirtyElements = geometry.__dirtyElements,
		dirtyUvs = geometry.__dirtyUvs,
		dirtyNormals = geometry.__dirtyNormals,
960
		dirtyTangents = geometry.__dirtyTangents,
961
		dirtyColors = geometry.__dirtyColors,
962
		dirtyMorphTargets = geometry.__dirtyMorphTargets,
M
Mr.doob 已提交
963

964
		vertices = geometry.vertices,
965
		chunk_faces = geometryGroup.faces,
966
		obj_faces = geometry.faces,
967

968 969
		obj_uvs  = geometry.faceVertexUvs[ 0 ],
		obj_uvs2 = geometry.faceVertexUvs[ 1 ],
970

A
alteredq 已提交
971
		obj_colors = geometry.colors,
972

A
alteredq 已提交
973 974 975
		obj_skinVerticesA = geometry.skinVerticesA,
		obj_skinVerticesB = geometry.skinVerticesB,
		obj_skinIndices = geometry.skinIndices,
976
		obj_skinWeights = geometry.skinWeights,
977

978
		obj_edgeFaces = object instanceof THREE.ShadowVolume ? geometry.edgeFaces : undefined,
979 980

		morphTargets = geometry.morphTargets;
981

982
		if ( customAttributes ) {
M
Mr.doob 已提交
983

984
			for ( a in customAttributes ) {
M
Mr.doob 已提交
985

986
				customAttributes[ a ].offset = 0;
987
				customAttributes[ a ].offsetSrc = 0;
M
Mr.doob 已提交
988

989 990
			}

M
Mr.doob 已提交
991
		}
992 993


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

996 997
			fi = chunk_faces[ f ];
			face = obj_faces[ fi ];
998 999

			if ( obj_uvs ) {
A
alteredq 已提交
1000 1001 1002 1003

				uv = obj_uvs[ fi ];

			}
1004 1005 1006

			if ( obj_uvs2 ) {

A
alteredq 已提交
1007 1008 1009
				uv2 = obj_uvs2[ fi ];

			}
M
Mr.doob 已提交
1010

1011
			vertexNormals = face.vertexNormals;
1012
			faceNormal = face.normal;
1013

1014 1015
			vertexColors = face.vertexColors;
			faceColor = face.color;
1016

1017
			vertexTangents = face.vertexTangents;
1018 1019 1020

			if ( face instanceof THREE.Face3 ) {

1021
				if ( dirtyVertices ) {
M
Mr.doob 已提交
1022

1023 1024 1025
					v1 = vertices[ face.a ].position;
					v2 = vertices[ face.b ].position;
					v3 = vertices[ face.c ].position;
M
Mr.doob 已提交
1026

1027 1028 1029
					vertexArray[ offset ]     = v1.x;
					vertexArray[ offset + 1 ] = v1.y;
					vertexArray[ offset + 2 ] = v1.z;
M
Mr.doob 已提交
1030

1031 1032 1033
					vertexArray[ offset + 3 ] = v2.x;
					vertexArray[ offset + 4 ] = v2.y;
					vertexArray[ offset + 5 ] = v2.z;
1034

1035 1036 1037
					vertexArray[ offset + 6 ] = v3.x;
					vertexArray[ offset + 7 ] = v3.y;
					vertexArray[ offset + 8 ] = v3.z;
M
Mr.doob 已提交
1038

1039
					offset += 9;
M
Mr.doob 已提交
1040

1041
				}
1042

1043
				if ( customAttributes ) {
M
Mr.doob 已提交
1044

1045
					for ( a in customAttributes ) {
M
Mr.doob 已提交
1046

1047
						customAttribute = customAttributes[ a ];
M
Mr.doob 已提交
1048

1049
						if ( customAttribute.__original.needsUpdate ) {
M
Mr.doob 已提交
1050

1051
							offset_custom = customAttribute.offset;
1052
							offset_customSrc = customAttribute.offsetSrc;
M
Mr.doob 已提交
1053

1054 1055 1056
							if ( customAttribute.size === 1 ) {

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

1058 1059 1060
									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 ];
1061 1062 1063

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

1064 1065 1066 1067
									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 ];

1068 1069 1070 1071
									customAttribute.offsetSrc ++;

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

1072 1073 1074
									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 ];
1075

1076
									customAttribute.offsetSrc += 3;
1077

1078
								}
M
Mr.doob 已提交
1079

1080
								customAttribute.offset += 3;
M
Mr.doob 已提交
1081

1082
							} else {
M
Mr.doob 已提交
1083

1084 1085
								if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {

1086 1087 1088
									v1 = customAttribute.value[ face.a ];
									v2 = customAttribute.value[ face.b ];
									v3 = customAttribute.value[ face.c ];
1089 1090 1091

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

1092 1093 1094 1095
									v1 = customAttribute.value[ offset_customSrc ];
									v2 = customAttribute.value[ offset_customSrc ];
									v3 = customAttribute.value[ offset_customSrc ];

1096 1097 1098 1099
									customAttribute.offsetSrc ++;

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

1100 1101 1102
									v1 = customAttribute.value[ offset_customSrc + 0 ];
									v2 = customAttribute.value[ offset_customSrc + 1 ];
									v3 = customAttribute.value[ offset_customSrc + 2 ];
1103

1104 1105
									customAttribute.offsetSrc += 3;
								}
M
Mr.doob 已提交
1106

1107 1108

								if ( customAttribute.size === 2 ) {
M
Mr.doob 已提交
1109 1110 1111

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

M
Mr.doob 已提交
1113 1114
									customAttribute.array[ offset_custom + 2 ] = v2.x;
									customAttribute.array[ offset_custom + 3 ] = v2.y;
1115

M
Mr.doob 已提交
1116
									customAttribute.array[ offset_custom + 4 ] = v3.x;
1117
									customAttribute.array[ offset_custom + 5 ] = v3.y;
M
Mr.doob 已提交
1118

1119
									customAttribute.offset += 6;
M
Mr.doob 已提交
1120

1121 1122 1123
								} else if ( customAttribute.size === 3 ) {

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

1125 1126 1127
										customAttribute.array[ offset_custom + 0 ] = v1.r;
										customAttribute.array[ offset_custom + 1 ] = v1.g;
										customAttribute.array[ offset_custom + 2 ] = v1.b;
1128

1129 1130 1131
										customAttribute.array[ offset_custom + 3 ] = v2.r;
										customAttribute.array[ offset_custom + 4 ] = v2.g;
										customAttribute.array[ offset_custom + 5 ] = v2.b;
1132

1133 1134 1135
										customAttribute.array[ offset_custom + 6 ] = v3.r;
										customAttribute.array[ offset_custom + 7 ] = v3.g;
										customAttribute.array[ offset_custom + 8 ] = v3.b;
1136

1137
									} else {
1138

1139 1140 1141
										customAttribute.array[ offset_custom + 0 ] = v1.x;
										customAttribute.array[ offset_custom + 1 ] = v1.y;
										customAttribute.array[ offset_custom + 2 ] = v1.z;
1142

1143 1144 1145
										customAttribute.array[ offset_custom + 3 ] = v2.x;
										customAttribute.array[ offset_custom + 4 ] = v2.y;
										customAttribute.array[ offset_custom + 5 ] = v2.z;
1146

1147 1148 1149
										customAttribute.array[ offset_custom + 6 ] = v3.x;
										customAttribute.array[ offset_custom + 7 ] = v3.y;
										customAttribute.array[ offset_custom + 8 ] = v3.z;
1150

1151
									}
M
Mr.doob 已提交
1152

1153
									customAttribute.offset += 9;
M
Mr.doob 已提交
1154

1155
								} else {
M
Mr.doob 已提交
1156 1157 1158 1159 1160

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

M
Mr.doob 已提交
1162 1163 1164 1165
									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;
1166

M
Mr.doob 已提交
1167
									customAttribute.array[ offset_custom + 8  ] = v3.x;
1168 1169 1170
									customAttribute.array[ offset_custom + 9  ] = v3.y;
									customAttribute.array[ offset_custom + 10 ] = v3.z;
									customAttribute.array[ offset_custom + 11 ] = v3.w;
M
Mr.doob 已提交
1171

1172
									customAttribute.offset += 12;
M
Mr.doob 已提交
1173

1174
								}
M
Mr.doob 已提交
1175

1176
							}
M
Mr.doob 已提交
1177

1178
						}
M
Mr.doob 已提交
1179

1180
					}
M
Mr.doob 已提交
1181

1182 1183 1184
				}


1185
				if ( dirtyMorphTargets ) {
1186 1187 1188

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

1189 1190 1191
						v1 = morphTargets[ vk ].vertices[ face.a ].position;
						v2 = morphTargets[ vk ].vertices[ face.b ].position;
						v3 = morphTargets[ vk ].vertices[ face.c ].position;
1192

1193
						vka = morphTargetsArrays[ vk ];
1194

1195 1196 1197
						vka[ offset_morphTarget + 0 ] = v1.x;
						vka[ offset_morphTarget + 1 ] = v1.y;
						vka[ offset_morphTarget + 2 ] = v1.z;
1198

1199 1200 1201
						vka[ offset_morphTarget + 3 ] = v2.x;
						vka[ offset_morphTarget + 4 ] = v2.y;
						vka[ offset_morphTarget + 5 ] = v2.z;
1202

1203 1204 1205
						vka[ offset_morphTarget + 6 ] = v3.x;
						vka[ offset_morphTarget + 7 ] = v3.y;
						vka[ offset_morphTarget + 8 ] = v3.z;
1206 1207
					}

1208
					offset_morphTarget += 9;
1209

1210 1211
				}

A
alteredq 已提交
1212 1213 1214
				if ( obj_skinWeights.length ) {

					// weights
1215

A
alteredq 已提交
1216 1217 1218
					sw1 = obj_skinWeights[ face.a ];
					sw2 = obj_skinWeights[ face.b ];
					sw3 = obj_skinWeights[ face.c ];
1219

A
alteredq 已提交
1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235
					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
1236

A
alteredq 已提交
1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256
					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
1257

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

A
alteredq 已提交
1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298
					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;
1299

A
alteredq 已提交
1300
				}
1301

1302 1303 1304
				if ( dirtyColors && vertexColorType ) {

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

1306 1307 1308 1309 1310
						c1 = vertexColors[ 0 ];
						c2 = vertexColors[ 1 ];
						c3 = vertexColors[ 2 ];

					} else {
1311

1312 1313 1314 1315 1316
						c1 = faceColor;
						c2 = faceColor;
						c3 = faceColor;

					}
1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328

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

1330 1331 1332 1333
					offset_color += 9;

				}

1334
				if ( dirtyTangents && geometry.hasTangents ) {
1335

1336 1337 1338
					t1 = vertexTangents[ 0 ];
					t2 = vertexTangents[ 1 ];
					t3 = vertexTangents[ 2 ];
1339

1340 1341 1342 1343
					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 已提交
1344

1345 1346 1347 1348
					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 已提交
1349

1350 1351 1352 1353
					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 已提交
1354

1355
					offset_tangent += 12;
M
Mr.doob 已提交
1356

1357 1358
				}

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

1361 1362 1363
					if ( vertexNormals.length == 3 && needsSmoothNormals ) {

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

1365
							vn = vertexNormals[ i ];
M
Mr.doob 已提交
1366

1367 1368 1369
							normalArray[ offset_normal ]     = vn.x;
							normalArray[ offset_normal + 1 ] = vn.y;
							normalArray[ offset_normal + 2 ] = vn.z;
M
Mr.doob 已提交
1370

1371
							offset_normal += 3;
M
Mr.doob 已提交
1372

1373
						}
M
Mr.doob 已提交
1374

1375
					} else {
1376

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

1379 1380 1381
							normalArray[ offset_normal ]     = faceNormal.x;
							normalArray[ offset_normal + 1 ] = faceNormal.y;
							normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
1382

1383
							offset_normal += 3;
M
Mr.doob 已提交
1384

1385
						}
M
Mr.doob 已提交
1386 1387

					}
M
Mr.doob 已提交
1388

1389 1390
				}

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

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

1395
						uvi = uv[ i ];
M
Mr.doob 已提交
1396

1397 1398
						uvArray[ offset_uv ]     = uvi.u;
						uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
1399

1400
						offset_uv += 2;
M
Mr.doob 已提交
1401

M
Mr.doob 已提交
1402
					}
1403 1404 1405

				}

A
alteredq 已提交
1406
				if ( dirtyUvs && uv2 !== undefined && uvType ) {
1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420

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

						uv2i = uv2[ i ];

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

						offset_uv2 += 2;

					}

				}

1421
				if ( dirtyElements ) {
M
Mr.doob 已提交
1422

1423 1424 1425
					faceArray[ offset_face ] = vertexIndex;
					faceArray[ offset_face + 1 ] = vertexIndex + 1;
					faceArray[ offset_face + 2 ] = vertexIndex + 2;
M
Mr.doob 已提交
1426

1427
					offset_face += 3;
M
Mr.doob 已提交
1428

1429 1430
					lineArray[ offset_line ]     = vertexIndex;
					lineArray[ offset_line + 1 ] = vertexIndex + 1;
M
Mr.doob 已提交
1431

1432 1433
					lineArray[ offset_line + 2 ] = vertexIndex;
					lineArray[ offset_line + 3 ] = vertexIndex + 2;
M
Mr.doob 已提交
1434

1435 1436
					lineArray[ offset_line + 4 ] = vertexIndex + 1;
					lineArray[ offset_line + 5 ] = vertexIndex + 2;
M
Mr.doob 已提交
1437

1438
					offset_line += 6;
1439

1440
					vertexIndex += 3;
M
Mr.doob 已提交
1441

1442
				}
M
Mr.doob 已提交
1443

1444 1445 1446

			} else if ( face instanceof THREE.Face4 ) {

1447
				if ( dirtyVertices ) {
M
Mr.doob 已提交
1448

1449 1450 1451 1452
					v1 = vertices[ face.a ].position;
					v2 = vertices[ face.b ].position;
					v3 = vertices[ face.c ].position;
					v4 = vertices[ face.d ].position;
M
Mr.doob 已提交
1453

1454 1455 1456
					vertexArray[ offset ]     = v1.x;
					vertexArray[ offset + 1 ] = v1.y;
					vertexArray[ offset + 2 ] = v1.z;
M
Mr.doob 已提交
1457

1458 1459 1460
					vertexArray[ offset + 3 ] = v2.x;
					vertexArray[ offset + 4 ] = v2.y;
					vertexArray[ offset + 5 ] = v2.z;
1461

1462 1463 1464
					vertexArray[ offset + 6 ] = v3.x;
					vertexArray[ offset + 7 ] = v3.y;
					vertexArray[ offset + 8 ] = v3.z;
1465

1466
					vertexArray[ offset + 9 ]  = v4.x;
1467 1468
					vertexArray[ offset + 10 ] = v4.y;
					vertexArray[ offset + 11 ] = v4.z;
M
Mr.doob 已提交
1469

1470
					offset += 12;
M
Mr.doob 已提交
1471

1472
				}
1473

1474
				if ( customAttributes ) {
M
Mr.doob 已提交
1475

1476
					for ( a in customAttributes ) {
M
Mr.doob 已提交
1477

1478 1479
						customAttribute = customAttributes[ a ];

1480
						if ( customAttribute.__original.needsUpdate ) {
1481 1482

							offset_custom = customAttribute.offset;
1483
							offset_customSrc = customAttribute.offsetSrc;
M
Mr.doob 已提交
1484

1485 1486 1487
							if ( customAttribute.size === 1 ) {

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

1489 1490 1491
									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 已提交
1492
									customAttribute.array[ offset_custom + 3 ] = customAttribute.value[ face.d ];
1493 1494 1495

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

1496 1497 1498
									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 已提交
1499
									customAttribute.array[ offset_custom + 3 ] = customAttribute.value[ offset_customSrc ];
1500 1501

									customAttribute.offsetSrc++;
1502 1503 1504

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

1505 1506 1507
									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 已提交
1508
									customAttribute.array[ offset_custom + 3 ] = customAttribute.value[ offset_customSrc + 3 ];
1509

1510
									customAttribute.offsetSrc += 4;
1511

1512
								}
M
Mr.doob 已提交
1513

1514
								customAttribute.offset += 4;
M
Mr.doob 已提交
1515

1516
							} else {
M
Mr.doob 已提交
1517

1518 1519
								if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {

1520 1521 1522 1523
									v1 = customAttribute.value[ face.a ];
									v2 = customAttribute.value[ face.b ];
									v3 = customAttribute.value[ face.c ];
									v4 = customAttribute.value[ face.d ];
1524 1525 1526

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

1527 1528 1529 1530 1531 1532
									v1 = customAttribute.value[ offset_customSrc ];
									v2 = customAttribute.value[ offset_customSrc ];
									v3 = customAttribute.value[ offset_customSrc ];
									v4 = customAttribute.value[ offset_customSrc ];

									customAttribute.offsetSrc++;
1533 1534 1535

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

1536 1537 1538 1539
									v1 = customAttribute.value[ offset_customSrc + 0 ];
									v2 = customAttribute.value[ offset_customSrc + 1 ];
									v3 = customAttribute.value[ offset_customSrc + 2 ];
									v4 = customAttribute.value[ offset_customSrc + 3 ];
1540

1541
									customAttribute.offsetSrc += 4;
1542

1543 1544
								}

M
Mr.doob 已提交
1545

1546
								if ( customAttribute.size === 2 ) {
M
Mr.doob 已提交
1547 1548 1549

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

M
Mr.doob 已提交
1551 1552
									customAttribute.array[ offset_custom + 2 ] = v2.x;
									customAttribute.array[ offset_custom + 3 ] = v2.y;
1553

M
Mr.doob 已提交
1554
									customAttribute.array[ offset_custom + 4 ] = v3.x;
1555
									customAttribute.array[ offset_custom + 5 ] = v3.y;
1556

M
Mr.doob 已提交
1557
									customAttribute.array[ offset_custom + 6 ] = v4.x;
1558
									customAttribute.array[ offset_custom + 7 ] = v4.y;
M
Mr.doob 已提交
1559

1560
									customAttribute.offset += 8;
M
Mr.doob 已提交
1561

1562 1563 1564
								} else if ( customAttribute.size === 3 ) {

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

1566 1567 1568
										customAttribute.array[ offset_custom + 0  ] = v1.r;
										customAttribute.array[ offset_custom + 1  ] = v1.g;
										customAttribute.array[ offset_custom + 2  ] = v1.b;
1569

1570 1571 1572
										customAttribute.array[ offset_custom + 3  ] = v2.r;
										customAttribute.array[ offset_custom + 4  ] = v2.g;
										customAttribute.array[ offset_custom + 5  ] = v2.b;
1573

1574 1575 1576
										customAttribute.array[ offset_custom + 6  ] = v3.r;
										customAttribute.array[ offset_custom + 7  ] = v3.g;
										customAttribute.array[ offset_custom + 8  ] = v3.b;
1577

1578 1579 1580 1581 1582
										customAttribute.array[ offset_custom + 9  ] = v4.r;
										customAttribute.array[ offset_custom + 10 ] = v4.g;
										customAttribute.array[ offset_custom + 11 ] = v4.b;

									} else {
1583

1584 1585 1586
										customAttribute.array[ offset_custom + 0  ] = v1.x;
										customAttribute.array[ offset_custom + 1  ] = v1.y;
										customAttribute.array[ offset_custom + 2  ] = v1.z;
1587

1588 1589 1590
										customAttribute.array[ offset_custom + 3  ] = v2.x;
										customAttribute.array[ offset_custom + 4  ] = v2.y;
										customAttribute.array[ offset_custom + 5  ] = v2.z;
1591

1592 1593 1594
										customAttribute.array[ offset_custom + 6  ] = v3.x;
										customAttribute.array[ offset_custom + 7  ] = v3.y;
										customAttribute.array[ offset_custom + 8  ] = v3.z;
1595

1596 1597 1598
										customAttribute.array[ offset_custom + 9  ] = v4.x;
										customAttribute.array[ offset_custom + 10 ] = v4.y;
										customAttribute.array[ offset_custom + 11 ] = v4.z;
1599

1600
									}
M
Mr.doob 已提交
1601

1602
									customAttribute.offset += 12;
M
Mr.doob 已提交
1603

1604
								} else {
M
Mr.doob 已提交
1605 1606 1607 1608 1609

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

M
Mr.doob 已提交
1611 1612 1613 1614
									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;
1615

M
Mr.doob 已提交
1616
									customAttribute.array[ offset_custom + 8  ] = v3.x;
1617 1618 1619
									customAttribute.array[ offset_custom + 9  ] = v3.y;
									customAttribute.array[ offset_custom + 10 ] = v3.z;
									customAttribute.array[ offset_custom + 11 ] = v3.w;
1620

M
Mr.doob 已提交
1621
									customAttribute.array[ offset_custom + 12 ] = v4.x;
1622 1623 1624
									customAttribute.array[ offset_custom + 13 ] = v4.y;
									customAttribute.array[ offset_custom + 14 ] = v4.z;
									customAttribute.array[ offset_custom + 15 ] = v4.w;
M
Mr.doob 已提交
1625

1626
									customAttribute.offset += 16;
M
Mr.doob 已提交
1627

1628
								}
M
Mr.doob 已提交
1629

1630
							}
M
Mr.doob 已提交
1631

1632
						}
M
Mr.doob 已提交
1633

1634
					}
M
Mr.doob 已提交
1635

1636 1637 1638
				}


1639
				if ( dirtyMorphTargets ) {
1640 1641 1642

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

1643 1644 1645 1646
						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;
1647

1648
						vka = morphTargetsArrays[ vk ];
1649

1650 1651 1652
						vka[ offset_morphTarget + 0 ] = v1.x;
						vka[ offset_morphTarget + 1 ] = v1.y;
						vka[ offset_morphTarget + 2 ] = v1.z;
1653

1654 1655 1656
						vka[ offset_morphTarget + 3 ] = v2.x;
						vka[ offset_morphTarget + 4 ] = v2.y;
						vka[ offset_morphTarget + 5 ] = v2.z;
1657

1658 1659 1660
						vka[ offset_morphTarget + 6 ] = v3.x;
						vka[ offset_morphTarget + 7 ] = v3.y;
						vka[ offset_morphTarget + 8 ] = v3.z;
1661

1662 1663 1664
						vka[ offset_morphTarget + 9 ] = v4.x;
						vka[ offset_morphTarget + 10 ] = v4.y;
						vka[ offset_morphTarget + 11 ] = v4.z;
1665 1666
					}

1667
					offset_morphTarget += 12;
1668

1669 1670
				}

A
alteredq 已提交
1671 1672 1673
				if ( obj_skinWeights.length ) {

					// weights
1674

A
alteredq 已提交
1675 1676 1677 1678
					sw1 = obj_skinWeights[ face.a ];
					sw2 = obj_skinWeights[ face.b ];
					sw3 = obj_skinWeights[ face.c ];
					sw4 = obj_skinWeights[ face.d ];
1679

A
alteredq 已提交
1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700
					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
1701

A
alteredq 已提交
1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727
					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
1728

A
alteredq 已提交
1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754
					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
1755

A
alteredq 已提交
1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775
					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;

1776 1777
					skinVertexBArray[ offset_skin + 12 ] = sb4.x;
					skinVertexBArray[ offset_skin + 13 ] = sb4.y;
A
alteredq 已提交
1778 1779 1780
					skinVertexBArray[ offset_skin + 14 ] = sb4.z;
					skinVertexBArray[ offset_skin + 15 ] = 1;

1781 1782
					offset_skin += 16;

A
alteredq 已提交
1783
				}
1784

1785 1786 1787
				if ( dirtyColors && vertexColorType ) {

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

1789 1790 1791 1792 1793 1794
						c1 = vertexColors[ 0 ];
						c2 = vertexColors[ 1 ];
						c3 = vertexColors[ 2 ];
						c4 = vertexColors[ 3 ];

					} else {
1795

1796 1797 1798 1799 1800 1801
						c1 = faceColor;
						c2 = faceColor;
						c3 = faceColor;
						c4 = faceColor;

					}
1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813

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

1815 1816 1817
					colorArray[ offset_color + 9 ]  = c4.r;
					colorArray[ offset_color + 10 ] = c4.g;
					colorArray[ offset_color + 11 ] = c4.b;
1818

1819 1820
					offset_color += 12;

1821 1822
				}

1823
				if ( dirtyTangents && geometry.hasTangents ) {
1824

1825 1826 1827 1828
					t1 = vertexTangents[ 0 ];
					t2 = vertexTangents[ 1 ];
					t3 = vertexTangents[ 2 ];
					t4 = vertexTangents[ 3 ];
1829

1830 1831 1832 1833
					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 已提交
1834

1835 1836 1837 1838
					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 已提交
1839

1840 1841
					tangentArray[ offset_tangent + 8 ]  = t3.x;
					tangentArray[ offset_tangent + 9 ]  = t3.y;
1842 1843
					tangentArray[ offset_tangent + 10 ] = t3.z;
					tangentArray[ offset_tangent + 11 ] = t3.w;
M
Mr.doob 已提交
1844

1845 1846 1847 1848
					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 已提交
1849

1850
					offset_tangent += 16;
M
Mr.doob 已提交
1851

1852
				}
M
Mr.doob 已提交
1853

M
Mr.doob 已提交
1854
				if ( dirtyNormals && normalType ) {
M
Mr.doob 已提交
1855

1856
					if ( vertexNormals.length == 4 && needsSmoothNormals ) {
1857

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

1860
							vn = vertexNormals[ i ];
M
Mr.doob 已提交
1861

1862 1863 1864
							normalArray[ offset_normal ]     = vn.x;
							normalArray[ offset_normal + 1 ] = vn.y;
							normalArray[ offset_normal + 2 ] = vn.z;
M
Mr.doob 已提交
1865

1866
							offset_normal += 3;
M
Mr.doob 已提交
1867

1868
						}
M
Mr.doob 已提交
1869

1870
					} else {
1871

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

1874 1875 1876
							normalArray[ offset_normal ]     = faceNormal.x;
							normalArray[ offset_normal + 1 ] = faceNormal.y;
							normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
1877

1878
							offset_normal += 3;
M
Mr.doob 已提交
1879

1880
						}
M
Mr.doob 已提交
1881 1882

					}
M
Mr.doob 已提交
1883

1884 1885
				}

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

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

1890
						uvi = uv[ i ];
M
Mr.doob 已提交
1891

1892 1893
						uvArray[ offset_uv ]     = uvi.u;
						uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
1894

1895
						offset_uv += 2;
M
Mr.doob 已提交
1896

M
Mr.doob 已提交
1897
					}
1898 1899

				}
1900

A
alteredq 已提交
1901
				if ( dirtyUvs && uv2 !== undefined && uvType ) {
1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914

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

1916
				if ( dirtyElements ) {
M
Mr.doob 已提交
1917

1918
					faceArray[ offset_face ]     = vertexIndex;
1919 1920
					faceArray[ offset_face + 1 ] = vertexIndex + 1;
					faceArray[ offset_face + 2 ] = vertexIndex + 3;
M
Mr.doob 已提交
1921

1922 1923 1924
					faceArray[ offset_face + 3 ] = vertexIndex + 1;
					faceArray[ offset_face + 4 ] = vertexIndex + 2;
					faceArray[ offset_face + 5 ] = vertexIndex + 3;
M
Mr.doob 已提交
1925

1926
					offset_face += 6;
M
Mr.doob 已提交
1927

1928 1929
					lineArray[ offset_line ]     = vertexIndex;
					lineArray[ offset_line + 1 ] = vertexIndex + 1;
M
Mr.doob 已提交
1930

1931
					lineArray[ offset_line + 2 ] = vertexIndex;
1932
					lineArray[ offset_line + 3 ] = vertexIndex + 3;
M
Mr.doob 已提交
1933

1934 1935
					lineArray[ offset_line + 4 ] = vertexIndex + 1;
					lineArray[ offset_line + 5 ] = vertexIndex + 2;
M
Mr.doob 已提交
1936

1937 1938
					lineArray[ offset_line + 6 ] = vertexIndex + 2;
					lineArray[ offset_line + 7 ] = vertexIndex + 3;
M
Mr.doob 已提交
1939

1940
					offset_line += 8;
M
Mr.doob 已提交
1941

1942
					vertexIndex += 4;
M
Mr.doob 已提交
1943

1944
				}
M
Mr.doob 已提交
1945

1946
			}
M
Mr.doob 已提交
1947

1948 1949
		}

1950 1951 1952 1953
		if ( obj_edgeFaces ) {

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

M
Mikael Emtinger 已提交
1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964
				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;
			}

1965
		}
M
Mikael Emtinger 已提交
1966

1967
		if ( dirtyVertices ) {
M
Mr.doob 已提交
1968

1969
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
1970
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
M
Mr.doob 已提交
1971

1972
		}
M
Mr.doob 已提交
1973

1974
		if ( customAttributes ) {
M
Mr.doob 已提交
1975

1976
			for ( a in customAttributes ) {
M
Mr.doob 已提交
1977

1978 1979
				customAttribute = customAttributes[ a ];

1980
				if ( customAttribute.__original.needsUpdate ) {
1981 1982 1983 1984 1985 1986 1987 1988 1989 1990

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

				}

			}

		}

1991
		if ( dirtyMorphTargets ) {
1992 1993 1994 1995

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

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

1998
			}
1999

2000 2001
		}

2002
		if ( dirtyColors && offset_color > 0 ) {
2003

2004
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
2005 2006 2007
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}
2008

2009
		if ( dirtyNormals ) {
M
Mr.doob 已提交
2010

2011
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
2012
			_gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
M
Mr.doob 已提交
2013

2014 2015
		}

2016
		if ( dirtyTangents && geometry.hasTangents ) {
2017

2018
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
2019
			_gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint );
M
Mr.doob 已提交
2020

2021
		}
2022

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

2025
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
2026
			_gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
M
Mr.doob 已提交
2027

2028
		}
M
Mr.doob 已提交
2029

2030 2031
		if ( dirtyUvs && offset_uv2 > 0 ) {

2032
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
2033 2034 2035 2036
			_gl.bufferData( _gl.ARRAY_BUFFER, uv2Array, hint );

		}

2037
		if ( dirtyElements ) {
M
Mr.doob 已提交
2038

2039
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
2040
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint );
2041

2042
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
2043
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
M
Mr.doob 已提交
2044

2045
		}
2046

2047
		if ( offset_skin > 0 ) {
2048

2049
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
A
alteredq 已提交
2050 2051
			_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexAArray, hint );

2052
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
A
alteredq 已提交
2053 2054
			_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexBArray, hint );

2055
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
A
alteredq 已提交
2056 2057
			_gl.bufferData( _gl.ARRAY_BUFFER, skinIndexArray, hint );

2058
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
A
alteredq 已提交
2059
			_gl.bufferData( _gl.ARRAY_BUFFER, skinWeightArray, hint );
2060

A
alteredq 已提交
2061
		}
2062

2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079
		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;

		}
2080

2081
	};
2082

2083
	function setLineBuffers ( geometry, hint ) {
M
Mr.doob 已提交
2084

2085
		var v, c, vertex, offset,
2086 2087 2088 2089
		vertices = geometry.vertices,
		colors = geometry.colors,
		vl = vertices.length,
		cl = colors.length,
M
Mr.doob 已提交
2090

2091 2092
		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,
2093

2094 2095
		dirtyVertices = geometry.__dirtyVertices,
		dirtyColors = geometry.__dirtyColors;
M
Mr.doob 已提交
2096

2097
		if ( dirtyVertices ) {
M
Mr.doob 已提交
2098

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

2101
				vertex = vertices[ v ].position;
M
Mr.doob 已提交
2102

2103
				offset = v * 3;
M
Mr.doob 已提交
2104

2105 2106 2107
				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;
M
Mr.doob 已提交
2108

2109 2110
			}

2111
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
A
alteredq 已提交
2112 2113
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );

2114
		}
M
Mr.doob 已提交
2115

2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129
		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;

			}

2130
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
2131 2132 2133 2134
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}

2135
	};
M
Mr.doob 已提交
2136

2137
	function setRibbonBuffers ( geometry, hint ) {
A
alteredq 已提交
2138 2139

		var v, c, vertex, offset,
2140 2141 2142 2143
		vertices = geometry.vertices,
		colors = geometry.colors,
		vl = vertices.length,
		cl = colors.length,
A
alteredq 已提交
2144

2145 2146
		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,
2147

2148 2149
		dirtyVertices = geometry.__dirtyVertices,
		dirtyColors = geometry.__dirtyColors;
A
alteredq 已提交
2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164

		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;

			}

2165
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
A
alteredq 已提交
2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183
			_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;

			}

2184
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
A
alteredq 已提交
2185 2186 2187 2188 2189
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}

	};
2190

2191
	function setParticleBuffers ( geometry, hint, object ) {
2192

A
alteredq 已提交
2193
		var v, c, vertex, offset,
2194 2195
		vertices = geometry.vertices,
		vl = vertices.length,
2196

2197 2198
		colors = geometry.colors,
		cl = colors.length,
2199

2200 2201
		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,
2202

2203
		sortArray = geometry.__sortArray,
2204

2205 2206
		dirtyVertices = geometry.__dirtyVertices,
		dirtyElements = geometry.__dirtyElements,
2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222
		dirtyColors = geometry.__dirtyColors,

		customAttributes = geometry.__webglCustomAttributes,
		a, ca, cal, v1,
		offset_custom,
		customAttribute;

		if ( customAttributes ) {

			for ( a in customAttributes ) {

				customAttributes[ a ].offset = 0;

			}

		}
2223

2224
		if ( object.sortParticles ) {
2225

2226
			_projScreenMatrix.multiplySelf( object.matrixWorld );
2227

2228 2229 2230
			for ( v = 0; v < vl; v++ ) {

				vertex = vertices[ v ].position;
2231

2232 2233
				_vector3.copy( vertex );
				_projScreenMatrix.multiplyVector3( _vector3 );
2234

2235
				sortArray[ v ] = [ _vector3.z, v ];
2236

2237
			}
2238

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

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

2243
				vertex = vertices[ sortArray[v][1] ].position;
2244

2245
				offset = v * 3;
2246

2247 2248 2249
				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;
2250

2251
			}
2252

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

A
alteredq 已提交
2255
				offset = c * 3;
2256

A
alteredq 已提交
2257 2258 2259 2260 2261
				color = colors[ sortArray[c][1] ];

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

2263
			}
2264

2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334
			if ( customAttributes ) {

				for ( a in customAttributes ) {

					customAttribute = customAttributes[ a ];

					cal = customAttribute.value.length;

					for ( ca = 0; ca < cal; ca ++ ) {

						index = sortArray[ca][1];

						offset_custom = customAttribute.offset;

						if ( customAttribute.size === 1 ) {

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

								customAttribute.array[ offset_custom ] = customAttribute.value[ index ];

							}

						} else {

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

								v1 = customAttribute.value[ index ];

							}

							if ( customAttribute.size === 2 ) {

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

							} else if ( customAttribute.size === 3 ) {

								if ( customAttribute.type === "c" ) {

									customAttribute.array[ offset_custom ] 	   = v1.r;
									customAttribute.array[ offset_custom + 1 ] = v1.g;
									customAttribute.array[ offset_custom + 2 ] = v1.b;

								} else {

									customAttribute.array[ offset_custom ] 	   = v1.x;
									customAttribute.array[ offset_custom + 1 ] = v1.y;
									customAttribute.array[ offset_custom + 2 ] = v1.z;

								}

							} else {

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

							}

						}

						customAttribute.offset += customAttribute.size;

					}

				}

			}

2335

2336
		} else {
2337

2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350
			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;

				}
2351 2352

			}
2353

A
alteredq 已提交
2354
			if ( dirtyColors ) {
2355

A
alteredq 已提交
2356 2357 2358 2359 2360 2361 2362 2363 2364 2365
				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;

2366
				}
2367

A
alteredq 已提交
2368
			}
2369

2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442
			if ( customAttributes ) {

				for ( a in customAttributes ) {

					customAttribute = customAttributes[ a ];

					if ( customAttribute.__original.needsUpdate ) {

						cal = customAttribute.value.length;

						for ( ca = 0; ca < cal; ca ++ ) {

							offset_custom = customAttribute.offset;

							if ( customAttribute.size === 1 ) {

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

									customAttribute.array[ offset_custom ] = customAttribute.value[ ca ];

								}

							} else {

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

									v1 = customAttribute.value[ ca ];

								}

								if ( customAttribute.size === 2 ) {

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

								} else if ( customAttribute.size === 3 ) {

									if ( customAttribute.type === "c" ) {

										customAttribute.array[ offset_custom ] 	   = v1.r;
										customAttribute.array[ offset_custom + 1 ] = v1.g;
										customAttribute.array[ offset_custom + 2 ] = v1.b;


									} else {

										customAttribute.array[ offset_custom ] 	   = v1.x;
										customAttribute.array[ offset_custom + 1 ] = v1.y;
										customAttribute.array[ offset_custom + 2 ] = v1.z;

									}

								} else {

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

								}

							}

							customAttribute.offset += customAttribute.size;

						}

					}

				}

			}

2443
		}
2444

A
alteredq 已提交
2445
		if ( dirtyVertices || object.sortParticles ) {
2446

2447
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
A
alteredq 已提交
2448
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
2449

A
alteredq 已提交
2450
		}
2451

A
alteredq 已提交
2452
		if ( dirtyColors || object.sortParticles ) {
2453

2454
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
A
alteredq 已提交
2455
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
2456

A
alteredq 已提交
2457
		}
2458

2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476
		if ( customAttributes ) {

			for ( a in customAttributes ) {

				customAttribute = customAttributes[ a ];

				if ( customAttribute.__original.needsUpdate || object.sortParticles ) {

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

				}

			}

		}


2477
	};
M
Mr.doob 已提交
2478

2479
	function setMaterialShaders( material, shaders ) {
2480

2481
		material.uniforms = THREE.UniformsUtils.clone( shaders.uniforms );
2482 2483
		material.vertexShader = shaders.vertexShader;
		material.fragmentShader = shaders.fragmentShader;
2484

M
Mr.doob 已提交
2485
	};
2486

2487
	function refreshUniformsCommon( uniforms, material ) {
M
Mr.doob 已提交
2488

M
Mr.doob 已提交
2489
		uniforms.diffuse.value = material.color;
A
alteredq 已提交
2490
		uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
2491

A
alteredq 已提交
2492
		uniforms.map.texture = material.map;
2493
		if ( material.map ) {
M
Mr.doob 已提交
2494

2495 2496 2497
			uniforms.offsetRepeat.value.set( material.map.offset.x, material.map.offset.y, material.map.repeat.x, material.map.repeat.y );

		}
2498

2499
		uniforms.lightMap.texture = material.lightMap;
2500

2501
		uniforms.envMap.texture = material.envMap;
A
alteredq 已提交
2502
		uniforms.reflectivity.value = material.reflectivity;
2503
		uniforms.refractionRatio.value = material.refractionRatio;
A
alteredq 已提交
2504
		uniforms.combine.value = material.combine;
2505
		uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
2506

2507
	};
2508

2509
	function refreshUniformsLine( uniforms, material ) {
2510

M
Mr.doob 已提交
2511
		uniforms.diffuse.value = material.color;
A
alteredq 已提交
2512
		uniforms.opacity.value = material.opacity;
2513 2514

	};
M
Mr.doob 已提交
2515

2516
	function refreshUniformsParticle( uniforms, material ) {
2517

M
Mr.doob 已提交
2518
		uniforms.psColor.value = material.color;
A
alteredq 已提交
2519 2520
		uniforms.opacity.value = material.opacity;
		uniforms.size.value = material.size;
M
Mr.doob 已提交
2521
		uniforms.scale.value = _canvas.height / 2.0; // TODO: Cache this.
2522

A
alteredq 已提交
2523
		uniforms.map.texture = material.map;
2524

A
alteredq 已提交
2525
	};
2526

2527
	function refreshUniformsFog( uniforms, fog ) {
2528

M
Mr.doob 已提交
2529
		uniforms.fogColor.value = fog.color;
2530

A
alteredq 已提交
2531
		if ( fog instanceof THREE.Fog ) {
2532

A
alteredq 已提交
2533 2534
			uniforms.fogNear.value = fog.near;
			uniforms.fogFar.value = fog.far;
2535

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

A
alteredq 已提交
2538
			uniforms.fogDensity.value = fog.density;
2539 2540

		}
2541

2542 2543
	};

2544
	function refreshUniformsPhong( uniforms, material ) {
M
Mr.doob 已提交
2545

M
Mr.doob 已提交
2546 2547
		uniforms.ambient.value = material.ambient;
		uniforms.specular.value = material.specular;
A
alteredq 已提交
2548
		uniforms.shininess.value = material.shininess;
M
Mr.doob 已提交
2549

2550
	};
M
Mr.doob 已提交
2551 2552


2553
	function refreshUniformsLights( uniforms, lights ) {
M
Mr.doob 已提交
2554

A
alteredq 已提交
2555 2556
		uniforms.enableLighting.value = lights.directional.length + lights.point.length;
		uniforms.ambientLightColor.value = lights.ambient;
2557

A
alteredq 已提交
2558 2559
		uniforms.directionalLightColor.value = lights.directional.colors;
		uniforms.directionalLightDirection.value = lights.directional.positions;
2560

A
alteredq 已提交
2561 2562
		uniforms.pointLightColor.value = lights.point.colors;
		uniforms.pointLightPosition.value = lights.point.positions;
2563
		uniforms.pointLightDistance.value = lights.point.distances;
M
Mr.doob 已提交
2564

A
alteredq 已提交
2565
	};
M
Mr.doob 已提交
2566

2567 2568 2569 2570
	function refreshUniformsShadow( uniforms, material ) {

		if ( uniforms.shadowMatrix ) {

2571 2572 2573 2574 2575 2576 2577
			for ( var i = 0; i < _shadowMatrix.length; i ++ ) {

				uniforms.shadowMatrix.value[ i ] = _shadowMatrix[ i ];
				uniforms.shadowMap.texture[ i ] = _this.shadowMap[ i ];


			}
2578 2579 2580 2581 2582 2583 2584 2585

			uniforms.shadowDarkness.value = _this.shadowMapDarkness;
			uniforms.shadowBias.value = _this.shadowMapBias;

		}

	};

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

2588
		var u, a, identifiers, i, parameters, maxLightCount, maxBones, maxShadows, shaderID;
2589

A
alteredq 已提交
2590
		if ( material instanceof THREE.MeshDepthMaterial ) {
2591

2592
			shaderID = 'depth';
2593

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

2596
			shaderID = 'shadowVolumeDynamic';
M
Mikael Emtinger 已提交
2597

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

2600
			shaderID = 'normal';
2601

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

2604
			shaderID = 'basic';
2605

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

2608
			shaderID = 'lambert';
M
Mr.doob 已提交
2609

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

2612
			shaderID = 'phong';
M
Mr.doob 已提交
2613

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

2616
			shaderID = 'basic';
2617

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

2620 2621 2622 2623 2624 2625 2626
			shaderID = 'particle_basic';

		}

		if ( shaderID ) {

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

A
alteredq 已提交
2628
		}
2629

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

2633
		maxLightCount = allocateLights( lights, 4 );
2634

2635 2636
		maxShadows = allocateShadows( lights );

2637
		maxBones = allocateBones( object );
M
Mr.doob 已提交
2638

2639
		parameters = {
2640

M
Mr.doob 已提交
2641
			map: !!material.map, envMap: !!material.envMap, lightMap: !!material.lightMap,
2642
			vertexColors: material.vertexColors,
2643 2644 2645
			fog: fog, sizeAttenuation: material.sizeAttenuation,
			skinning: material.skinning,
			morphTargets: material.morphTargets,
2646
			maxMorphTargets: this.maxMorphTargets,
2647
			maxDirLights: maxLightCount.directional, maxPointLights: maxLightCount.point,
2648
			maxBones: maxBones,
2649
			shadowMapEnabled: this.shadowMapEnabled && object.receiveShadow,
2650 2651 2652
			shadowMapSoft: this.shadowMapSoft,
			shadowMapWidth: this.shadowMapWidth,
			shadowMapHeight: this.shadowMapHeight,
2653
			maxShadows: maxShadows
2654

2655
		};
M
Mikael Emtinger 已提交
2656

2657
		material.program = buildProgram( shaderID, material.fragmentShader, material.vertexShader, material.uniforms, material.attributes, parameters );
2658

2659
		var attributes = material.program.attributes;
2660

2661
		if ( attributes.position >= 0 ) _gl.enableVertexAttribArray( attributes.position );
2662 2663 2664
		if ( attributes.color >= 0 ) _gl.enableVertexAttribArray( attributes.color );
		if ( attributes.normal >= 0 ) _gl.enableVertexAttribArray( attributes.normal );
		if ( attributes.tangent >= 0 ) _gl.enableVertexAttribArray( attributes.tangent );
2665

2666 2667 2668
		if ( material.skinning &&
			 attributes.skinVertexA >=0 && attributes.skinVertexB >= 0 &&
			 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
2669

2670 2671 2672 2673
			_gl.enableVertexAttribArray( attributes.skinVertexA );
			_gl.enableVertexAttribArray( attributes.skinVertexB );
			_gl.enableVertexAttribArray( attributes.skinIndex );
			_gl.enableVertexAttribArray( attributes.skinWeight );
2674

2675
		}
2676

2677
		if ( material.attributes ) {
M
Mr.doob 已提交
2678

2679
			for ( a in material.attributes ) {
M
Mr.doob 已提交
2680

2681
				if( attributes[ a ] !== undefined && attributes[ a ] >= 0 ) _gl.enableVertexAttribArray( attributes[ a ] );
M
Mr.doob 已提交
2682

2683
			}
M
Mr.doob 已提交
2684

2685
		}
2686

2687
		if ( material.morphTargets ) {
2688

2689
			material.numSupportedMorphTargets = 0;
2690

2691
			if ( attributes.morphTarget0 >= 0 ) {
2692

2693 2694
				_gl.enableVertexAttribArray( attributes.morphTarget0 );
				material.numSupportedMorphTargets ++;
2695

2696
			}
2697

2698
			if ( attributes.morphTarget1 >= 0 ) {
2699

2700 2701
				_gl.enableVertexAttribArray( attributes.morphTarget1 );
				material.numSupportedMorphTargets ++;
2702

2703
			}
2704

2705
			if ( attributes.morphTarget2 >= 0 ) {
2706

2707 2708
				_gl.enableVertexAttribArray( attributes.morphTarget2 );
				material.numSupportedMorphTargets ++;
2709

2710
			}
2711

2712
			if ( attributes.morphTarget3 >= 0 ) {
2713

2714 2715
				_gl.enableVertexAttribArray( attributes.morphTarget3 );
				material.numSupportedMorphTargets ++;
2716

2717
			}
2718

2719
			if ( attributes.morphTarget4 >= 0 ) {
2720

2721 2722
				_gl.enableVertexAttribArray( attributes.morphTarget4 );
				material.numSupportedMorphTargets ++;
2723

2724
			}
2725

2726
			if ( attributes.morphTarget5 >= 0 ) {
2727

2728 2729
				_gl.enableVertexAttribArray( attributes.morphTarget5 );
				material.numSupportedMorphTargets ++;
2730

2731
			}
2732

2733
			if ( attributes.morphTarget6 >= 0 ) {
2734

2735 2736
				_gl.enableVertexAttribArray( attributes.morphTarget6 );
				material.numSupportedMorphTargets ++;
2737

2738
			}
2739

2740
			if ( attributes.morphTarget7 >= 0 ) {
2741

2742 2743
				_gl.enableVertexAttribArray( attributes.morphTarget7 );
				material.numSupportedMorphTargets ++;
2744

2745
			}
2746

2747
		}
M
Mr.doob 已提交
2748

2749
	};
2750

2751
	function setProgram( camera, lights, fog, material, object ) {
2752

2753
		if ( ! material.program ) {
2754 2755 2756 2757

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

		}
M
Mr.doob 已提交
2758

2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774
		if ( material.morphTargets ) {

			if ( ! object.__webglMorphTargetInfluences ) {

				object.__webglMorphTargetInfluences = new Float32Array( _this.maxMorphTargets );

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

					object.__webglMorphTargetInfluences[ i ] = 0;

				}

			}

		}

2775
		var program = material.program,
A
alteredq 已提交
2776 2777
			p_uniforms = program.uniforms,
			m_uniforms = material.uniforms;
2778

2779
		if ( program != _currentProgram ) {
M
Mr.doob 已提交
2780

M
Mr.doob 已提交
2781
			_gl.useProgram( program );
2782
			_currentProgram = program;
2783

M
Mr.doob 已提交
2784
		}
2785

2786 2787
		_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, _projectionMatrixArray );

A
alteredq 已提交
2788
		// refresh uniforms common to several materials
2789 2790

		if ( fog && (
A
alteredq 已提交
2791 2792
			 material instanceof THREE.MeshBasicMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
2793
			 material instanceof THREE.MeshPhongMaterial ||
A
alteredq 已提交
2794
			 material instanceof THREE.LineBasicMaterial ||
2795 2796
			 material instanceof THREE.ParticleBasicMaterial ||
			 material.fog )
A
alteredq 已提交
2797
			) {
2798

A
alteredq 已提交
2799
			refreshUniformsFog( m_uniforms, fog );
2800 2801

		}
M
Mr.doob 已提交
2802

M
Mr.doob 已提交
2803
		if ( material instanceof THREE.MeshPhongMaterial ||
2804 2805
			 material instanceof THREE.MeshLambertMaterial ||
			 material.lights ) {
2806

A
alteredq 已提交
2807
			setupLights( program, lights );
A
alteredq 已提交
2808
			refreshUniformsLights( m_uniforms, _lights );
M
Mr.doob 已提交
2809 2810 2811

		}

2812 2813 2814
		if ( material instanceof THREE.MeshBasicMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
			 material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
2815

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

A
alteredq 已提交
2818
		}
M
Mr.doob 已提交
2819

A
alteredq 已提交
2820
		// refresh single material specific uniforms
2821

2822
		if ( material instanceof THREE.LineBasicMaterial ) {
M
Mr.doob 已提交
2823

A
alteredq 已提交
2824
			refreshUniformsLine( m_uniforms, material );
2825

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

A
alteredq 已提交
2828
			refreshUniformsParticle( m_uniforms, material );
2829

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

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

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

2836 2837
			m_uniforms.mNear.value = camera.near;
			m_uniforms.mFar.value = camera.far;
A
alteredq 已提交
2838
			m_uniforms.opacity.value = material.opacity;
2839

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

A
alteredq 已提交
2842
			m_uniforms.opacity.value = material.opacity;
2843 2844 2845 2846 2847 2848 2849

		}

		if ( object.receiveShadow && ! material._shadowPass ) {

			refreshUniformsShadow( m_uniforms, material );

2850
		}
2851

A
alteredq 已提交
2852
		// load common uniforms
2853

A
alteredq 已提交
2854 2855
		loadUniformsGeneric( program, m_uniforms );
		loadUniformsMatrices( p_uniforms, object );
2856

A
alteredq 已提交
2857 2858
		// load material specific uniforms
		// (shader material also gets them for the sake of genericity)
2859

A
alteredq 已提交
2860 2861
		if ( material instanceof THREE.MeshShaderMaterial ||
			 material instanceof THREE.MeshPhongMaterial ||
2862
			 material.envMap ) {
2863

2864
			if( p_uniforms.cameraPosition !== null ) {
M
Mr.doob 已提交
2865

2866
				_gl.uniform3f( p_uniforms.cameraPosition, camera.position.x, camera.position.y, camera.position.z );
M
Mr.doob 已提交
2867

2868
			}
2869

2870
		}
2871

A
alteredq 已提交
2872
		if ( material instanceof THREE.MeshShaderMaterial ||
2873
			 material.envMap ||
2874 2875
			 material.skinning ||
			 object.receiveShadow ) {
2876

2877
			if ( p_uniforms.objectMatrix !== null ) {
M
Mr.doob 已提交
2878

2879
				_gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object._objectMatrixArray );
M
Mr.doob 已提交
2880

2881
			}
2882

A
alteredq 已提交
2883
		}
2884

A
alteredq 已提交
2885 2886
		if ( material instanceof THREE.MeshPhongMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
A
alteredq 已提交
2887
			 material instanceof THREE.MeshShaderMaterial ||
2888 2889
			 material.skinning ) {

2890
			if( p_uniforms.viewMatrix !== null ) {
M
Mr.doob 已提交
2891

2892
				_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, _viewMatrixArray );
M
Mr.doob 已提交
2893 2894

			}
2895

A
alteredq 已提交
2896
		}
2897

2898 2899
		if ( material instanceof THREE.ShadowVolumeDynamicMaterial ) {

M
Mikael Emtinger 已提交
2900
			var dirLight = m_uniforms.directionalLightDirection.value;
2901

2902 2903 2904
			dirLight[ 0 ] = -lights[ 1 ].position.x;
			dirLight[ 1 ] = -lights[ 1 ].position.y;
			dirLight[ 2 ] = -lights[ 1 ].position.z;
2905

M
Mikael Emtinger 已提交
2906 2907 2908
			_gl.uniform3fv( p_uniforms.directionalLightDirection, dirLight );
			_gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object._objectMatrixArray );
			_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, _viewMatrixArray );
2909

M
Mikael Emtinger 已提交
2910 2911 2912
		}


2913
		if ( material.skinning ) {
2914

2915
			loadUniformsSkinning( p_uniforms, object );
2916

A
alteredq 已提交
2917
		}
2918

A
alteredq 已提交
2919
		return program;
2920

A
alteredq 已提交
2921
	};
2922

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

2925 2926
		if ( material.opacity == 0 ) return;

2927
		var program, attributes, linewidth, primitives, a, attribute;
A
alteredq 已提交
2928

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

2931
		attributes = program.attributes;
M
Mr.doob 已提交
2932

2933
		// vertices
M
Mr.doob 已提交
2934

2935
		if ( !material.morphTargets && attributes.position >= 0 ) {
2936 2937

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

2940
		} else {
2941

2942 2943 2944 2945 2946
			if ( object.morphTargetBase ) {

				setupMorphTargets( material, geometryGroup, object );

			}
2947

2948 2949
		}

2950 2951 2952

		// custom attributes

2953 2954
		// Use the per-geometryGroup custom attribute arrays which are setup in initMeshBuffers

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

2957
			for( a in geometryGroup.__webglCustomAttributes ) {
M
Mr.doob 已提交
2958

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

2961
					attribute = geometryGroup.__webglCustomAttributes[ a ];
M
Mr.doob 已提交
2962

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

2966
				}
M
Mr.doob 已提交
2967

2968
			}
M
Mr.doob 已提交
2969

2970
		}
2971 2972


2973
/*		if ( material.attributes ) {
2974 2975 2976

			for( a in material.attributes ) {

2977
				if( attributes[ a ] !== undefined && attributes[ a ] >= 0 ) {
2978 2979 2980

					attribute = material.attributes[ a ];

2981
					if( attribute.buffer ) {
M
Mr.doob 已提交
2982

2983 2984 2985 2986
						_gl.bindBuffer( _gl.ARRAY_BUFFER, attribute.buffer );
						_gl.vertexAttribPointer( attributes[ a ], attribute.size, _gl.FLOAT, false, 0, 0 );

					}
2987 2988 2989 2990 2991

				}

			}

2992
		}*/
2993 2994


2995

A
alteredq 已提交
2996 2997 2998 2999
		// colors

		if ( attributes.color >= 0 ) {

3000
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
3001
			_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
3002 3003 3004

		}

3005
		// normals
M
Mr.doob 已提交
3006

3007
		if ( attributes.normal >= 0 ) {
3008

3009
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
3010
			_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
3011

3012
		}
3013

3014 3015 3016
		// tangents

		if ( attributes.tangent >= 0 ) {
3017

3018
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
3019
			_gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
3020

3021
		}
3022

3023
		// uvs
M
Mr.doob 已提交
3024

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

3027
			if ( geometryGroup.__webglUVBuffer ) {
3028

3029
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
3030
				_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
3031

3032
				_gl.enableVertexAttribArray( attributes.uv );
3033

3034
			} else {
3035

3036
				_gl.disableVertexAttribArray( attributes.uv );
M
Mr.doob 已提交
3037

3038
			}
3039 3040 3041

		}

3042 3043
		if ( attributes.uv2 >= 0 ) {

3044
			if ( geometryGroup.__webglUV2Buffer ) {
3045

3046
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058
				_gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );

				_gl.enableVertexAttribArray( attributes.uv2 );

			} else {

				_gl.disableVertexAttribArray( attributes.uv2 );

			}

		}

3059
		if ( material.skinning &&
3060
			 attributes.skinVertexA >= 0 && attributes.skinVertexB >= 0 &&
A
alteredq 已提交
3061
			 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
3062

3063
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
A
alteredq 已提交
3064 3065
			_gl.vertexAttribPointer( attributes.skinVertexA, 4, _gl.FLOAT, false, 0, 0 );

3066
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
A
alteredq 已提交
3067 3068
			_gl.vertexAttribPointer( attributes.skinVertexB, 4, _gl.FLOAT, false, 0, 0 );

3069
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
A
alteredq 已提交
3070 3071
			_gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 );

3072
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
A
alteredq 已提交
3073
			_gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 );
3074

A
alteredq 已提交
3075
		}
3076

3077
		// render mesh
M
Mr.doob 已提交
3078

3079
		if ( object instanceof THREE.Mesh ) {
3080

3081
			// wireframe
3082

3083
			if ( material.wireframe ) {
M
Mr.doob 已提交
3084

3085
				_gl.lineWidth( material.wireframeLinewidth );
3086 3087
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
				_gl.drawElements( _gl.LINES, geometryGroup.__webglLineCount, _gl.UNSIGNED_SHORT, 0 );
3088

3089
			// triangles
3090

3091
			} else {
3092

3093 3094 3095
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
				_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );

3096
			}
3097

3098 3099
			_this.data.vertices += geometryGroup.__webglFaceCount;
			_this.data.faces += geometryGroup.__webglFaceCount / 3;
3100
			_this.data.drawCalls ++;
3101

3102
		// render lines
3103

3104
		} else if ( object instanceof THREE.Line ) {
3105

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

3108
			_gl.lineWidth( material.linewidth );
3109
			_gl.drawArrays( primitives, 0, geometryGroup.__webglLineCount );
3110

3111 3112
			_this.data.drawCalls ++;

3113
		// render particles
3114

3115
		} else if ( object instanceof THREE.ParticleSystem ) {
3116

3117
			_gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webglParticleCount );
3118

3119 3120
			_this.data.drawCalls ++;

A
alteredq 已提交
3121
		// render ribbon
3122

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

3125
			_gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webglVertexCount );
3126

3127 3128
			_this.data.drawCalls ++;

3129 3130 3131 3132
		}

	};

M
Mikael Emtinger 已提交
3133

M
Mikael Emtinger 已提交
3134
	function setupMorphTargets( material, geometryGroup, object ) {
3135

M
Mikael Emtinger 已提交
3136
		// set base
3137

M
Mikael Emtinger 已提交
3138
		var attributes = material.program.attributes;
3139

3140
		if (  object.morphTargetBase !== - 1 ) {
3141 3142

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

3145
		} else if ( attributes.position >= 0 ) {
3146 3147

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

M
Mikael Emtinger 已提交
3150
		}
3151

3152
		if ( object.morphTargetForcedOrder.length ) {
M
Mikael Emtinger 已提交
3153 3154

			// set forced order
3155

M
Mikael Emtinger 已提交
3156 3157 3158
			var m = 0;
			var order = object.morphTargetForcedOrder;
			var influences = object.morphTargetInfluences;
3159 3160 3161 3162

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

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

3165
				object.__webglMorphTargetInfluences[ m ] = influences[ order[ m ] ];
3166 3167 3168

				m ++;
			}
3169

M
Mikael Emtinger 已提交
3170
		} else {
3171

M
Mikael Emtinger 已提交
3172
			// find most influencing
3173

M
Mikael Emtinger 已提交
3174
			var used = [];
3175
			var candidateInfluence = - 1;
M
Mikael Emtinger 已提交
3176 3177 3178 3179
			var candidate = 0;
			var influences = object.morphTargetInfluences;
			var i, il = influences.length;
			var m = 0;
3180

3181
			if ( object.morphTargetBase !== - 1 ) {
3182

M
Mikael Emtinger 已提交
3183
				used[ object.morphTargetBase ] = true;
3184

M
Mikael Emtinger 已提交
3185
			}
3186 3187 3188

			while ( m < material.numSupportedMorphTargets ) {

3189
				for ( i = 0; i < il; i ++ ) {
3190 3191 3192

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

M
Mikael Emtinger 已提交
3193 3194
						candidate = i;
						candidateInfluence = influences[ candidate ];
3195

M
Mikael Emtinger 已提交
3196
					}
3197

M
Mikael Emtinger 已提交
3198
				}
3199 3200

				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ candidate ] );
M
Mikael Emtinger 已提交
3201
				_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
3202 3203 3204

				object.__webglMorphTargetInfluences[ m ] = candidateInfluence;

M
Mikael Emtinger 已提交
3205 3206
				used[ candidate ] = 1;
				candidateInfluence = -1;
3207
				m ++;
3208

M
Mikael Emtinger 已提交
3209
			}
3210

M
Mikael Emtinger 已提交
3211 3212 3213
		}

		// load updated influences uniform
3214

3215
		if( material.program.uniforms.morphTargetInfluences !== null ) {
M
Mr.doob 已提交
3216

3217
			_gl.uniform1fv( material.program.uniforms.morphTargetInfluences, object.__webglMorphTargetInfluences );
M
Mr.doob 已提交
3218

3219 3220
		}

M
Mikael Emtinger 已提交
3221 3222 3223
	}


3224
	function renderBufferImmediate( object, program, shading ) {
3225

3226 3227
		if ( ! object.__webglVertexBuffer ) object.__webglVertexBuffer = _gl.createBuffer();
		if ( ! object.__webglNormalBuffer ) object.__webglNormalBuffer = _gl.createBuffer();
3228

A
alteredq 已提交
3229
		if ( object.hasPos ) {
3230

3231 3232 3233 3234
			_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 );
3235

A
alteredq 已提交
3236
		}
3237

A
alteredq 已提交
3238
		if ( object.hasNormal ) {
3239

3240
			_gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglNormalBuffer );
3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268

			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;

M
Mr.doob 已提交
3269
					normalArray[ i ] 	 = nx;
3270 3271 3272
					normalArray[ i + 1 ] = ny;
					normalArray[ i + 2 ] = nz;

M
Mr.doob 已提交
3273
					normalArray[ i + 3 ] = nx;
3274 3275 3276
					normalArray[ i + 4 ] = ny;
					normalArray[ i + 5 ] = nz;

M
Mr.doob 已提交
3277
					normalArray[ i + 6 ] = nx;
3278 3279 3280 3281 3282 3283 3284
					normalArray[ i + 7 ] = ny;
					normalArray[ i + 8 ] = nz;

				}

			}

3285 3286 3287
			_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 );
3288

A
alteredq 已提交
3289
		}
3290

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

A
alteredq 已提交
3293
		object.count = 0;
3294

A
alteredq 已提交
3295
	};
3296

3297
	function setObjectFaces( object ) {
3298

3299
		if ( _oldDoubleSided != object.doubleSided ) {
3300

3301
			if( object.doubleSided ) {
3302

3303
				_gl.disable( _gl.CULL_FACE );
3304

3305
			} else {
3306

A
alteredq 已提交
3307
				_gl.enable( _gl.CULL_FACE );
3308

A
alteredq 已提交
3309
			}
3310

3311
			_oldDoubleSided = object.doubleSided;
3312

3313
		}
3314

3315
		if ( _oldFlipSided != object.flipSided ) {
3316

3317 3318 3319 3320
			if( object.flipSided ) {

				_gl.frontFace( _gl.CW );

3321
			} else {
3322 3323 3324 3325

				_gl.frontFace( _gl.CCW );

			}
3326

3327
			_oldFlipSided = object.flipSided;
3328 3329

		}
3330

3331
	};
3332

3333
	function setDepthTest( test ) {
3334

A
alteredq 已提交
3335 3336 3337
		if ( _oldDepth != test ) {

			if( test ) {
3338

A
alteredq 已提交
3339
				_gl.enable( _gl.DEPTH_TEST );
3340

A
alteredq 已提交
3341
			} else {
3342

A
alteredq 已提交
3343
				_gl.disable( _gl.DEPTH_TEST );
3344

A
alteredq 已提交
3345
			}
3346

A
alteredq 已提交
3347 3348 3349
			_oldDepth = test;

		}
3350

A
alteredq 已提交
3351
	};
M
Mr.doob 已提交
3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380

	function setPolygonOffset ( polygonoffset, factor, units ) {

		if ( _oldPolygonOffset != polygonoffset ) {

			if ( polygonoffset ) {

				_gl.enable( _gl.POLYGON_OFFSET_FILL );

			} else {

				_gl.disable( _gl.POLYGON_OFFSET_FILL );

			}

			_oldPolygonOffset = polygonoffset;

		}

		if ( polygonoffset && ( _oldPolygonOffsetFactor != factor || _oldPolygonOffsetUnits != units ) ) {

			_gl.polygonOffset( factor, units );

			_oldPolygonOffsetFactor = factor;
			_oldPolygonOffsetUnits = units;

		}

	};
3381

3382
	function computeFrustum( m ) {
3383 3384 3385 3386 3387 3388 3389 3390 3391

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

A
alteredq 已提交
3393
		for ( i = 0; i < 6; i ++ ) {
3394 3395 3396 3397 3398 3399 3400

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

		}

	};
3401

3402
	function isInFrustum( object ) {
3403

3404
		var distance, matrix = object.matrixWorld,
3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416
		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;

	};
3417

3418
	function addToFixedArray( where, what ) {
3419

3420 3421
		where.list[ where.count ] = what;
		where.count += 1;
3422

3423
	};
3424

3425
	function unrollImmediateBufferMaterials( globject ) {
3426

3427 3428 3429 3430 3431 3432 3433
		var i, l, m, ml, material,
			object = globject.object,
			opaque = globject.opaque,
			transparent = globject.transparent;

		transparent.count = 0;
		opaque.count = 0;
3434

3435 3436 3437
		for ( m = 0, ml = object.materials.length; m < ml; m++ ) {

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

3440
		}
3441

3442
	};
3443

3444
	function unrollBufferMaterials( globject ) {
3445

3446 3447 3448 3449 3450 3451 3452 3453
		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;
3454

3455 3456 3457 3458 3459 3460 3461 3462 3463
		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 ];
3464
					if ( material ) material.transparent ? addToFixedArray( transparent, material ) : addToFixedArray( opaque, material );
3465 3466 3467 3468 3469 3470

				}

			} else {

				material = meshMaterial;
3471
				if ( material ) material.transparent ? addToFixedArray( transparent, material ) : addToFixedArray( opaque, material );
3472

3473 3474 3475
			}

		}
3476

3477
	};
3478

3479
	function painterSort( a, b ) {
3480

3481
		return b.z - a.z;
3482 3483

	};
3484

3485 3486 3487
	function renderShadowMap( scene, camera ) {

		var i, il, light,
3488 3489
			j = 0,
			shadowMap, shadowMatrix,
3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507
			oil,
			material,
			o, ol, webglObject, object,
			lights = scene.lights,
			fog = null;

		if ( ! _cameraLight ) {

			_cameraLight = new THREE.Camera( _this.shadowCameraFov, camera.aspect, _this.shadowCameraNear, _this.shadowCameraFar );

		}

		for ( i = 0, il = lights.length; i < il; i ++ ) {

			light = lights[ i ];

			if ( light instanceof THREE.SpotLight && light.castShadow ) {

3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523
				if ( ! _this.shadowMap[ j ] ) {

					var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat };
					_this.shadowMap[ j ] = new THREE.WebGLRenderTarget( _this.shadowMapWidth, _this.shadowMapHeight, pars );

				}

				if ( ! _shadowMatrix[ j ] ) {

					_shadowMatrix[ j ] = new THREE.Matrix4();

				}

				shadowMap = _this.shadowMap[ j ];
				shadowMatrix = _shadowMatrix[ j ];

3524 3525 3526 3527 3528 3529 3530 3531 3532
				_cameraLight.position.copy( light.position );
				_cameraLight.target.position.copy( light.target.position );

				_cameraLight.update( undefined, true );

				scene.update( undefined, false, _cameraLight );

				// compute shadow matrix

3533 3534 3535 3536
				shadowMatrix.set( 0.5, 0.0, 0.0, 0.5,
								  0.0, 0.5, 0.0, 0.5,
								  0.0, 0.0, 0.5, 0.5,
								  0.0, 0.0, 0.0, 1.0 );
3537

3538 3539
				shadowMatrix.multiplySelf( _cameraLight.projectionMatrix );
				shadowMatrix.multiplySelf( _cameraLight.matrixWorldInverse );
3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550

				// render shadow map

				_cameraLight.matrixWorldInverse.flattenToArray( _viewMatrixArray );
				_cameraLight.projectionMatrix.flattenToArray( _projectionMatrixArray );

				_projScreenMatrix.multiply( _cameraLight.projectionMatrix, _cameraLight.matrixWorldInverse );
				computeFrustum( _projScreenMatrix );

				_this.initWebGLObjects( scene );

3551
				setRenderTarget( shadowMap );
3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648

				// using arbitrary clear color in depth pass
				// creates variance in shadows

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

				_this.clear();

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


				// set matrices & frustum culling

				ol = scene.__webglObjects.length;
				oil = scene.__webglObjectsImmediate.length;

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

					webglObject = scene.__webglObjects[ o ];
					object = webglObject.object;

					if ( object.visible && object.castShadow ) {

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

							object.matrixWorld.flattenToArray( object._objectMatrixArray );

							setupMatrices( object, _cameraLight, false );

							webglObject.render = true;

						} else {

							webglObject.render = false;

						}

					} else {

						webglObject.render = false;

					}

				}

				setDepthTest( true );
				setBlending( THREE.NormalBlending ); // maybe blending should be just disabled?

				//_gl.cullFace( _gl.FRONT );

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

					webglObject = scene.__webglObjects[ o ];

					if ( webglObject.render ) {

						object = webglObject.object;
						buffer = webglObject.buffer;

						setObjectFaces( object );

						material = object.geometry.morphTargets.length ? _depthMaterialMorph : _depthMaterial;

						renderBuffer( _cameraLight, lights, fog, material, buffer, object );

					}

				}


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

					webglObject = scene.__webglObjectsImmediate[ o ];
					object = webglObject.object;

					if ( object.visible && object.castShadow ) {

						if( object.matrixAutoUpdate ) {

							object.matrixWorld.flattenToArray( object._objectMatrixArray );

						}

						setupMatrices( object, _cameraLight, false );

						setObjectFaces( object );

						program = setProgram( _cameraLight, lights, fog, _depthMaterial, object );
						object.render( function( object ) { renderBufferImmediate( object, program, _depthMaterial.shading ); } );

					}

				}

				//_gl.cullFace( _gl.BACK );

3649 3650
				j ++;

3651 3652 3653 3654 3655 3656
			}

		}

	};

3657
	this.render = function( scene, camera, renderTarget, forceClear ) {
3658

A
alteredq 已提交
3659
		var i, program, opaque, transparent, material,
3660
			o, ol, oil, webglObject, object, buffer,
A
alteredq 已提交
3661
			lights = scene.lights,
N
Nicholas Kinsey 已提交
3662
			fog = scene.fog;
3663

3664 3665
		if ( this.shadowMapEnabled ) renderShadowMap( scene, camera );

3666 3667
		_this.data.vertices = 0;
		_this.data.faces = 0;
3668
		_this.data.drawCalls = 0;
3669

3670
		camera.matrixAutoUpdate && camera.update( undefined, true );
3671

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

M
Mr.doob 已提交
3674
		camera.matrixWorldInverse.flattenToArray( _viewMatrixArray );
3675
		camera.projectionMatrix.flattenToArray( _projectionMatrixArray );
M
Mr.doob 已提交
3676

M
Mr.doob 已提交
3677
		_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
3678
		computeFrustum( _projScreenMatrix );
3679

A
alteredq 已提交
3680
		this.initWebGLObjects( scene );
M
Mr.doob 已提交
3681

A
alteredq 已提交
3682
		setRenderTarget( renderTarget );
M
Mr.doob 已提交
3683

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

3686
			this.clear();
M
Mr.doob 已提交
3687

3688 3689
		}

3690
		// set matrices
3691

3692
		ol = scene.__webglObjects.length;
3693

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

3696 3697
			webglObject = scene.__webglObjects[ o ];
			object = webglObject.object;
M
Mr.doob 已提交
3698

3699
			if ( object.visible ) {
3700 3701

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

3703
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
3704

3705
					setupMatrices( object, camera, true );
3706

3707
					unrollBufferMaterials( webglObject );
3708

3709
					webglObject.render = true;
3710

3711
					if ( this.sortObjects ) {
3712

3713
						if ( webglObject.object.renderDepth ) {
M
Mr.doob 已提交
3714

3715
							webglObject.z = webglObject.object.renderDepth;
M
Mr.doob 已提交
3716

3717
						} else {
M
Mr.doob 已提交
3718

3719 3720
							_vector3.copy( object.position );
							_projScreenMatrix.multiplyVector3( _vector3 );
M
Mr.doob 已提交
3721

3722
							webglObject.z = _vector3.z;
M
Mr.doob 已提交
3723

3724
						}
3725

3726
					}
3727

3728
				} else {
3729

3730
					webglObject.render = false;
3731

3732
				}
3733

3734
			} else {
3735

3736
				webglObject.render = false;
3737

3738
			}
3739

3740
		}
3741

3742
		if ( this.sortObjects ) {
3743

3744
			scene.__webglObjects.sort( painterSort );
3745

3746
		}
3747

3748
		oil = scene.__webglObjectsImmediate.length;
3749

3750
		for ( o = 0; o < oil; o++ ) {
3751

3752 3753
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
3754

3755
			if ( object.visible ) {
3756 3757 3758

				if( object.matrixAutoUpdate ) {

3759
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
3760

A
alteredq 已提交
3761
				}
3762

3763
				setupMatrices( object, camera, true );
3764

3765
				unrollImmediateBufferMaterials( webglObject );
3766

3767
			}
3768

3769
		}
A
alteredq 已提交
3770

M
Mr.doob 已提交
3771
		if ( scene.overrideMaterial ) {
3772

M
Mr.doob 已提交
3773 3774
			setDepthTest( scene.overrideMaterial.depthTest );
			setBlending( scene.overrideMaterial.blending );
3775

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

M
Mr.doob 已提交
3778 3779 3780
				webglObject = scene.__webglObjects[ o ];

				if ( webglObject.render ) {
3781

M
Mr.doob 已提交
3782 3783
					object = webglObject.object;
					buffer = webglObject.buffer;
3784

M
Mr.doob 已提交
3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795
					setObjectFaces( object );

					renderBuffer( camera, lights, fog, scene.overrideMaterial, buffer, object );

				}

			}

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

				webglObject = scene.__webglObjectsImmediate[ o ];
3796
				object = webglObject.object;
3797

M
Mr.doob 已提交
3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825
				if ( object.visible ) {

					setObjectFaces( object );

					program = setProgram( camera, lights, fog, scene.overrideMaterial, object );
					object.render( function( object ) { renderBufferImmediate( object, program, scene.overrideMaterial.shading ); } );

				}

			}

		} else {

			// opaque pass

			setBlending( THREE.NormalBlending );

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

				webglObject = scene.__webglObjects[ o ];

				if ( webglObject.render ) {

					object = webglObject.object;
					buffer = webglObject.buffer;
					opaque = webglObject.opaque;

					setObjectFaces( object );
3826

M
Mr.doob 已提交
3827
					for ( i = 0; i < opaque.count; i ++ ) {
3828

M
Mr.doob 已提交
3829
						material = opaque.list[ i ];
3830

M
Mr.doob 已提交
3831 3832 3833 3834 3835
						setDepthTest( material.depthTest );
						setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
						renderBuffer( camera, lights, fog, material, buffer, object );

					}
3836

3837
				}
3838 3839 3840

			}

M
Mr.doob 已提交
3841
			// opaque pass (immediate simulator)
3842

M
Mr.doob 已提交
3843
			for ( o = 0; o < oil; o++ ) {
3844

M
Mr.doob 已提交
3845 3846
				webglObject = scene.__webglObjectsImmediate[ o ];
				object = webglObject.object;
3847

M
Mr.doob 已提交
3848
				if ( object.visible ) {
3849

M
Mr.doob 已提交
3850
					opaque = webglObject.opaque;
3851

M
Mr.doob 已提交
3852
					setObjectFaces( object );
3853

M
Mr.doob 已提交
3854
					for( i = 0; i < opaque.count; i++ ) {
3855

M
Mr.doob 已提交
3856
						material = opaque.list[ i ];
3857

M
Mr.doob 已提交
3858 3859
						setDepthTest( material.depthTest );
						setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
3860

M
Mr.doob 已提交
3861 3862
						program = setProgram( camera, lights, fog, material, object );
						object.render( function( object ) { renderBufferImmediate( object, program, material.shading ); } );
3863

M
Mr.doob 已提交
3864
					}
3865

3866
				}
3867

A
alteredq 已提交
3868
			}
3869

M
Mr.doob 已提交
3870
			// transparent pass
A
alteredq 已提交
3871

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

M
Mr.doob 已提交
3874
				webglObject = scene.__webglObjects[ o ];
3875

M
Mr.doob 已提交
3876
				if ( webglObject.render ) {
3877

M
Mr.doob 已提交
3878 3879 3880
					object = webglObject.object;
					buffer = webglObject.buffer;
					transparent = webglObject.transparent;
3881

M
Mr.doob 已提交
3882
					setObjectFaces( object );
3883

M
Mr.doob 已提交
3884
					for ( i = 0; i < transparent.count; i ++ ) {
3885

M
Mr.doob 已提交
3886
						material = transparent.list[ i ];
3887

M
Mr.doob 已提交
3888 3889 3890
						setBlending( material.blending );
						setDepthTest( material.depthTest );
						setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
3891

M
Mr.doob 已提交
3892
						renderBuffer( camera, lights, fog, material, buffer, object );
3893

M
Mr.doob 已提交
3894
					}
3895

3896
				}
3897

3898
			}
M
Mr.doob 已提交
3899

M
Mr.doob 已提交
3900
			// transparent pass (immediate simulator)
M
Mr.doob 已提交
3901

M
Mr.doob 已提交
3902
			for ( o = 0; o < oil; o++ ) {
3903

M
Mr.doob 已提交
3904 3905
				webglObject = scene.__webglObjectsImmediate[ o ];
				object = webglObject.object;
3906

M
Mr.doob 已提交
3907
				if ( object.visible ) {
3908

M
Mr.doob 已提交
3909
					transparent = webglObject.transparent;
3910

M
Mr.doob 已提交
3911
					setObjectFaces( object );
3912

M
Mr.doob 已提交
3913
					for ( i = 0; i < transparent.count; i ++ ) {
3914

M
Mr.doob 已提交
3915
						material = transparent.list[ i ];
3916

M
Mr.doob 已提交
3917 3918 3919
						setBlending( material.blending );
						setDepthTest( material.depthTest );
						setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
3920

M
Mr.doob 已提交
3921 3922
						program = setProgram( camera, lights, fog, material, object );
						object.render( function( object ) { renderBufferImmediate( object, program, material.shading ); } );
3923

M
Mr.doob 已提交
3924
					}
3925

3926
				}
3927

3928
			}
3929

3930
		}
3931

M
Mikael Emtinger 已提交
3932
		// render 2d
3933

M
Mikael Emtinger 已提交
3934
		if ( scene.__webglSprites.length ) {
3935

3936
			renderSprites( scene, camera );
3937

M
Mikael Emtinger 已提交
3938 3939
		}

M
Mikael Emtinger 已提交
3940
		// render stencil shadows
M
Mikael Emtinger 已提交
3941

3942
		if ( _stencil && scene.__webglShadowVolumes.length && scene.lights.length ) {
M
Mikael Emtinger 已提交
3943 3944

			renderStencilShadows( scene );
3945

M
Mikael Emtinger 已提交
3946 3947
		}

3948

3949
		// render lens flares
3950 3951 3952

		if ( scene.__webglLensFlares.length ) {

3953
			renderLensFlares( scene, camera );
3954

3955 3956
		}

M
Mikael Emtinger 已提交
3957 3958 3959 3960 3961 3962 3963 3964 3965

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

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

			updateRenderTargetMipmap( renderTarget );

		}

3966
		//_gl.finish();
3967

M
Mikael Emtinger 已提交
3968 3969 3970 3971 3972 3973 3974
	};



	/*
	 * Stencil Shadows
	 * method: we're rendering the world in light, then the shadow
M
Mr.doob 已提交
3975
	 *         volumes into the stencil and last a big darkening
M
Mikael Emtinger 已提交
3976 3977
	 *         quad over the whole thing. This is not how "you're
	 *	       supposed to" do stencil shadows but is much faster
M
Mr.doob 已提交
3978
	 *
M
Mikael Emtinger 已提交
3979 3980 3981
	 */

	function renderStencilShadows( scene ) {
3982

M
Mikael Emtinger 已提交
3983 3984 3985 3986 3987
		// setup stencil

		_gl.enable( _gl.POLYGON_OFFSET_FILL );
		_gl.polygonOffset( 0.1, 1.0 );
		_gl.enable( _gl.STENCIL_TEST );
3988
		_gl.enable( _gl.DEPTH_TEST );
M
Mikael Emtinger 已提交
3989 3990
		_gl.depthMask( false );
		_gl.colorMask( false, false, false, false );
3991

M
Mikael Emtinger 已提交
3992 3993 3994 3995
		_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 );

3996

M
Mikael Emtinger 已提交
3997
		// loop through all directional lights
3998

M
Mikael Emtinger 已提交
3999 4000
		var l, ll = scene.lights.length;
		var p;
M
Mikael Emtinger 已提交
4001
		var light, lights = scene.lights;
4002
		var dirLight = [];
M
Mikael Emtinger 已提交
4003
		var object, geometryGroup, material;
4004
		var program;
M
Mikael Emtinger 已提交
4005
		var p_uniforms;
4006 4007
		var m_uniforms;
		var attributes;
M
Mikael Emtinger 已提交
4008
		var o, ol = scene.__webglShadowVolumes.length;
4009 4010 4011

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

M
Mikael Emtinger 已提交
4012
			light = scene.lights[ l ];
4013

4014
			if ( light instanceof THREE.DirectionalLight && light.castShadow ) {
M
Mikael Emtinger 已提交
4015 4016 4017 4018 4019 4020

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

				// render all volumes
4021 4022 4023

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

M
Mikael Emtinger 已提交
4024 4025 4026
					object        = scene.__webglShadowVolumes[ o ].object;
					geometryGroup = scene.__webglShadowVolumes[ o ].buffer;
					material      = object.materials[ 0 ];
4027

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

M
Mikael Emtinger 已提交
4030
					program = material.program,
4031
					p_uniforms = program.uniforms,
4032 4033
					m_uniforms = material.uniforms,
					attributes = program.attributes;
4034

4035
					if ( _currentProgram !== program ) {
4036

M
Mikael Emtinger 已提交
4037
						_gl.useProgram( program );
M
Mikael Emtinger 已提交
4038
						_currentProgram = program;
4039

M
Mikael Emtinger 已提交
4040 4041 4042
						_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, _projectionMatrixArray );
						_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, _viewMatrixArray );
						_gl.uniform3fv( p_uniforms.directionalLightDirection, dirLight );
4043

M
Mikael Emtinger 已提交
4044
					}
4045 4046


M
Mikael Emtinger 已提交
4047 4048
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
					_gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object._objectMatrixArray );
4049 4050


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

M
Mikael Emtinger 已提交
4054
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
M
Mikael Emtinger 已提交
4055
					_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
4056

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

M
Mikael Emtinger 已提交
4059
					_gl.cullFace( _gl.FRONT );
M
Mikael Emtinger 已提交
4060
					_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );
4061

M
Mikael Emtinger 已提交
4062
					_gl.cullFace( _gl.BACK );
M
Mikael Emtinger 已提交
4063
					_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );
4064

M
Mikael Emtinger 已提交
4065
				}
M
Mikael Emtinger 已提交
4066

M
Mikael Emtinger 已提交
4067
			}
M
Mikael Emtinger 已提交
4068

M
Mikael Emtinger 已提交
4069 4070
		}

4071

M
Mikael Emtinger 已提交
4072
		// setup color+stencil
M
Mikael Emtinger 已提交
4073

M
Mikael Emtinger 已提交
4074 4075 4076 4077
		_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 );
4078
		_gl.disable( _gl.DEPTH_TEST );
M
Mikael Emtinger 已提交
4079 4080


4081
		// draw darkening polygon
M
Mr.doob 已提交
4082

4083
		_oldBlending = -1;
4084
		_oldDepth = -1;
M
Mikael Emtinger 已提交
4085
		_currentProgram = _stencilShadow.program;
M
Mr.doob 已提交
4086

M
Mikael Emtinger 已提交
4087 4088 4089
		_gl.useProgram( _stencilShadow.program );
		_gl.uniformMatrix4fv( _stencilShadow.projectionLocation, false, _projectionMatrixArray );
		_gl.uniform1f( _stencilShadow.darknessLocation, _stencilShadow.darkness );
4090

M
Mikael Emtinger 已提交
4091 4092 4093
		_gl.bindBuffer( _gl.ARRAY_BUFFER, _stencilShadow.vertexBuffer );
		_gl.vertexAttribPointer( _stencilShadow.vertexLocation, 3, _gl.FLOAT, false, 0, 0 );
		_gl.enableVertexAttribArray( _stencilShadow.vertexLocation );
M
Mr.doob 已提交
4094

M
Mikael Emtinger 已提交
4095 4096
		_gl.blendFunc( _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
		_gl.blendEquation( _gl.FUNC_ADD );
4097

M
Mikael Emtinger 已提交
4098
		_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _stencilShadow.elementBuffer );
M
Mikael Emtinger 已提交
4099 4100 4101 4102 4103
		_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );


		// disable stencil

4104 4105 4106 4107
		_gl.disable( _gl.STENCIL_TEST );
		_gl.enable( _gl.DEPTH_TEST );
		_gl.depthMask( _currentDepthMask );

M
Mikael Emtinger 已提交
4108
	}
4109

4110

4111 4112
	/*
	 * Render sprites
M
Mr.doob 已提交
4113
	 *
4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129
	 */

	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
4130

4131 4132
		_gl.useProgram( _sprite.program );
		_currentProgram = _sprite.program;
4133
		_oldBlending = -1;
4134
		_oldDepth = -1;
4135

M
Mr.doob 已提交
4136
		if ( !_spriteAttributesEnabled ) {
4137

M
Mr.doob 已提交
4138 4139
			_gl.enableVertexAttribArray( _sprite.attributes.position );
			_gl.enableVertexAttribArray( _sprite.attributes.uv );
4140

M
Mr.doob 已提交
4141 4142 4143
			_spriteAttributesEnabled = true;

		}
4144

4145
		_gl.disable( _gl.CULL_FACE );
4146
		_gl.enable( _gl.BLEND );
4147
		_gl.depthMask( true );
4148 4149 4150 4151 4152 4153

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

4155 4156 4157 4158
		_gl.uniformMatrix4fv( uniforms.projectionMatrix, false, _projectionMatrixArray );

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

4160
		// update positions and sort
4161

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

4164
			object = scene.__webglSprites[ o ];
4165

4166
			if( !object.useScreenCoordinates ) {
4167

4168 4169
				object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
				object.z = -object._modelViewMatrix.n34;
4170

4171
			} else {
4172

4173
				object.z = -object.position.z;
4174

4175
			}
4176

4177 4178 4179
		}

		scene.__webglSprites.sort( painterSort );
4180 4181

		// render all non-custom shader sprites
4182 4183

		for ( o = 0, ol = scene.__webglSprites.length; o < ol; o++ ) {
4184 4185 4186

			object = scene.__webglSprites[ o ];

4187 4188 4189 4190 4191
			if ( object.material === undefined ) {

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

					if ( object.useScreenCoordinates ) {
4192 4193

						_gl.uniform1i( uniforms.useScreenCoordinates, 1 );
M
Mr.doob 已提交
4194
						_gl.uniform3f( uniforms.screenPosition, ( object.position.x - halfViewportWidth  ) / halfViewportWidth,
4195 4196
																( halfViewportHeight - object.position.y ) / halfViewportHeight,
																  Math.max( 0, Math.min( 1, object.position.z )));
4197

4198 4199
					} else {

4200

4201 4202 4203 4204

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

4206
					}
4207

4208
					size = object.map.image.width / ( object.scaleByViewport ? _viewportHeight : 1 );
4209
					scale[ 0 ] = size * invAspect * object.scale.x;
4210
					scale[ 1 ] = size * object.scale.y;
4211

4212 4213 4214 4215 4216 4217 4218
					_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 );

4219 4220
					if ( object.mergeWith3D && !mergeWith3D ) {

4221 4222
						_gl.enable( _gl.DEPTH_TEST );
						mergeWith3D = true;
4223 4224 4225

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

4226 4227
						_gl.disable( _gl.DEPTH_TEST );
						mergeWith3D = false;
4228

4229
					}
4230

4231 4232
					setBlending( object.blending );
					setTexture( object.map, 0 );
4233

4234 4235
					_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
				}
4236

4237
			} else {
4238

4239
				anyCustom = true;
4240

4241
			}
4242

4243 4244 4245 4246 4247
		}


		// loop through all custom

4248 4249 4250
		/*
		if( anyCustom ) {

4251
		}
4252
		*/
4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263

		// restore gl

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

	}



4264 4265
	/*
	 * Render lens flares
M
Mr.doob 已提交
4266 4267 4268
	 * 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
4269
	 *         update transparency of flares. Then they are rendered.
M
Mr.doob 已提交
4270
	 *
4271 4272 4273
	 */

	function renderLensFlares( scene, camera ) {
4274

4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296
		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 已提交
4297
		_currentProgram = _lensFlare.program;
4298
		_oldBlending = -1;
4299
		_oldDepth = -1;
4300 4301


M
Mr.doob 已提交
4302
		if ( ! _lensFlareAttributesEnabled ) {
M
Mr.doob 已提交
4303

M
Mr.doob 已提交
4304 4305
			_gl.enableVertexAttribArray( _lensFlare.attributes.vertex );
			_gl.enableVertexAttribArray( _lensFlare.attributes.uv );
M
Mr.doob 已提交
4306

M
Mr.doob 已提交
4307 4308 4309 4310
			_lensFlareAttributesEnabled = true;

		}

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

4314 4315
		_gl.uniform1i( uniforms.occlusionMap, 0 );
		_gl.uniform1i( uniforms.map, 1 );
4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326

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

4327 4328 4329 4330
		_gl.activeTexture( _gl.TEXTURE0 );
		_gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.occlusionTexture );

		_gl.activeTexture( _gl.TEXTURE1 );
4331

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

4334
			// calc object screen position
4335

4336
			object = scene.__webglLensFlares[ o ].object;
4337

4338
			tempPosition.set( object.matrixWorld.n14, object.matrixWorld.n24, object.matrixWorld.n34 );
4339

4340 4341 4342
			camera.matrixWorldInverse.multiplyVector3( tempPosition );
			objectZ = tempPosition.z;
			camera.projectionMatrix.multiplyVector3( tempPosition );
4343 4344


4345
			// setup arrays for gl programs
4346

4347 4348 4349
			screenPosition[ 0 ] = tempPosition.x;
			screenPosition[ 1 ] = tempPosition.y;
			screenPosition[ 2 ] = tempPosition.z;
4350

4351 4352
			screenPositionPixels[ 0 ] = screenPosition[ 0 ] * halfViewportWidth + halfViewportWidth;
			screenPositionPixels[ 1 ] = screenPosition[ 1 ] * halfViewportHeight + halfViewportHeight;
4353

4354

M
Mr.doob 已提交
4355
			// screen cull
4356 4357

			if ( _lensFlare.hasVertexTexture || ( screenPositionPixels[ 0 ] > 0 &&
4358 4359
				screenPositionPixels[ 0 ] < _viewportWidth &&
				screenPositionPixels[ 1 ] > 0 &&
4360
				screenPositionPixels[ 1 ] < _viewportHeight )) {
4361 4362


4363
				// save current RGB to temp texture
4364

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

4368

4369
				// render pink quad
4370

4371 4372 4373
				_gl.uniform1i( uniforms.renderType, 0 );
				_gl.uniform2fv( uniforms.scale, scale );
				_gl.uniform3fv( uniforms.screenPosition, screenPosition );
4374

4375 4376
				_gl.disable( _gl.BLEND );
				_gl.enable( _gl.DEPTH_TEST );
4377

4378
				_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
4379 4380


4381
				// copy result to occlusionMap
4382

4383
				_gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.occlusionTexture );
4384
				_gl.copyTexImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, screenPositionPixels[ 0 ] - 8, screenPositionPixels[ 1 ] - 8, 16, 16, 0 );
4385 4386


4387
				// restore graphics
4388

4389 4390 4391 4392
				_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 );
4393 4394


4395
				// update object positions
4396

4397 4398 4399
				object.positionScreen.x = screenPosition[ 0 ];
				object.positionScreen.y = screenPosition[ 1 ];
				object.positionScreen.z = screenPosition[ 2 ];
4400

4401
				if ( object.customUpdateCallback ) {
4402

4403
					object.customUpdateCallback( object );
4404

4405
				} else {
4406

4407
					object.updateLensFlares();
4408

4409
				}
4410 4411


4412
				// render flares
4413

4414 4415
				_gl.uniform1i( uniforms.renderType, 2 );
				_gl.enable( _gl.BLEND );
4416

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

4419
					flare = object.lensFlares[ f ];
4420

4421
					if ( flare.opacity > 0.001 && flare.scale > 0.001 ) {
4422

4423 4424 4425
						screenPosition[ 0 ] = flare.x;
						screenPosition[ 1 ] = flare.y;
						screenPosition[ 2 ] = flare.z;
4426

4427 4428 4429
						size = flare.size * flare.scale / _viewportHeight;
						scale[ 0 ] = size * invAspect;
						scale[ 1 ] = size;
4430

4431 4432 4433 4434
						_gl.uniform3fv( uniforms.screenPosition, screenPosition );
						_gl.uniform2fv( uniforms.scale, scale );
						_gl.uniform1f( uniforms.rotation, flare.rotation );
						_gl.uniform1f( uniforms.opacity, flare.opacity );
4435

4436 4437
						setBlending( flare.blending );
						setTexture( flare.texture, 1 );
4438

4439
						_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
4440

4441
					}
4442

4443
				}
4444

4445
			}
M
Mr.doob 已提交
4446

4447 4448 4449
		}

		// restore gl
4450

4451 4452
		_gl.enable( _gl.CULL_FACE );
		_gl.enable( _gl.DEPTH_TEST );
4453
		_gl.depthMask( _currentDepthMask );
4454

4455
	};
4456 4457


4458
	function setupMatrices( object, camera, computeNormalMatrix ) {
4459

4460
		object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
4461 4462 4463 4464 4465 4466

		if ( computeNormalMatrix ) {

			THREE.Matrix4.makeInvert3x3( object._modelViewMatrix ).transposeIntoArray( object._normalMatrixArray );

		}
4467

4468
	};
4469

A
alteredq 已提交
4470
	this.initWebGLObjects = function ( scene ) {
4471

4472
		if ( !scene.__webglObjects ) {
4473

4474 4475
			scene.__webglObjects = [];
			scene.__webglObjectsImmediate = [];
M
Mikael Emtinger 已提交
4476
			scene.__webglShadowVolumes = [];
M
Mikael Emtinger 已提交
4477
			scene.__webglLensFlares = [];
M
Mikael Emtinger 已提交
4478
			scene.__webglSprites = [];
4479

4480 4481
		}

M
Mr.doob 已提交
4482
		while ( scene.__objectsAdded.length ) {
4483

M
Mr.doob 已提交
4484 4485
			addObject( scene.__objectsAdded[ 0 ], scene );
			scene.__objectsAdded.splice( 0, 1 );
4486 4487 4488

		}

M
Mr.doob 已提交
4489
		while ( scene.__objectsRemoved.length ) {
4490

M
Mr.doob 已提交
4491 4492
			removeObject( scene.__objectsRemoved[ 0 ], scene );
			scene.__objectsRemoved.splice( 0, 1 );
4493 4494

		}
4495

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

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

M
Mr.doob 已提交
4500
			updateObject( scene.__webglObjects[ o ].object, scene );
A
alteredq 已提交
4501 4502

		}
4503

M
Mikael Emtinger 已提交
4504 4505 4506 4507 4508
		for ( var o = 0, ol = scene.__webglShadowVolumes.length; o < ol; o ++ ) {

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

		}
4509

M
Mikael Emtinger 已提交
4510 4511 4512 4513 4514
		for ( var o = 0, ol = scene.__webglLensFlares.length; o < ol; o ++ ) {

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

		}
A
alteredq 已提交
4515

4516 4517
		/*
		for ( var o = 0, ol = scene.__webglSprites.length; o < ol; o ++ ) {
M
Mikael Emtinger 已提交
4518 4519 4520

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

4521 4522
		}
		*/
M
Mikael Emtinger 已提交
4523

4524
	};
4525

4526
	function addObject( object, scene ) {
4527

4528
		var g, geometry, geometryGroup;
M
Mr.doob 已提交
4529

4530
		if ( object._modelViewMatrix == undefined ) {
4531

4532
			object._modelViewMatrix = new THREE.Matrix4();
4533

4534 4535 4536
			object._normalMatrixArray = new Float32Array( 9 );
			object._modelViewMatrixArray = new Float32Array( 16 );
			object._objectMatrixArray = new Float32Array( 16 );
4537

4538
			object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
4539

4540
		}
A
alteredq 已提交
4541

4542
		if ( object instanceof THREE.Mesh ) {
A
alteredq 已提交
4543

4544 4545 4546 4547 4548 4549 4550 4551
			geometry = object.geometry;

			if ( geometry.geometryGroups == undefined ) {

				sortFacesByMaterial( geometry );

			}

4552
			// create separate VBOs per geometry chunk
A
alteredq 已提交
4553

4554
			for ( g in geometry.geometryGroups ) {
A
alteredq 已提交
4555

4556
				geometryGroup = geometry.geometryGroups[ g ];
M
Mr.doob 已提交
4557

4558
				// initialise VBO on the first access
M
Mr.doob 已提交
4559

4560
				if ( ! geometryGroup.__webglVertexBuffer ) {
M
Mr.doob 已提交
4561

4562 4563
					createMeshBuffers( geometryGroup );
					initMeshBuffers( geometryGroup, object );
A
alteredq 已提交
4564

4565
					geometry.__dirtyVertices = true;
4566
					geometry.__dirtyMorphTargets = true;
4567 4568 4569 4570 4571
					geometry.__dirtyElements = true;
					geometry.__dirtyUvs = true;
					geometry.__dirtyNormals = true;
					geometry.__dirtyTangents = true;
					geometry.__dirtyColors = true;
M
Mr.doob 已提交
4572

4573
				}
4574

4575
				// create separate wrapper per each use of VBO
4576

4577 4578
				if ( object instanceof THREE.ShadowVolume ) {

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

M
Mikael Emtinger 已提交
4581
				} else {
4582

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

M
Mikael Emtinger 已提交
4585
				}
4586

4587
			}
M
Mr.doob 已提交
4588

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

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

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

4595 4596
			geometry = object.geometry;

4597
			if( ! geometry.__webglVertexBuffer ) {
A
alteredq 已提交
4598 4599 4600 4601 4602 4603 4604 4605 4606

				createRibbonBuffers( geometry );
				initRibbonBuffers( geometry );

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

			}

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

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

4611 4612
			geometry = object.geometry;

4613
			if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
4614

4615 4616
				createLineBuffers( geometry );
				initLineBuffers( geometry );
M
Mr.doob 已提交
4617

4618 4619
				geometry.__dirtyVertices = true;
				geometry.__dirtyColors = true;
M
Mr.doob 已提交
4620

4621
			}
M
Mr.doob 已提交
4622

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

A
alteredq 已提交
4625 4626 4627 4628
		} else if ( object instanceof THREE.ParticleSystem ) {

			geometry = object.geometry;

4629
			if ( ! geometry.__webglVertexBuffer ) {
A
alteredq 已提交
4630 4631

				createParticleBuffers( geometry );
4632
				initParticleBuffers( geometry, object );
A
alteredq 已提交
4633 4634 4635

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

4637
			}
4638

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

A
alteredq 已提交
4641 4642 4643 4644
		} else if ( THREE.MarchingCubes !== undefined && object instanceof THREE.MarchingCubes ) {

			addBufferImmediate( scene.__webglObjectsImmediate, object );

4645
		} else if ( object instanceof THREE.Sprite ) {
4646

4647
			scene.__webglSprites.push( object );
4648

4649
		}
4650

4651
		/*else if ( object instanceof THREE.Particle ) {
A
alteredq 已提交
4652 4653 4654 4655 4656

		}*/

	};

4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707
	function areCustomAttributesDirty( geometryGroup ) {

		var a, m, ml, material, materials;

		materials = geometryGroup.__materials;

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

			material = materials[ m ];

			if ( material.attributes ) {

				for ( a in material.attributes ) {

					if ( material.attributes[ a ].needsUpdate ) return true;

				}

			}

		}


		return false;

	};

	function clearCustomAttributes( geometryGroup ) {

		var a, m, ml, material, materials;

		materials = geometryGroup.__materials;

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

			material = materials[ m ];

			if ( material.attributes ) {

				for ( a in material.attributes ) {

					material.attributes[ a ].needsUpdate = false;

				}

			}

		}

	};

4708
	function updateObject( object, scene ) {
A
alteredq 已提交
4709

4710
		var g, geometry, geometryGroup, a, customAttributeDirty;
A
alteredq 已提交
4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721

		if ( object instanceof THREE.Mesh ) {

			geometry = object.geometry;

			// check all geometry groups

			for ( g in geometry.geometryGroups ) {

				geometryGroup = geometry.geometryGroups[ g ];

4722
				customAttributeDirty = areCustomAttributesDirty( geometryGroup );
4723

4724
				if ( geometry.__dirtyVertices || geometry.__dirtyMorphTargets || geometry.__dirtyElements ||
4725 4726
					 geometry.__dirtyUvs || geometry.__dirtyNormals ||
					 geometry.__dirtyColors || geometry.__dirtyTangents || customAttributeDirty ) {
A
alteredq 已提交
4727 4728 4729 4730 4731 4732 4733

					setMeshBuffers( geometryGroup, object, _gl.DYNAMIC_DRAW );

				}

			}

4734
			geometry.__dirtyVertices = false;
4735
			geometry.__dirtyMorphTargets = false;
A
alteredq 已提交
4736 4737 4738 4739
			geometry.__dirtyElements = false;
			geometry.__dirtyUvs = false;
			geometry.__dirtyNormals = false;
			geometry.__dirtyTangents = false;
4740
			geometry.__dirtyColors = false;
M
Mr.doob 已提交
4741

4742 4743
			clearCustomAttributes( geometryGroup );

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

4746 4747
			geometry = object.geometry;

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

A
alteredq 已提交
4750
				setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
4751

A
alteredq 已提交
4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763
			}

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

4765
			}
4766

A
alteredq 已提交
4767 4768 4769 4770 4771 4772 4773
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;

		} else if ( object instanceof THREE.ParticleSystem ) {

			geometry = object.geometry;

4774 4775 4776
			customAttributeDirty = areCustomAttributesDirty( geometry );

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

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

4780
			}
M
Mr.doob 已提交
4781

4782 4783
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
M
Mr.doob 已提交
4784

4785 4786
			clearCustomAttributes( geometry );

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

A
alteredq 已提交
4789
			// it updates itself in render callback
4790 4791

		} else if ( object instanceof THREE.Particle ) {
4792 4793

		}*/
4794

4795 4796 4797 4798 4799 4800
		/*
		delete geometry.vertices;
		delete geometry.faces;
		delete geometryGroup.faces;
		*/

4801
	};
4802

4803
	function removeInstances( objlist, object ) {
M
Mr.doob 已提交
4804

4805
		var o, ol;
M
Mr.doob 已提交
4806

4807
		for ( o = objlist.length - 1; o >= 0; o -- ) {
4808

4809
			if ( objlist[ o ].object == object ) {
4810

4811
				objlist.splice( o, 1 );
4812

4813
			}
4814

4815
		}
M
Mr.doob 已提交
4816

4817
	};
4818

4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834
	function removeInstancesDirect( objlist, object ) {

		var o, ol;

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

			if ( objlist[ o ] == object ) {

				objlist.splice( o, 1 );

			}

		}

	};

4835
	function removeObject( object, scene ) {
4836

4837
		// must check as shadow volume before mesh (as they are also meshes)
4838

4839
		if ( object instanceof THREE.ShadowVolume ) {
M
Mr.doob 已提交
4840

4841
			removeInstances( scene.__webglShadowVolumes, object );
M
Mr.doob 已提交
4842

4843 4844 4845
		} else if ( object instanceof THREE.Mesh  ||
			 object instanceof THREE.ParticleSystem ||
			 object instanceof THREE.Ribbon ||
4846
			 object instanceof THREE.Line ) {
4847

4848
			removeInstances( scene.__webglObjects, object );
4849

4850
		} else if ( object instanceof THREE.Sprite ) {
M
Mr.doob 已提交
4851

4852
			removeInstancesDirect( scene.__webglSprites, object );
M
Mr.doob 已提交
4853

4854 4855 4856 4857 4858
		} else if ( object instanceof THREE.LensFlare ) {

			removeInstances( scene.__webglLensFlares, object );

		} else if ( object instanceof THREE.MarchingCubes ) {
4859

4860 4861 4862
			removeInstances( scene.__webglObjectsImmediate, object );

		}
M
Mr.doob 已提交
4863 4864 4865

	};

4866
	function sortFacesByMaterial( geometry ) {
4867 4868 4869 4870 4871 4872 4873

		// 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 = {};
4874
		var numMorphTargets = geometry.morphTargets !== undefined ? geometry.morphTargets.length : 0;
4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916

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

4917
				geometry.geometryGroups[ ghash ] = { 'faces': [], 'materials': materials, 'vertices': 0, 'numMorphTargets': numMorphTargets };
4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929

			}

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

4930
					geometry.geometryGroups[ ghash ] = { 'faces': [], 'materials': materials, 'vertices': 0, 'numMorphTargets': numMorphTargets };
4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942

				}

			}

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

		}

	};

4943
	function addBuffer( objlist, buffer, object ) {
4944

4945 4946 4947 4948 4949
		objlist.push( {
			buffer: buffer, object: object,
			opaque: { list: [], count: 0 },
			transparent: { list: [], count: 0 }
		} );
M
Mr.doob 已提交
4950

4951
	};
4952

4953
	function addBufferImmediate( objlist, object ) {
4954

4955 4956 4957 4958 4959
		objlist.push( {
			object: object,
			opaque: { list: [], count: 0 },
			transparent: { list: [], count: 0 }
		} );
4960

4961
	};
4962

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

4965
		if ( cullFace ) {
M
Mr.doob 已提交
4966

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

4969
				_gl.frontFace( _gl.CCW );
M
Mr.doob 已提交
4970

4971
			} else {
M
Mr.doob 已提交
4972

4973
				_gl.frontFace( _gl.CW );
M
Mr.doob 已提交
4974

4975
			}
M
Mr.doob 已提交
4976

4977
			if( cullFace == "back" ) {
M
Mr.doob 已提交
4978

4979
				_gl.cullFace( _gl.BACK );
M
Mr.doob 已提交
4980

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

4983
				_gl.cullFace( _gl.FRONT );
M
Mr.doob 已提交
4984

4985
			} else {
M
Mr.doob 已提交
4986

4987
				_gl.cullFace( _gl.FRONT_AND_BACK );
M
Mr.doob 已提交
4988

4989
			}
M
Mr.doob 已提交
4990

4991
			_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
4992

4993
		} else {
M
Mr.doob 已提交
4994

4995
			_gl.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
4996

4997 4998 4999
		}

	};
N
Nicolas Garcia Belmonte 已提交
5000

5001
	this.supportsVertexTextures = function () {
5002

A
alteredq 已提交
5003
		return _supportsVertexTextures;
5004

5005
	};
5006

5007
	function maxVertexTextures() {
5008

5009 5010 5011
		return _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );

	};
5012

5013
	function buildProgram( shaderID, fragmentShader, vertexShader, uniforms, attributes, parameters ) {
5014

5015
		var p, pl, program, code;
5016
		var chunks = [];
5017 5018 5019

		// Generate code

5020 5021 5022 5023 5024 5025 5026 5027 5028 5029
		if ( shaderID ) {

			chunks.push( shaderID );

		} else {

			chunks.push( fragmentShader );
			chunks.push( vertexShader );

		}
5030 5031 5032

		for ( p in parameters ) {

5033 5034
			chunks.push( p );
			chunks.push( parameters[ p ] );
5035 5036 5037

		}

5038 5039
		code = chunks.join();

5040 5041 5042 5043 5044 5045 5046
		// 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*/ );
5047

5048 5049 5050 5051 5052
				return _programs[ p ].program;

			}

		}
5053

5054
		//console.log( "building new program " );
5055 5056 5057

		//

5058
		program = _gl.createProgram();
M
Mr.doob 已提交
5059

5060
		var prefix_vertex = [
M
Mr.doob 已提交
5061

A
alteredq 已提交
5062
			_supportsVertexTextures ? "#define VERTEX_TEXTURES" : "",
5063

5064 5065 5066
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

5067 5068
			"#define MAX_SHADOWS " + parameters.maxShadows,

5069 5070
			"#define MAX_BONES " + parameters.maxBones,

5071
			parameters.map ? "#define USE_MAP" : "",
5072 5073 5074
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
5075
			parameters.skinning ? "#define USE_SKINNING" : "",
5076
			parameters.morphTargets ? "#define USE_MORPHTARGETS" : "",
5077

5078
			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
5079
			parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
5080

5081 5082
			parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",

M
Mr.doob 已提交
5083 5084 5085
			"uniform mat4 objectMatrix;",
			"uniform mat4 modelViewMatrix;",
			"uniform mat4 projectionMatrix;",
5086 5087
			"uniform mat4 viewMatrix;",
			"uniform mat3 normalMatrix;",
M
Mr.doob 已提交
5088
			"uniform vec3 cameraPosition;",
A
alteredq 已提交
5089 5090 5091

			"uniform mat4 cameraInverseMatrix;",

M
Mr.doob 已提交
5092 5093 5094
			"attribute vec3 position;",
			"attribute vec3 normal;",
			"attribute vec2 uv;",
5095
			"attribute vec2 uv2;",
5096

5097
			"#ifdef USE_COLOR",
5098

5099
				"attribute vec3 color;",
5100

5101 5102
			"#endif",

5103
			"#ifdef USE_MORPHTARGETS",
5104

5105 5106 5107 5108 5109 5110 5111 5112
				"attribute vec3 morphTarget0;",
				"attribute vec3 morphTarget1;",
				"attribute vec3 morphTarget2;",
				"attribute vec3 morphTarget3;",
				"attribute vec3 morphTarget4;",
				"attribute vec3 morphTarget5;",
				"attribute vec3 morphTarget6;",
				"attribute vec3 morphTarget7;",
5113

5114 5115 5116
			"#endif",

			"#ifdef USE_SKINNING",
5117

5118 5119 5120 5121
				"attribute vec4 skinVertexA;",
				"attribute vec4 skinVertexB;",
				"attribute vec4 skinIndex;",
				"attribute vec4 skinWeight;",
5122

5123
			"#endif",
5124

M
Mr.doob 已提交
5125
			""
A
alteredq 已提交
5126

M
Mr.doob 已提交
5127
		].join("\n");
5128

M
Mr.doob 已提交
5129 5130 5131 5132 5133 5134 5135 5136 5137
		var prefix_fragment = [

			"#ifdef GL_ES",
			"precision highp float;",
			"#endif",

			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

5138 5139
			"#define MAX_SHADOWS " + parameters.maxShadows,

M
Mr.doob 已提交
5140 5141 5142 5143 5144 5145 5146
			parameters.fog ? "#define USE_FOG" : "",
			parameters.fog instanceof THREE.FogExp2 ? "#define FOG_EXP2" : "",

			parameters.map ? "#define USE_MAP" : "",
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
5147

5148
			parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
5149 5150 5151
			parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
			parameters.shadowMapSoft ? "#define SHADOWMAP_WIDTH " + parameters.shadowMapWidth.toFixed( 1 ) : "",
			parameters.shadowMapSoft ? "#define SHADOWMAP_HEIGHT " + parameters.shadowMapHeight.toFixed( 1 ) : "",
M
Mr.doob 已提交
5152 5153 5154 5155 5156 5157 5158

			"uniform mat4 viewMatrix;",
			"uniform vec3 cameraPosition;",
			""

		].join("\n");

5159 5160
		_gl.attachShader( program, getShader( "fragment", prefix_fragment + fragmentShader ) );
		_gl.attachShader( program, getShader( "vertex", prefix_vertex + vertexShader ) );
M
Mr.doob 已提交
5161

M
Mr.doob 已提交
5162
		_gl.linkProgram( program );
N
Nicolas Garcia Belmonte 已提交
5163

M
Mr.doob 已提交
5164
		if ( !_gl.getProgramParameter( program, _gl.LINK_STATUS ) ) {
N
Nicolas Garcia Belmonte 已提交
5165

5166
			console.error( "Could not initialise shader\n" + "VALIDATE_STATUS: " + _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) + ", gl error [" + _gl.getError() + "]" );
M
Mr.doob 已提交
5167

N
Nicolas Garcia Belmonte 已提交
5168
		}
5169

5170 5171
		//console.log( prefix_fragment + fragmentShader );
		//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
5172

M
Mr.doob 已提交
5173
		program.uniforms = {};
5174
		program.attributes = {};
M
Mr.doob 已提交
5175

5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193
		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 );
5194

5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217
		// 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 );

5218 5219
		_programs.push( { program: program, code: code } );

M
Mr.doob 已提交
5220
		return program;
M
Mr.doob 已提交
5221

M
Mr.doob 已提交
5222
	};
M
Mr.doob 已提交
5223

5224
	function loadUniformsSkinning( uniforms, object ) {
5225

M
Mr.doob 已提交
5226
		_gl.uniformMatrix4fv( uniforms.cameraInverseMatrix, false, _viewMatrixArray );
A
alteredq 已提交
5227
		_gl.uniformMatrix4fv( uniforms.boneGlobalMatrices, false, object.boneMatrices );
5228

5229
	};
5230

5231

5232
	function loadUniformsMatrices( uniforms, object ) {
5233

A
alteredq 已提交
5234 5235 5236 5237
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray );
		_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrixArray );

	};
5238

5239
	function loadUniformsGeneric( program, uniforms ) {
M
Mr.doob 已提交
5240

5241
		var u, uniform, value, type, location, texture, i, il;
M
Mr.doob 已提交
5242

M
Mr.doob 已提交
5243
		for( u in uniforms ) {
M
Mr.doob 已提交
5244

5245
			location = program.uniforms[ u ];
5246
			if ( !location ) continue;
M
Mr.doob 已提交
5247

5248
			uniform = uniforms[ u ];
M
Mr.doob 已提交
5249

5250 5251
			type = uniform.type;
			value = uniform.value;
M
Mr.doob 已提交
5252

M
Mr.doob 已提交
5253
			if( type == "i" ) {
M
Mr.doob 已提交
5254

M
Mr.doob 已提交
5255
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
5256

M
Mr.doob 已提交
5257
			} else if( type == "f" ) {
M
Mr.doob 已提交
5258

M
Mr.doob 已提交
5259
				_gl.uniform1f( location, value );
5260

A
alteredq 已提交
5261 5262 5263
			} else if( type == "fv1" ) {

				_gl.uniform1fv( location, value );
M
Mr.doob 已提交
5264

5265 5266 5267 5268
			} else if( type == "fv" ) {

				_gl.uniform3fv( location, value );

5269 5270 5271 5272
			} else if( type == "v2" ) {

				_gl.uniform2f( location, value.x, value.y );

5273 5274 5275
			} else if( type == "v3" ) {

				_gl.uniform3f( location, value.x, value.y, value.z );
5276

5277 5278 5279 5280
			} else if( type == "v4" ) {

				_gl.uniform4f( location, value.x, value.y, value.z, value.w );

5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291
			} else if( type == "m4" ) {

				if ( ! uniform._array ) {

					uniform._array = new Float32Array( 16 );

				}

				value.flattenToArray( uniform._array );
				_gl.uniformMatrix4fv( location, false, uniform._array );

5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307
			} else if( type == "m4v" ) {

				if ( ! uniform._array ) {

					uniform._array = new Float32Array( 16 * value.length );

				}

				for ( i = 0, il = value.length; i < il; i ++ ) {

					value[ i ].flattenToArrayOffset( uniform._array, i * 16 );

				}

				_gl.uniformMatrix4fv( location, false, uniform._array );

5308 5309 5310
			} else if( type == "c" ) {

				_gl.uniform3f( location, value.r, value.g, value.b );
M
Mr.doob 已提交
5311

M
Mr.doob 已提交
5312
			} else if( type == "t" ) {
M
Mr.doob 已提交
5313

M
Mr.doob 已提交
5314
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
5315

5316
				texture = uniform.texture;
M
Mr.doob 已提交
5317

5318
				if ( !texture ) continue;
M
Mr.doob 已提交
5319

5320
				if ( texture.image instanceof Array && texture.image.length == 6 ) {
M
Mr.doob 已提交
5321

5322
					setCubeTexture( texture, value );
M
Mr.doob 已提交
5323

5324
				} else {
M
Mr.doob 已提交
5325

5326
					setTexture( texture, value );
M
Mr.doob 已提交
5327

5328
				}
M
Mr.doob 已提交
5329

5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355
			} else if( type == "tv" ) {

				if ( ! uniform._array ) {

					uniform._array = [];

					for( i = 0, il = uniform.texture.length; i < il; i ++ ) {

						uniform._array[ i ] = value + i;

					}

				}

				_gl.uniform1iv( location, uniform._array );

				for( i = 0, il = uniform.texture.length; i < il; i ++ ) {

					texture = uniform.texture[ i ];

					if ( !texture ) continue;

					setTexture( texture, uniform._array[ i ] );

				}

5356
			}
M
Mr.doob 已提交
5357

5358
		}
M
Mr.doob 已提交
5359

5360
	};
M
Mr.doob 已提交
5361

5362
	function setBlending( blending ) {
A
alteredq 已提交
5363 5364

		if ( blending != _oldBlending ) {
5365

A
alteredq 已提交
5366 5367 5368 5369 5370
			switch ( blending ) {

				case THREE.AdditiveBlending:

					_gl.blendEquation( _gl.FUNC_ADD );
5371
					_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE );
A
alteredq 已提交
5372 5373 5374 5375 5376

					break;

				case THREE.SubtractiveBlending:

5377 5378 5379 5380
					// TODO: Find blendFuncSeparate() combination

					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.ZERO, _gl.ONE_MINUS_SRC_COLOR );
A
alteredq 已提交
5381 5382 5383

					break;

5384 5385 5386
				case THREE.MultiplyBlending:

					// TODO: Find blendFuncSeparate() combination
A
alteredq 已提交
5387 5388

					_gl.blendEquation( _gl.FUNC_ADD );
5389
					_gl.blendFunc( _gl.ZERO, _gl.SRC_COLOR );
A
alteredq 已提交
5390 5391 5392 5393 5394

					break;

				default:

5395 5396
					_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 已提交
5397 5398

					break;
5399

A
alteredq 已提交
5400
			}
5401

A
alteredq 已提交
5402
			_oldBlending = blending;
5403

A
alteredq 已提交
5404 5405 5406
		}

	};
5407

5408
	function setTextureParameters( textureType, texture, image ) {
5409

5410
		if ( isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ) ) {
M
Mr.doob 已提交
5411

5412 5413
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
M
Mr.doob 已提交
5414

5415 5416
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
M
Mr.doob 已提交
5417

5418
			_gl.generateMipmap( textureType );
M
Mr.doob 已提交
5419

5420
		} else {
M
Mr.doob 已提交
5421

5422 5423
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
5424

5425 5426
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
M
Mr.doob 已提交
5427

5428
		}
M
Mr.doob 已提交
5429

5430
	};
5431

5432
	function setTexture( texture, slot ) {
5433

5434
		if ( texture.needsUpdate ) {
A
alteredq 已提交
5435

5436
			if ( !texture.__webglInit ) {
M
Mr.doob 已提交
5437

5438
				texture.__webglTexture = _gl.createTexture();
A
alteredq 已提交
5439

5440
				_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
M
Mr.doob 已提交
5441
				// _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, true );
5442
				_gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image );
M
Mr.doob 已提交
5443

5444
				texture.__webglInit = true;
M
Mr.doob 已提交
5445

A
alteredq 已提交
5446
			} else {
M
Mr.doob 已提交
5447

5448
				_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
M
Mr.doob 已提交
5449 5450 5451
				// _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, true );
				_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 已提交
5452 5453 5454

			}

5455
			setTextureParameters( _gl.TEXTURE_2D, texture, texture.image );
M
Mr.doob 已提交
5456

5457
			_gl.bindTexture( _gl.TEXTURE_2D, null );
5458

A
alteredq 已提交
5459
			texture.needsUpdate = false;
5460 5461 5462

		}

5463
		/*
5464 5465 5466 5467 5468 5469 5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 5483
		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;

		}
5484
		*/
M
Mr.doob 已提交
5485

5486
		_gl.activeTexture( _gl.TEXTURE0 + slot );
5487
		_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
M
Mr.doob 已提交
5488

5489

5490
	};
M
Mr.doob 已提交
5491

5492
	function setCubeTexture( texture, slot ) {
5493 5494 5495 5496 5497

		if ( texture.image.length == 6 ) {

			if ( texture.needsUpdate ) {

5498 5499 5500
				if ( !texture.__webglInit ) {

					texture.image.__webglTextureCube = _gl.createTexture();
5501

5502
					_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
5503

5504
					for ( var i = 0; i < 6; ++i ) {
5505

5506
						_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image[ i ] );
5507

5508
					}
5509 5510

					texture.__webglInit = true;
5511 5512 5513

				} else {

5514
					_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
5515

5516
					for ( var i = 0; i < 6; ++i ) {
5517

M
Mr.doob 已提交
5518
						// _gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image[ i ] );
5519
						_gl.texSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image[ i ] );
5520

5521
					}
5522 5523 5524

				}

5525
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, texture.image[0] );
5526 5527 5528
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );

				texture.needsUpdate = false;
5529

5530 5531 5532
			}

			_gl.activeTexture( _gl.TEXTURE0 + slot );
5533
			_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
5534 5535 5536 5537 5538

		}

	};

5539
	function setRenderTarget( renderTexture ) {
5540

5541
		if ( renderTexture && !renderTexture.__webglFramebuffer ) {
M
Mr.doob 已提交
5542

M
Mikael Emtinger 已提交
5543 5544 5545
			if( renderTexture.depthBuffer === undefined ) renderTexture.depthBuffer = true;
			if( renderTexture.stencilBuffer === undefined ) renderTexture.stencilBuffer = true;

5546 5547 5548
			renderTexture.__webglFramebuffer = _gl.createFramebuffer();
			renderTexture.__webglRenderbuffer = _gl.createRenderbuffer();
			renderTexture.__webglTexture = _gl.createTexture();
5549 5550 5551


			// Setup texture
M
Mr.doob 已提交
5552

5553
			_gl.bindTexture( _gl.TEXTURE_2D, renderTexture.__webglTexture );
5554 5555 5556 5557
			_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 ) );
5558
			_gl.texImage2D( _gl.TEXTURE_2D, 0, paramThreeToGL( renderTexture.format ), renderTexture.width, renderTexture.height, 0, paramThreeToGL( renderTexture.format ), paramThreeToGL( renderTexture.type ), null );
5559

M
Mikael Emtinger 已提交
5560
			// Setup render and frame buffer
M
Mr.doob 已提交
5561

M
Mikael Emtinger 已提交
5562
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderTexture.__webglRenderbuffer );
5563
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTexture.__webglFramebuffer );
M
Mikael Emtinger 已提交
5564

5565
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, renderTexture.__webglTexture, 0 );
5566 5567 5568

			if ( renderTexture.depthBuffer && !renderTexture.stencilBuffer ) {

M
Mikael Emtinger 已提交
5569 5570
				_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTexture.width, renderTexture.height );
				_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderTexture.__webglRenderbuffer );
5571

M
Mr.doob 已提交
5572
			/* For some reason this is not working. Defaulting to RGBA4.
M
Mikael Emtinger 已提交
5573
			} else if( !renderTexture.depthBuffer && renderTexture.stencilBuffer ) {
5574

M
Mikael Emtinger 已提交
5575 5576 5577 5578
				_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 ) {
5579

M
Mikael Emtinger 已提交
5580 5581
				_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTexture.width, renderTexture.height );
				_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderTexture.__webglRenderbuffer );
5582

M
Mikael Emtinger 已提交
5583
			} else {
5584

M
Mikael Emtinger 已提交
5585
				_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTexture.width, renderTexture.height );
5586

M
Mikael Emtinger 已提交
5587
			}
5588

5589 5590

			// Release everything
M
Mr.doob 已提交
5591

5592 5593 5594
			_gl.bindTexture( _gl.TEXTURE_2D, null );
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
M
Mr.doob 已提交
5595

5596 5597
		}

5598
		var framebuffer, width, height;
M
Mr.doob 已提交
5599

5600
		if ( renderTexture ) {
M
Mr.doob 已提交
5601

5602
			framebuffer = renderTexture.__webglFramebuffer;
5603 5604
			width = renderTexture.width;
			height = renderTexture.height;
M
Mr.doob 已提交
5605

5606
		} else {
M
Mr.doob 已提交
5607

5608
			framebuffer = null;
5609 5610
			width = _viewportWidth;
			height = _viewportHeight;
M
Mr.doob 已提交
5611

5612
		}
M
Mr.doob 已提交
5613

5614
		if ( framebuffer != _currentFramebuffer ) {
M
Mr.doob 已提交
5615

5616
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
5617
			_gl.viewport( _viewportX, _viewportY, width, height );
M
Mr.doob 已提交
5618

5619
			_currentFramebuffer = framebuffer;
M
Mr.doob 已提交
5620

5621
		}
5622

5623
	};
M
Mr.doob 已提交
5624

5625
	function updateRenderTargetMipmap( renderTarget ) {
M
Mr.doob 已提交
5626

5627
		_gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
5628 5629
		_gl.generateMipmap( _gl.TEXTURE_2D );
		_gl.bindTexture( _gl.TEXTURE_2D, null );
M
Mr.doob 已提交
5630 5631

	};
5632

5633
	function cacheUniformLocations( program, identifiers ) {
M
Mr.doob 已提交
5634

M
Mr.doob 已提交
5635
		var i, l, id;
M
Mr.doob 已提交
5636

M
Mr.doob 已提交
5637
		for( i = 0, l = identifiers.length; i < l; i++ ) {
M
Mr.doob 已提交
5638

5639 5640
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
5641

M
Mr.doob 已提交
5642
		}
M
Mr.doob 已提交
5643

M
Mr.doob 已提交
5644
	};
M
Mr.doob 已提交
5645

5646
	function cacheAttributeLocations( program, identifiers ) {
5647

5648
		var i, l, id;
M
Mr.doob 已提交
5649

5650
		for( i = 0, l = identifiers.length; i < l; i++ ) {
M
Mr.doob 已提交
5651

5652 5653
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
M
Mr.doob 已提交
5654

5655
		}
M
Mr.doob 已提交
5656

M
Mr.doob 已提交
5657
	};
M
Mr.doob 已提交
5658

5659
	function getShader( type, string ) {
N
Nicolas Garcia Belmonte 已提交
5660 5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671 5672 5673 5674 5675 5676 5677

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

5678
			console.error( _gl.getShaderInfoLog( shader ) );
5679
			console.error( string );
N
Nicolas Garcia Belmonte 已提交
5680 5681 5682 5683 5684
			return null;

		}

		return shader;
M
Mr.doob 已提交
5685

5686
	};
N
Nicolas Garcia Belmonte 已提交
5687

5688
	// fallback filters for non-power-of-2 textures
5689

5690
	function filterFallback( f ) {
5691

5692 5693 5694 5695 5696 5697 5698 5699
		switch ( f ) {

			case THREE.NearestFilter:
			case THREE.NearestMipMapNearestFilter:
			case THREE.NearestMipMapLinearFilter: return _gl.NEAREST; break;

			case THREE.LinearFilter:
			case THREE.LinearMipMapNearestFilter:
M
Mr.doob 已提交
5700
			case THREE.LinearMipMapLinearFilter:
M
Mikael Emtinger 已提交
5701
			default:
5702

M
Mikael Emtinger 已提交
5703
				return _gl.LINEAR; break;
5704 5705

		}
5706

5707
	};
5708 5709

	function paramThreeToGL( p ) {
M
Mr.doob 已提交
5710

5711
		switch ( p ) {
M
Mr.doob 已提交
5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 5724

			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;

5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 5736 5737 5738
			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;

5739
		}
M
Mr.doob 已提交
5740

5741
		return 0;
M
Mr.doob 已提交
5742

5743 5744
	};

5745
	function isPowerOfTwo( value ) {
5746 5747 5748 5749 5750

		return ( value & ( value - 1 ) ) == 0;

	};

5751
	function materialNeedsSmoothNormals( material ) {
5752 5753 5754

		return material && material.shading != undefined && material.shading == THREE.SmoothShading;

5755
	};
M
Mr.doob 已提交
5756

5757
	function bufferNeedsSmoothNormals( geometryGroup, object ) {
M
Mr.doob 已提交
5758

5759
		var m, ml, i, l, meshMaterial, needsSmoothNormals = false;
M
Mr.doob 已提交
5760

M
Mr.doob 已提交
5761
		for ( m = 0, ml = object.materials.length; m < ml; m++ ) {
5762

M
Mr.doob 已提交
5763
			meshMaterial = object.materials[ m ];
5764 5765 5766

			if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {

5767
				for ( i = 0, l = geometryGroup.materials.length; i < l; i++ ) {
5768

5769
					if ( materialNeedsSmoothNormals( geometryGroup.materials[ i ] ) ) {
5770

5771 5772 5773 5774 5775 5776 5777 5778 5779 5780 5781 5782 5783 5784 5785 5786 5787 5788 5789 5790 5791
						needsSmoothNormals = true;
						break;

					}

				}

			} else {

				if ( materialNeedsSmoothNormals( meshMaterial ) ) {

					needsSmoothNormals = true;
					break;

				}

			}

			if ( needsSmoothNormals ) break;

		}
M
Mr.doob 已提交
5792

5793
		return needsSmoothNormals;
M
Mr.doob 已提交
5794

5795
	};
M
Mr.doob 已提交
5796

5797
	function unrollGroupMaterials( geometryGroup, object ) {
5798

5799 5800 5801
		var m, ml, i, il,
			material, meshMaterial,
			materials = [];
5802

5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813
		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 ) {
5814

5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831 5832 5833
						materials.push( material );

					}

				}

			} else {

				material = meshMaterial;

				if ( material ) {

					materials.push( material );

				}

			}

		}
5834

5835 5836 5837
		return materials;

	};
5838

5839
	function bufferGuessVertexColorType( materials, geometryGroup, object ) {
5840

5841
		var i, m, ml = materials.length;
5842

5843
		// use vertexColor type from the first material in unrolled materials
5844

5845
		for ( i = 0; i < ml; i++ ) {
5846

5847
			m = materials[ i ];
5848

5849
			if ( m.vertexColors ) {
5850

5851 5852 5853
				return m.vertexColors;

			}
5854

5855
		}
5856

5857
		return false;
5858

5859 5860
	};

5861
	function bufferGuessNormalType( materials, geometryGroup, object ) {
5862

5863
		var i, m, ml = materials.length;
5864

5865
		// only MeshBasicMaterial and MeshDepthMaterial don't need normals
5866

5867
		for ( i = 0; i < ml; i++ ) {
5868

5869
			m = materials[ i ];
5870

A
alteredq 已提交
5871
			if ( ( m instanceof THREE.MeshBasicMaterial && !m.envMap ) || m instanceof THREE.MeshDepthMaterial ) continue;
5872

5873
			if ( materialNeedsSmoothNormals( m ) ) {
5874

5875 5876 5877 5878 5879 5880 5881 5882 5883
				return THREE.SmoothShading;

			} else {

				return THREE.FlatShading;

			}

		}
5884

5885
		return false;
5886

5887 5888
	};

5889
	function bufferGuessUVType( materials, geometryGroup, object ) {
5890

5891
		var i, m, ml = materials.length;
5892

5893
		// material must use some texture to require uvs
5894

5895
		for ( i = 0; i < ml; i++ ) {
5896

5897
			m = materials[ i ];
5898

A
alteredq 已提交
5899
			if ( m.map || m.lightMap || m instanceof THREE.MeshShaderMaterial ) {
5900

5901
				return true;
5902

5903
			}
5904

5905
		}
5906

5907
		return false;
5908

5909
	};
5910

5911
	function allocateBones( object ) {
5912

5913 5914 5915 5916 5917 5918 5919
		// 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)
5920

5921
		var maxBones = 50;
5922

5923
		if ( object !== undefined && object instanceof THREE.SkinnedMesh ) {
5924

5925 5926 5927 5928 5929
			maxBones = object.bones.length;

		}

		return maxBones;
5930

5931
	};
5932

5933
	function allocateLights( lights, maxLights ) {
5934

5935 5936
		var l, ll, light, dirLights, pointLights, maxDirLights, maxPointLights;
		dirLights = pointLights = maxDirLights = maxPointLights = 0;
5937

5938
		for ( l = 0, ll = lights.length; l < ll; l++ ) {
5939

5940
			light = lights[ l ];
5941

5942 5943 5944
			if ( light instanceof THREE.SpotLight ) dirLights ++; // hack, not a proper spotlight
			if ( light instanceof THREE.DirectionalLight ) dirLights ++;
			if ( light instanceof THREE.PointLight ) pointLights ++;
5945

5946
		}
5947

5948
		if ( ( pointLights + dirLights ) <= maxLights ) {
5949

5950 5951
			maxDirLights = dirLights;
			maxPointLights = pointLights;
5952

5953
		} else {
5954

5955 5956
			maxDirLights = Math.ceil( maxLights * dirLights / ( pointLights + dirLights ) );
			maxPointLights = maxLights - maxDirLights;
5957 5958 5959

		}

5960
		return { 'directional' : maxDirLights, 'point' : maxPointLights };
5961 5962

	};
M
Mr.doob 已提交
5963

5964 5965 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 5981
	function allocateShadows( lights ) {

		var l, ll, light,
			maxShadows = 0;

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

			light = lights[ l ];

			if ( light instanceof THREE.SpotLight && light.castShadow ) maxShadows ++;

		}

		return maxShadows;

	};


A
alteredq 已提交
5982
	/* DEBUG
5983
	function getGLParams() {
M
Mr.doob 已提交
5984

5985
		var params  = {
M
Mr.doob 已提交
5986

5987 5988
			'MAX_VARYING_VECTORS': _gl.getParameter( _gl.MAX_VARYING_VECTORS ),
			'MAX_VERTEX_ATTRIBS': _gl.getParameter( _gl.MAX_VERTEX_ATTRIBS ),
M
Mr.doob 已提交
5989

5990 5991 5992
			'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 已提交
5993

5994 5995 5996
			'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 已提交
5997

5998 5999
		return params;
	};
M
Mr.doob 已提交
6000

6001
	function dumpObject( obj ) {
M
Mr.doob 已提交
6002

6003 6004
		var p, str = "";
		for ( p in obj ) {
M
Mr.doob 已提交
6005

6006
			str += p + ": " + obj[p] + "\n";
M
Mr.doob 已提交
6007

6008
		}
M
Mr.doob 已提交
6009

6010 6011
		return str;
	}
A
alteredq 已提交
6012
	*/
6013
};
6014