WebGLRenderer.js 134.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
	// Init GL

	try {

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

			throw 'Error creating WebGL context.';

		}

M
Mr.doob 已提交
105 106 107 108 109 110 111 112
		console.log(
			navigator.userAgent + " | " +
			_gl.getParameter( _gl.VERSION ) + " | " +
			_gl.getParameter( _gl.VENDOR ) + " | " +
			_gl.getParameter( _gl.RENDERER ) + " | " +
			_gl.getParameter( _gl.SHADING_LANGUAGE_VERSION )
		);

113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
	} 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 已提交
138

139 140
	this.context = _gl;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

M
Mikael Emtinger 已提交
181
	}
M
Mr.doob 已提交
182 183


M
Mikael Emtinger 已提交
184
	// prepare lens flare
M
Mr.doob 已提交
185

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

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

M
Mikael Emtinger 已提交
192 193 194
	i = 0;
	_lensFlare.vertices[ i++ ] = -1; _lensFlare.vertices[ i++ ] = -1;	// vertex
	_lensFlare.vertices[ i++ ] = 0;  _lensFlare.vertices[ i++ ] = 0;	// uv... etc.
M
Mr.doob 已提交
195

M
Mikael Emtinger 已提交
196 197
	_lensFlare.vertices[ i++ ] = 1;  _lensFlare.vertices[ i++ ] = -1;
	_lensFlare.vertices[ i++ ] = 1;  _lensFlare.vertices[ i++ ] = 0;
M
Mr.doob 已提交
198

M
Mikael Emtinger 已提交
199 200
	_lensFlare.vertices[ i++ ] = 1;  _lensFlare.vertices[ i++ ] = 1;
	_lensFlare.vertices[ i++ ] = 1;  _lensFlare.vertices[ i++ ] = 1;
M
Mr.doob 已提交
201

M
Mikael Emtinger 已提交
202 203 204 205 206 207 208
	_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;

209 210 211 212
	_lensFlare.vertexBuffer     = _gl.createBuffer();
	_lensFlare.elementBuffer    = _gl.createBuffer();
	_lensFlare.tempTexture      = _gl.createTexture();
	_lensFlare.occlusionTexture = _gl.createTexture();
M
Mr.doob 已提交
213

M
Mikael Emtinger 已提交
214 215
	_gl.bindBuffer( _gl.ARRAY_BUFFER, _lensFlare.vertexBuffer );
	_gl.bufferData( _gl.ARRAY_BUFFER,  _lensFlare.vertices, _gl.STATIC_DRAW );
M
Mikael Emtinger 已提交
216

M
Mikael Emtinger 已提交
217 218 219 220 221 222 223 224 225 226
	_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 );

227 228 229 230 231 232 233 234
	_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 ) {
235

236 237 238 239 240 241 242
		_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 );

243

244 245 246
	} else {

		_lensFlare.hasVertexTexture = true;
247

248 249 250 251
		_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 );
252

253
	}
M
Mikael Emtinger 已提交
254 255 256 257 258

	_lensFlare.attributes = {};
	_lensFlare.uniforms = {};
	_lensFlare.attributes.vertex       = _gl.getAttribLocation ( _lensFlare.program, "position" );
	_lensFlare.attributes.uv           = _gl.getAttribLocation ( _lensFlare.program, "UV" );
259
	_lensFlare.uniforms.renderType     = _gl.getUniformLocation( _lensFlare.program, "renderType" );
M
Mikael Emtinger 已提交
260
	_lensFlare.uniforms.map            = _gl.getUniformLocation( _lensFlare.program, "map" );
261
	_lensFlare.uniforms.occlusionMap   = _gl.getUniformLocation( _lensFlare.program, "occlusionMap" );
M
Mikael Emtinger 已提交
262 263 264 265 266
	_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 已提交
267 268
	//_gl.enableVertexAttribArray( _lensFlare.attributes.vertex );
	//_gl.enableVertexAttribArray( _lensFlare.attributes.uv );
269

M
Mr.doob 已提交
270
	var _lensFlareAttributesEnabled = false;
M
Mikael Emtinger 已提交
271

M
Mikael Emtinger 已提交
272
	// prepare sprites
M
Mr.doob 已提交
273 274

	var _sprite = {};
M
Mikael Emtinger 已提交
275 276 277 278 279

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

	i = 0;
M
Mr.doob 已提交
280 281 282 283 284 285 286 287 288 289 290 291

	_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 已提交
292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313

	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 = {};
314 315 316 317 318 319 320 321 322 323 324 325 326 327
	_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 已提交
328

M
Mr.doob 已提交
329 330
	//_gl.enableVertexAttribArray( _sprite.attributes.position );
	//_gl.enableVertexAttribArray( _sprite.attributes.uv );
M
Mikael Emtinger 已提交
331

M
Mr.doob 已提交
332
	var _spriteAttributesEnabled = false;
M
Mikael Emtinger 已提交
333

N
Nicolas Garcia Belmonte 已提交
334 335 336 337
	this.setSize = function ( width, height ) {

		_canvas.width = width;
		_canvas.height = height;
338

339 340 341
		this.setViewport( 0, 0, _canvas.width, _canvas.height );

	};
N
Nicolas Garcia Belmonte 已提交
342

343
	this.setViewport = function ( x, y, width, height ) {
344

345 346
		_viewportX = x;
		_viewportY = y;
347

348 349
		_viewportWidth = width;
		_viewportHeight = height;
350

351
		_gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight );
352

N
Nicolas Garcia Belmonte 已提交
353
	};
354

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

357
		_gl.scissor( x, y, width, height );
358

359
	};
360

361
	this.enableScissorTest = function ( enable ) {
362

363 364 365 366
		if ( enable )
			_gl.enable( _gl.SCISSOR_TEST );
		else
			_gl.disable( _gl.SCISSOR_TEST );
367

368
	};
369

370
	this.enableDepthBufferWrite = function ( enable ) {
371

372
		_currentDepthMask = enable;
373 374 375
		_gl.depthMask( enable );

	};
376

377
	this.setClearColorHex = function ( hex, alpha ) {
378

379 380 381 382
		_clearColor.setHex( hex );
		_clearAlpha = alpha;

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

384
	};
A
alteredq 已提交
385

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

388 389 390 391
		_clearColor.copy( color );
		_clearAlpha = alpha;

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

	};
394

N
Nicolas Garcia Belmonte 已提交
395 396
	this.clear = function () {

M
Mikael Emtinger 已提交
397
		_gl.clear( _gl.COLOR_BUFFER_BIT | _gl.DEPTH_BUFFER_BIT | _gl.STENCIL_BUFFER_BIT );
N
Nicolas Garcia Belmonte 已提交
398 399 400

	};

M
Mikael Emtinger 已提交
401
	this.setStencilShadowDarkness = function( value ) {
402

M
Mikael Emtinger 已提交
403 404 405
		_stencilShadow.darkness = value;
	};

406
	this.getContext = function() {
407

408
		return _gl;
409

410 411
	}

M
Mr.doob 已提交
412

A
alteredq 已提交
413
	function setupLights ( program, lights ) {
414

415
		var l, ll, light, r = 0, g = 0, b = 0,
416
		color, position, intensity, distance,
M
Mr.doob 已提交
417

418
		zlights = _lights,
M
Mr.doob 已提交
419

420
		dcolors = zlights.directional.colors,
421
		dpositions = zlights.directional.positions,
422

423
		pcolors = zlights.point.colors,
424
		ppositions = zlights.point.positions,
425
		pdistances = zlights.point.distances,
426

427 428
		dlength = 0,
		plength = 0,
429

430 431
		doffset = 0,
		poffset = 0;
M
Mr.doob 已提交
432

433
		for ( l = 0, ll = lights.length; l < ll; l++ ) {
434

435
			light = lights[ l ];
436
			color = light.color;
437

438 439
			position = light.position;
			intensity = light.intensity;
440
			distance = light.distance;
441 442 443

			if ( light instanceof THREE.AmbientLight ) {

444 445 446
				r += color.r;
				g += color.g;
				b += color.b;
M
Mr.doob 已提交
447

448
			} else if ( light instanceof THREE.DirectionalLight ) {
449

450
				doffset = dlength * 3;
451

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

456
				dpositions[ doffset ] = position.x;
457 458
				dpositions[ doffset + 1 ] = position.y;
				dpositions[ doffset + 2 ] = position.z;
459

460
				dlength += 1;
M
Mr.doob 已提交
461

462 463
			} else if( light instanceof THREE.PointLight ) {

464
				poffset = plength * 3;
465

466
				pcolors[ poffset ] = color.r * intensity;
467 468
				pcolors[ poffset + 1 ] = color.g * intensity;
				pcolors[ poffset + 2 ] = color.b * intensity;
469

470
				ppositions[ poffset ] = position.x;
471 472
				ppositions[ poffset + 1 ] = position.y;
				ppositions[ poffset + 2 ] = position.z;
M
Mr.doob 已提交
473

474 475
				pdistances[ plength ] = distance;

476
				plength += 1;
M
Mr.doob 已提交
477

478 479 480
			}

		}
481

482 483
		// null eventual remains from removed lights
		// (this is to avoid if in shader)
484

485 486
		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 已提交
487

488 489
		zlights.point.length = plength;
		zlights.directional.length = dlength;
M
Mr.doob 已提交
490

491 492 493
		zlights.ambient[ 0 ] = r;
		zlights.ambient[ 1 ] = g;
		zlights.ambient[ 2 ] = b;
M
Mr.doob 已提交
494

495
	};
M
Mr.doob 已提交
496

497
	function createParticleBuffers ( geometry ) {
M
Mr.doob 已提交
498

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

502
	};
M
Mr.doob 已提交
503

504
	function createLineBuffers( geometry ) {
M
Mr.doob 已提交
505

506 507
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
M
Mr.doob 已提交
508

509
	};
510

511
	function createRibbonBuffers( geometry ) {
A
alteredq 已提交
512

513 514
		geometry.__webglVertexBuffer = _gl.createBuffer();
		geometry.__webglColorBuffer = _gl.createBuffer();
A
alteredq 已提交
515 516 517

	};

518
	function createMeshBuffers( geometryGroup ) {
M
Mr.doob 已提交
519

520 521 522 523 524 525
		geometryGroup.__webglVertexBuffer = _gl.createBuffer();
		geometryGroup.__webglNormalBuffer = _gl.createBuffer();
		geometryGroup.__webglTangentBuffer = _gl.createBuffer();
		geometryGroup.__webglColorBuffer = _gl.createBuffer();
		geometryGroup.__webglUVBuffer = _gl.createBuffer();
		geometryGroup.__webglUV2Buffer = _gl.createBuffer();
526

527 528 529 530 531 532 533 534 535
		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 ) {
536

537
			var m, ml;
M
Mr.doob 已提交
538
			geometryGroup.__webglMorphTargetsBuffers = [];
539 540 541 542 543

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

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

544 545 546
			}

		}
M
Mr.doob 已提交
547

548
	};
549

550
	function initLineBuffers ( geometry ) {
M
Mr.doob 已提交
551

552 553 554
		var nvertices = geometry.vertices.length;

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

557
		geometry.__webglLineCount = nvertices;
M
Mr.doob 已提交
558

559
	};
M
Mr.doob 已提交
560

561
	function initRibbonBuffers ( geometry ) {
A
alteredq 已提交
562 563 564 565 566 567

		var nvertices = geometry.vertices.length;

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

568
		geometry.__webglVertexCount = nvertices;
A
alteredq 已提交
569 570

	};
571

572
	function initParticleBuffers ( geometry ) {
573 574 575 576

		var nvertices = geometry.vertices.length;

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

579
		geometry.__sortArray = [];
580

581
		geometry.__webglParticleCount = nvertices;
582 583 584

	};

585
	function initMeshBuffers ( geometryGroup, object ) {
M
Mr.doob 已提交
586

M
Mikael Emtinger 已提交
587
		var f, fl, fi, face,
588
		m, ml, size,
589 590 591 592 593
		nvertices = 0, ntris = 0, nlines = 0,

		uvType,
		vertexColorType,
		normalType,
594 595
		materials, material,
		attribute, property, originalAttribute,
596 597 598 599

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

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

603 604
			fi = chunk_faces[ f ];
			face = obj_faces[ fi ];
M
Mr.doob 已提交
605

606
			if ( face instanceof THREE.Face3 ) {
M
Mr.doob 已提交
607

608 609 610
				nvertices += 3;
				ntris += 1;
				nlines += 3;
M
Mr.doob 已提交
611

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

614 615
				nvertices += 4;
				ntris += 2;
616
				nlines += 4;
M
Mr.doob 已提交
617

618
			}
M
Mr.doob 已提交
619

620
		}
621 622

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

624 625 626 627 628 629 630
		// 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;
631

632 633
		uvType = bufferGuessUVType( materials, geometryGroup, object );
		normalType = bufferGuessNormalType( materials, geometryGroup, object );
A
alteredq 已提交
634 635
		vertexColorType = bufferGuessVertexColorType( materials, geometryGroup, object );

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

638
		geometryGroup.__vertexArray = new Float32Array( nvertices * 3 );
639

640
		if ( normalType ) {
M
Mr.doob 已提交
641

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

644
		}
645

646
		if ( geometry.hasTangents ) {
647

648
			geometryGroup.__tangentArray = new Float32Array( nvertices * 4 );
649

650
		}
651

652
		if ( vertexColorType ) {
653

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

656
		}
M
Mr.doob 已提交
657

658
		if ( uvType ) {
659

660
			if ( geometry.faceUvs.length > 0 || geometry.faceVertexUvs.length > 0 ) {
661

662 663 664 665 666
				geometryGroup.__uvArray = new Float32Array( nvertices * 2 );

			}

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

668 669 670 671 672 673 674 675 676 677 678 679 680 681 682
				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 已提交
683
		geometryGroup.__faceArray = new Uint16Array( ntris * 3 + ( object.geometry.edgeFaces ? object.geometry.edgeFaces.length * 2 * 3 : 0 ));
684
		geometryGroup.__lineArray = new Uint16Array( nlines * 2 );
M
Mr.doob 已提交
685

686 687
		if ( geometryGroup.numMorphTargets ) {

M
Mr.doob 已提交
688
			geometryGroup.__morphTargetsArrays = [];
689 690 691

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

692 693
				geometryGroup.__morphTargetsArrays.push( new Float32Array( nvertices * 3 ) );

694 695 696
			}

		}
697

698
		geometryGroup.__needsSmoothNormals = ( normalType == THREE.SmoothShading );
699

700 701 702 703
		geometryGroup.__uvType = uvType;
		geometryGroup.__vertexColorType = vertexColorType;
		geometryGroup.__normalType = normalType;

704 705
		geometryGroup.__webglFaceCount = ntris * 3 + ( object.geometry.edgeFaces ? object.geometry.edgeFaces.length * 2 * 3 : 0 );
		geometryGroup.__webglLineCount = nlines * 2;
706

M
Mr.doob 已提交
707

708
		// custom attributes
M
Mr.doob 已提交
709 710 711

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

712 713 714
			material = materials[ m ];

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

716 717
				geometryGroup.__webglCustomAttributes = {};

718 719 720 721 722 723
				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 已提交
724

725
					attribute = {};
726 727 728 729 730

					for ( property in originalAttribute ) {

						attribute[ property ] = originalAttribute[ property ];

731
					}
M
Mr.doob 已提交
732

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

735
						attribute.__webglInitialized = true;
736

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

739 740 741 742
						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;
743

744 745 746
						attribute.size = size;
						attribute.array = new Float32Array( nvertices * size );
						attribute.buffer = _gl.createBuffer();
747
						attribute.buffer.belongsToAttribute = a;
M
Mr.doob 已提交
748

749 750
						originalAttribute.needsUpdate = true;
						attribute.__original = originalAttribute;
751

752
					}
753 754 755 756 757 758

					geometryGroup.__webglCustomAttributes[ a ] = attribute;

				}

			}
M
Mr.doob 已提交
759

760
		}
761

762 763
		geometryGroup.__inittedArrays = true;

764
	};
M
Mr.doob 已提交
765

766

767
	function setMeshBuffers ( geometryGroup, object, hint ) {
768

769 770 771 772 773 774 775
		if ( ! geometryGroup.__inittedArrays ) {

			// console.log( object );
			return;

		}

M
Mr.doob 已提交
776
		var f, fl, fi, face,
777 778 779 780 781 782 783 784 785 786 787 788 789
		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,
790
		a,
M
Mr.doob 已提交
791

792
		vertexIndex = 0,
793

794 795
		offset = 0,
		offset_uv = 0,
796
		offset_uv2 = 0,
797 798 799 800
		offset_face = 0,
		offset_normal = 0,
		offset_tangent = 0,
		offset_line = 0,
801
		offset_color = 0,
A
alteredq 已提交
802
		offset_skin = 0,
803
		offset_morphTarget = 0,
804
		offset_custom = 0,
805
		offset_customSrc = 0,
M
Mr.doob 已提交
806

807 808 809 810 811 812
		vertexArray = geometryGroup.__vertexArray,
		uvArray = geometryGroup.__uvArray,
		uv2Array = geometryGroup.__uv2Array,
		normalArray = geometryGroup.__normalArray,
		tangentArray = geometryGroup.__tangentArray,
		colorArray = geometryGroup.__colorArray,
813

814 815 816 817
		skinVertexAArray = geometryGroup.__skinVertexAArray,
		skinVertexBArray = geometryGroup.__skinVertexBArray,
		skinIndexArray = geometryGroup.__skinIndexArray,
		skinWeightArray = geometryGroup.__skinWeightArray,
M
Mr.doob 已提交
818

819 820
		morphTargetsArrays = geometryGroup.__morphTargetsArrays,

821 822
		customAttributes = geometryGroup.__webglCustomAttributes,
		customAttribute,
823

824 825
		faceArray = geometryGroup.__faceArray,
		lineArray = geometryGroup.__lineArray,
M
Mr.doob 已提交
826

827
		needsSmoothNormals = geometryGroup.__needsSmoothNormals,
828

829
		vertexColorType = geometryGroup.__vertexColorType,
A
alteredq 已提交
830 831
		uvType = geometryGroup.__uvType,
		normalType = geometryGroup.__normalType,
832

833
		geometry = object.geometry, // this is shared for all chunks
834

835
		dirtyVertices = geometry.__dirtyVertices,
836 837 838
		dirtyElements = geometry.__dirtyElements,
		dirtyUvs = geometry.__dirtyUvs,
		dirtyNormals = geometry.__dirtyNormals,
839
		dirtyTangents = geometry.__dirtyTangents,
840
		dirtyColors = geometry.__dirtyColors,
841
		dirtyMorphTargets = geometry.__dirtyMorphTargets,
M
Mr.doob 已提交
842

843
		vertices = geometry.vertices,
844
		chunk_faces = geometryGroup.faces,
845
		obj_faces = geometry.faces,
846

847 848
		obj_uvs  = geometry.faceVertexUvs[ 0 ],
		obj_uvs2 = geometry.faceVertexUvs[ 1 ],
849

A
alteredq 已提交
850
		obj_colors = geometry.colors,
851

A
alteredq 已提交
852 853 854
		obj_skinVerticesA = geometry.skinVerticesA,
		obj_skinVerticesB = geometry.skinVerticesB,
		obj_skinIndices = geometry.skinIndices,
855
		obj_skinWeights = geometry.skinWeights,
856
		obj_edgeFaces = object instanceof THREE.ShadowVolume ? geometry.edgeFaces : undefined,
857 858

		morphTargets = geometry.morphTargets;
859

860
		if ( customAttributes ) {
M
Mr.doob 已提交
861

862
			for ( a in customAttributes ) {
M
Mr.doob 已提交
863

864
				customAttributes[ a ].offset = 0;
865
				customAttributes[ a ].offsetSrc = 0;
M
Mr.doob 已提交
866

867 868
			}

M
Mr.doob 已提交
869
		}
870 871


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

874 875
			fi = chunk_faces[ f ];
			face = obj_faces[ fi ];
876 877

			if ( obj_uvs ) {
A
alteredq 已提交
878 879 880 881

				uv = obj_uvs[ fi ];

			}
882 883 884

			if ( obj_uvs2 ) {

A
alteredq 已提交
885 886 887
				uv2 = obj_uvs2[ fi ];

			}
M
Mr.doob 已提交
888

889
			vertexNormals = face.vertexNormals;
890
			faceNormal = face.normal;
891

892 893
			vertexColors = face.vertexColors;
			faceColor = face.color;
894

895
			vertexTangents = face.vertexTangents;
896 897 898

			if ( face instanceof THREE.Face3 ) {

899
				if ( dirtyVertices ) {
M
Mr.doob 已提交
900

901 902 903
					v1 = vertices[ face.a ].position;
					v2 = vertices[ face.b ].position;
					v3 = vertices[ face.c ].position;
M
Mr.doob 已提交
904

905 906 907
					vertexArray[ offset ]     = v1.x;
					vertexArray[ offset + 1 ] = v1.y;
					vertexArray[ offset + 2 ] = v1.z;
M
Mr.doob 已提交
908

909 910 911
					vertexArray[ offset + 3 ] = v2.x;
					vertexArray[ offset + 4 ] = v2.y;
					vertexArray[ offset + 5 ] = v2.z;
912

913 914 915
					vertexArray[ offset + 6 ] = v3.x;
					vertexArray[ offset + 7 ] = v3.y;
					vertexArray[ offset + 8 ] = v3.z;
M
Mr.doob 已提交
916

917
					offset += 9;
M
Mr.doob 已提交
918

919
				}
920

921
				if ( customAttributes ) {
M
Mr.doob 已提交
922

923
					for ( a in customAttributes ) {
M
Mr.doob 已提交
924

925
						customAttribute = customAttributes[ a ];
M
Mr.doob 已提交
926

927
						if ( customAttribute.__original.needsUpdate ) {
M
Mr.doob 已提交
928

929
							offset_custom = customAttribute.offset;
930
							offset_customSrc = customAttribute.offsetSrc;
M
Mr.doob 已提交
931

932 933 934
							if ( customAttribute.size === 1 ) {

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

936 937 938
									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 ];
939 940 941

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

942 943 944 945
									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 ];

946 947 948 949
									customAttribute.offsetSrc ++;

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

950 951 952
									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 ];
953

954
									customAttribute.offsetSrc += 3;
955

956
								}
M
Mr.doob 已提交
957

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

960
							} else {
M
Mr.doob 已提交
961

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

964 965 966
									v1 = customAttribute.value[ face.a ];
									v2 = customAttribute.value[ face.b ];
									v3 = customAttribute.value[ face.c ];
967 968 969

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

970 971 972 973
									v1 = customAttribute.value[ offset_customSrc ];
									v2 = customAttribute.value[ offset_customSrc ];
									v3 = customAttribute.value[ offset_customSrc ];

974 975 976 977
									customAttribute.offsetSrc ++;

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

978 979 980
									v1 = customAttribute.value[ offset_customSrc + 0 ];
									v2 = customAttribute.value[ offset_customSrc + 1 ];
									v3 = customAttribute.value[ offset_customSrc + 2 ];
981

982 983
									customAttribute.offsetSrc += 3;
								}
M
Mr.doob 已提交
984

985 986

								if ( customAttribute.size === 2 ) {
M
Mr.doob 已提交
987 988 989

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

M
Mr.doob 已提交
991 992
									customAttribute.array[ offset_custom + 2 ] = v2.x;
									customAttribute.array[ offset_custom + 3 ] = v2.y;
993

M
Mr.doob 已提交
994
									customAttribute.array[ offset_custom + 4 ] = v3.x;
995
									customAttribute.array[ offset_custom + 5 ] = v3.y;
M
Mr.doob 已提交
996

997
									customAttribute.offset += 6;
M
Mr.doob 已提交
998

999 1000 1001
								} else if ( customAttribute.size === 3 ) {

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

1003 1004 1005
										customAttribute.array[ offset_custom + 0 ] = v1.r;
										customAttribute.array[ offset_custom + 1 ] = v1.g;
										customAttribute.array[ offset_custom + 2 ] = v1.b;
1006

1007 1008 1009
										customAttribute.array[ offset_custom + 3 ] = v2.r;
										customAttribute.array[ offset_custom + 4 ] = v2.g;
										customAttribute.array[ offset_custom + 5 ] = v2.b;
1010

1011 1012 1013
										customAttribute.array[ offset_custom + 6 ] = v3.r;
										customAttribute.array[ offset_custom + 7 ] = v3.g;
										customAttribute.array[ offset_custom + 8 ] = v3.b;
1014

1015
									} else {
1016

1017 1018 1019
										customAttribute.array[ offset_custom + 0 ] = v1.x;
										customAttribute.array[ offset_custom + 1 ] = v1.y;
										customAttribute.array[ offset_custom + 2 ] = v1.z;
1020

1021 1022 1023
										customAttribute.array[ offset_custom + 3 ] = v2.x;
										customAttribute.array[ offset_custom + 4 ] = v2.y;
										customAttribute.array[ offset_custom + 5 ] = v2.z;
1024

1025 1026 1027
										customAttribute.array[ offset_custom + 6 ] = v3.x;
										customAttribute.array[ offset_custom + 7 ] = v3.y;
										customAttribute.array[ offset_custom + 8 ] = v3.z;
1028

1029
									}
M
Mr.doob 已提交
1030

1031
									customAttribute.offset += 9;
M
Mr.doob 已提交
1032

1033
								} else {
M
Mr.doob 已提交
1034 1035 1036 1037 1038

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

M
Mr.doob 已提交
1040 1041 1042 1043
									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;
1044

M
Mr.doob 已提交
1045
									customAttribute.array[ offset_custom + 8  ] = v3.x;
1046 1047 1048
									customAttribute.array[ offset_custom + 9  ] = v3.y;
									customAttribute.array[ offset_custom + 10 ] = v3.z;
									customAttribute.array[ offset_custom + 11 ] = v3.w;
M
Mr.doob 已提交
1049

1050
									customAttribute.offset += 12;
M
Mr.doob 已提交
1051

1052
								}
M
Mr.doob 已提交
1053

1054
							}
M
Mr.doob 已提交
1055

1056
						}
M
Mr.doob 已提交
1057

1058
					}
M
Mr.doob 已提交
1059

1060 1061 1062
				}


1063
				if ( dirtyMorphTargets ) {
1064 1065 1066

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

1067 1068 1069
						v1 = morphTargets[ vk ].vertices[ face.a ].position;
						v2 = morphTargets[ vk ].vertices[ face.b ].position;
						v3 = morphTargets[ vk ].vertices[ face.c ].position;
1070

1071
						vka = morphTargetsArrays[ vk ];
1072

1073 1074 1075
						vka[ offset_morphTarget + 0 ] = v1.x;
						vka[ offset_morphTarget + 1 ] = v1.y;
						vka[ offset_morphTarget + 2 ] = v1.z;
1076

1077 1078 1079
						vka[ offset_morphTarget + 3 ] = v2.x;
						vka[ offset_morphTarget + 4 ] = v2.y;
						vka[ offset_morphTarget + 5 ] = v2.z;
1080

1081 1082 1083
						vka[ offset_morphTarget + 6 ] = v3.x;
						vka[ offset_morphTarget + 7 ] = v3.y;
						vka[ offset_morphTarget + 8 ] = v3.z;
1084 1085
					}

1086
					offset_morphTarget += 9;
1087

1088 1089
				}

A
alteredq 已提交
1090 1091 1092
				if ( obj_skinWeights.length ) {

					// weights
1093

A
alteredq 已提交
1094 1095 1096
					sw1 = obj_skinWeights[ face.a ];
					sw2 = obj_skinWeights[ face.b ];
					sw3 = obj_skinWeights[ face.c ];
1097

A
alteredq 已提交
1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113
					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
1114

A
alteredq 已提交
1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134
					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
1135

A
alteredq 已提交
1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155
					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
1156

A
alteredq 已提交
1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176
					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;
1177

A
alteredq 已提交
1178
				}
1179

1180 1181 1182
				if ( dirtyColors && vertexColorType ) {

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

1184 1185 1186 1187 1188
						c1 = vertexColors[ 0 ];
						c2 = vertexColors[ 1 ];
						c3 = vertexColors[ 2 ];

					} else {
1189

1190 1191 1192 1193 1194
						c1 = faceColor;
						c2 = faceColor;
						c3 = faceColor;

					}
1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206

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

1208 1209 1210 1211
					offset_color += 9;

				}

1212
				if ( dirtyTangents && geometry.hasTangents ) {
1213

1214 1215 1216
					t1 = vertexTangents[ 0 ];
					t2 = vertexTangents[ 1 ];
					t3 = vertexTangents[ 2 ];
1217

1218 1219 1220 1221
					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 已提交
1222

1223 1224 1225 1226
					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 已提交
1227

1228 1229 1230 1231
					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 已提交
1232

1233
					offset_tangent += 12;
M
Mr.doob 已提交
1234

1235 1236
				}

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

1239 1240 1241
					if ( vertexNormals.length == 3 && needsSmoothNormals ) {

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

1243
							vn = vertexNormals[ i ];
M
Mr.doob 已提交
1244

1245 1246 1247
							normalArray[ offset_normal ]     = vn.x;
							normalArray[ offset_normal + 1 ] = vn.y;
							normalArray[ offset_normal + 2 ] = vn.z;
M
Mr.doob 已提交
1248

1249
							offset_normal += 3;
M
Mr.doob 已提交
1250

1251
						}
M
Mr.doob 已提交
1252

1253
					} else {
1254

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

1257 1258 1259
							normalArray[ offset_normal ]     = faceNormal.x;
							normalArray[ offset_normal + 1 ] = faceNormal.y;
							normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
1260

1261
							offset_normal += 3;
M
Mr.doob 已提交
1262

1263
						}
M
Mr.doob 已提交
1264 1265

					}
M
Mr.doob 已提交
1266

1267 1268
				}

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

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

1273
						uvi = uv[ i ];
M
Mr.doob 已提交
1274

1275 1276
						uvArray[ offset_uv ]     = uvi.u;
						uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
1277

1278
						offset_uv += 2;
M
Mr.doob 已提交
1279

M
Mr.doob 已提交
1280
					}
1281 1282 1283

				}

A
alteredq 已提交
1284
				if ( dirtyUvs && uv2 !== undefined && uvType ) {
1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298

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

						uv2i = uv2[ i ];

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

						offset_uv2 += 2;

					}

				}

1299
				if ( dirtyElements ) {
M
Mr.doob 已提交
1300

1301 1302 1303
					faceArray[ offset_face ] = vertexIndex;
					faceArray[ offset_face + 1 ] = vertexIndex + 1;
					faceArray[ offset_face + 2 ] = vertexIndex + 2;
M
Mr.doob 已提交
1304

1305
					offset_face += 3;
M
Mr.doob 已提交
1306

1307 1308
					lineArray[ offset_line ]     = vertexIndex;
					lineArray[ offset_line + 1 ] = vertexIndex + 1;
M
Mr.doob 已提交
1309

1310 1311
					lineArray[ offset_line + 2 ] = vertexIndex;
					lineArray[ offset_line + 3 ] = vertexIndex + 2;
M
Mr.doob 已提交
1312

1313 1314
					lineArray[ offset_line + 4 ] = vertexIndex + 1;
					lineArray[ offset_line + 5 ] = vertexIndex + 2;
M
Mr.doob 已提交
1315

1316
					offset_line += 6;
1317

1318
					vertexIndex += 3;
M
Mr.doob 已提交
1319

1320
				}
M
Mr.doob 已提交
1321

1322 1323 1324

			} else if ( face instanceof THREE.Face4 ) {

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

1327 1328 1329 1330
					v1 = vertices[ face.a ].position;
					v2 = vertices[ face.b ].position;
					v3 = vertices[ face.c ].position;
					v4 = vertices[ face.d ].position;
M
Mr.doob 已提交
1331

1332 1333 1334
					vertexArray[ offset ]     = v1.x;
					vertexArray[ offset + 1 ] = v1.y;
					vertexArray[ offset + 2 ] = v1.z;
M
Mr.doob 已提交
1335

1336 1337 1338
					vertexArray[ offset + 3 ] = v2.x;
					vertexArray[ offset + 4 ] = v2.y;
					vertexArray[ offset + 5 ] = v2.z;
1339

1340 1341 1342
					vertexArray[ offset + 6 ] = v3.x;
					vertexArray[ offset + 7 ] = v3.y;
					vertexArray[ offset + 8 ] = v3.z;
1343

1344
					vertexArray[ offset + 9 ]  = v4.x;
1345 1346
					vertexArray[ offset + 10 ] = v4.y;
					vertexArray[ offset + 11 ] = v4.z;
M
Mr.doob 已提交
1347

1348
					offset += 12;
M
Mr.doob 已提交
1349

1350
				}
1351

1352
				if ( customAttributes ) {
M
Mr.doob 已提交
1353

1354
					for ( a in customAttributes ) {
M
Mr.doob 已提交
1355

1356 1357
						customAttribute = customAttributes[ a ];

1358
						if ( customAttribute.__original.needsUpdate ) {
1359 1360

							offset_custom = customAttribute.offset;
1361
							offset_customSrc = customAttribute.offsetSrc;
M
Mr.doob 已提交
1362

1363 1364 1365
							if ( customAttribute.size === 1 ) {

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

1367 1368 1369
									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 已提交
1370
									customAttribute.array[ offset_custom + 3 ] = customAttribute.value[ face.d ];
1371 1372 1373

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

1374 1375 1376
									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 已提交
1377
									customAttribute.array[ offset_custom + 3 ] = customAttribute.value[ offset_customSrc ];
1378 1379

									customAttribute.offsetSrc++;
1380 1381 1382

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

1383 1384 1385
									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 已提交
1386
									customAttribute.array[ offset_custom + 3 ] = customAttribute.value[ offset_customSrc + 3 ];
1387

1388 1389
									customAttribute.offsetSrc += 4;
								}
M
Mr.doob 已提交
1390

1391
								customAttribute.offset += 4;
M
Mr.doob 已提交
1392

1393
							} else {
M
Mr.doob 已提交
1394

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

1397 1398 1399 1400
									v1 = customAttribute.value[ face.a ];
									v2 = customAttribute.value[ face.b ];
									v3 = customAttribute.value[ face.c ];
									v4 = customAttribute.value[ face.d ];
1401 1402 1403

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

1404 1405 1406 1407 1408 1409
									v1 = customAttribute.value[ offset_customSrc ];
									v2 = customAttribute.value[ offset_customSrc ];
									v3 = customAttribute.value[ offset_customSrc ];
									v4 = customAttribute.value[ offset_customSrc ];

									customAttribute.offsetSrc++;
1410 1411 1412

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

1413 1414 1415 1416
									v1 = customAttribute.value[ offset_customSrc + 0 ];
									v2 = customAttribute.value[ offset_customSrc + 1 ];
									v3 = customAttribute.value[ offset_customSrc + 2 ];
									v4 = customAttribute.value[ offset_customSrc + 3 ];
1417

1418 1419 1420
									customAttribute.offsetSrc += 4;
								}

M
Mr.doob 已提交
1421

1422
								if ( customAttribute.size === 2 ) {
M
Mr.doob 已提交
1423 1424 1425

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

M
Mr.doob 已提交
1427 1428
									customAttribute.array[ offset_custom + 2 ] = v2.x;
									customAttribute.array[ offset_custom + 3 ] = v2.y;
1429

M
Mr.doob 已提交
1430
									customAttribute.array[ offset_custom + 4 ] = v3.x;
1431
									customAttribute.array[ offset_custom + 5 ] = v3.y;
1432

M
Mr.doob 已提交
1433
									customAttribute.array[ offset_custom + 6 ] = v4.x;
1434
									customAttribute.array[ offset_custom + 7 ] = v4.y;
M
Mr.doob 已提交
1435

1436
									customAttribute.offset += 8;
M
Mr.doob 已提交
1437

1438 1439 1440
								} else if ( customAttribute.size === 3 ) {

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

1442 1443 1444
										customAttribute.array[ offset_custom + 0  ] = v1.r;
										customAttribute.array[ offset_custom + 1  ] = v1.g;
										customAttribute.array[ offset_custom + 2  ] = v1.b;
1445

1446 1447 1448
										customAttribute.array[ offset_custom + 3  ] = v2.r;
										customAttribute.array[ offset_custom + 4  ] = v2.g;
										customAttribute.array[ offset_custom + 5  ] = v2.b;
1449

1450 1451 1452
										customAttribute.array[ offset_custom + 6  ] = v3.r;
										customAttribute.array[ offset_custom + 7  ] = v3.g;
										customAttribute.array[ offset_custom + 8  ] = v3.b;
1453

1454 1455 1456 1457 1458
										customAttribute.array[ offset_custom + 9  ] = v4.r;
										customAttribute.array[ offset_custom + 10 ] = v4.g;
										customAttribute.array[ offset_custom + 11 ] = v4.b;

									} else {
1459

1460 1461 1462
										customAttribute.array[ offset_custom + 0  ] = v1.x;
										customAttribute.array[ offset_custom + 1  ] = v1.y;
										customAttribute.array[ offset_custom + 2  ] = v1.z;
1463

1464 1465 1466
										customAttribute.array[ offset_custom + 3  ] = v2.x;
										customAttribute.array[ offset_custom + 4  ] = v2.y;
										customAttribute.array[ offset_custom + 5  ] = v2.z;
1467

1468 1469 1470
										customAttribute.array[ offset_custom + 6  ] = v3.x;
										customAttribute.array[ offset_custom + 7  ] = v3.y;
										customAttribute.array[ offset_custom + 8  ] = v3.z;
1471

1472 1473 1474
										customAttribute.array[ offset_custom + 9  ] = v4.x;
										customAttribute.array[ offset_custom + 10 ] = v4.y;
										customAttribute.array[ offset_custom + 11 ] = v4.z;
1475

1476
									}
M
Mr.doob 已提交
1477

1478
									customAttribute.offset += 12;
M
Mr.doob 已提交
1479

1480
								} else {
M
Mr.doob 已提交
1481 1482 1483 1484 1485

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

M
Mr.doob 已提交
1487 1488 1489 1490
									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;
1491

M
Mr.doob 已提交
1492
									customAttribute.array[ offset_custom + 8  ] = v3.x;
1493 1494 1495
									customAttribute.array[ offset_custom + 9  ] = v3.y;
									customAttribute.array[ offset_custom + 10 ] = v3.z;
									customAttribute.array[ offset_custom + 11 ] = v3.w;
1496

M
Mr.doob 已提交
1497
									customAttribute.array[ offset_custom + 12 ] = v4.x;
1498 1499 1500
									customAttribute.array[ offset_custom + 13 ] = v4.y;
									customAttribute.array[ offset_custom + 14 ] = v4.z;
									customAttribute.array[ offset_custom + 15 ] = v4.w;
M
Mr.doob 已提交
1501

1502
									customAttribute.offset += 16;
M
Mr.doob 已提交
1503

1504
								}
M
Mr.doob 已提交
1505

1506
							}
M
Mr.doob 已提交
1507

1508
						}
M
Mr.doob 已提交
1509

1510
					}
M
Mr.doob 已提交
1511

1512 1513 1514
				}


1515
				if ( dirtyMorphTargets ) {
1516 1517 1518

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

1519 1520 1521 1522
						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;
1523

1524
						vka = morphTargetsArrays[ vk ];
1525

1526 1527 1528
						vka[ offset_morphTarget + 0 ] = v1.x;
						vka[ offset_morphTarget + 1 ] = v1.y;
						vka[ offset_morphTarget + 2 ] = v1.z;
1529

1530 1531 1532
						vka[ offset_morphTarget + 3 ] = v2.x;
						vka[ offset_morphTarget + 4 ] = v2.y;
						vka[ offset_morphTarget + 5 ] = v2.z;
1533

1534 1535 1536
						vka[ offset_morphTarget + 6 ] = v3.x;
						vka[ offset_morphTarget + 7 ] = v3.y;
						vka[ offset_morphTarget + 8 ] = v3.z;
1537

1538 1539 1540
						vka[ offset_morphTarget + 9 ] = v4.x;
						vka[ offset_morphTarget + 10 ] = v4.y;
						vka[ offset_morphTarget + 11 ] = v4.z;
1541 1542
					}

1543
					offset_morphTarget += 12;
1544

1545 1546
				}

A
alteredq 已提交
1547 1548 1549
				if ( obj_skinWeights.length ) {

					// weights
1550

A
alteredq 已提交
1551 1552 1553 1554
					sw1 = obj_skinWeights[ face.a ];
					sw2 = obj_skinWeights[ face.b ];
					sw3 = obj_skinWeights[ face.c ];
					sw4 = obj_skinWeights[ face.d ];
1555

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

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

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

A
alteredq 已提交
1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651
					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;

1652 1653
					skinVertexBArray[ offset_skin + 12 ] = sb4.x;
					skinVertexBArray[ offset_skin + 13 ] = sb4.y;
A
alteredq 已提交
1654 1655 1656
					skinVertexBArray[ offset_skin + 14 ] = sb4.z;
					skinVertexBArray[ offset_skin + 15 ] = 1;

1657 1658
					offset_skin += 16;

A
alteredq 已提交
1659
				}
1660

1661 1662 1663
				if ( dirtyColors && vertexColorType ) {

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

1665 1666 1667 1668 1669 1670
						c1 = vertexColors[ 0 ];
						c2 = vertexColors[ 1 ];
						c3 = vertexColors[ 2 ];
						c4 = vertexColors[ 3 ];

					} else {
1671

1672 1673 1674 1675 1676 1677
						c1 = faceColor;
						c2 = faceColor;
						c3 = faceColor;
						c4 = faceColor;

					}
1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689

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

1691 1692 1693
					colorArray[ offset_color + 9 ]  = c4.r;
					colorArray[ offset_color + 10 ] = c4.g;
					colorArray[ offset_color + 11 ] = c4.b;
1694

1695 1696
					offset_color += 12;

1697 1698
				}

1699
				if ( dirtyTangents && geometry.hasTangents ) {
1700

1701 1702 1703 1704
					t1 = vertexTangents[ 0 ];
					t2 = vertexTangents[ 1 ];
					t3 = vertexTangents[ 2 ];
					t4 = vertexTangents[ 3 ];
1705

1706 1707 1708 1709
					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 已提交
1710

1711 1712 1713 1714
					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 已提交
1715

1716 1717
					tangentArray[ offset_tangent + 8 ]  = t3.x;
					tangentArray[ offset_tangent + 9 ]  = t3.y;
1718 1719
					tangentArray[ offset_tangent + 10 ] = t3.z;
					tangentArray[ offset_tangent + 11 ] = t3.w;
M
Mr.doob 已提交
1720

1721 1722 1723 1724
					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 已提交
1725

1726
					offset_tangent += 16;
M
Mr.doob 已提交
1727

1728
				}
M
Mr.doob 已提交
1729

M
Mr.doob 已提交
1730
				if ( dirtyNormals && normalType ) {
M
Mr.doob 已提交
1731

1732
					if ( vertexNormals.length == 4 && needsSmoothNormals ) {
1733

1734
						for ( i = 0; i < 4; i ++ ) {
1735

1736
							vn = vertexNormals[ i ];
M
Mr.doob 已提交
1737

1738 1739 1740
							normalArray[ offset_normal ]     = vn.x;
							normalArray[ offset_normal + 1 ] = vn.y;
							normalArray[ offset_normal + 2 ] = vn.z;
M
Mr.doob 已提交
1741

1742
							offset_normal += 3;
M
Mr.doob 已提交
1743

1744
						}
M
Mr.doob 已提交
1745

1746
					} else {
1747

1748
						for ( i = 0; i < 4; i ++ ) {
1749

1750 1751 1752
							normalArray[ offset_normal ]     = faceNormal.x;
							normalArray[ offset_normal + 1 ] = faceNormal.y;
							normalArray[ offset_normal + 2 ] = faceNormal.z;
M
Mr.doob 已提交
1753

1754
							offset_normal += 3;
M
Mr.doob 已提交
1755

1756
						}
M
Mr.doob 已提交
1757 1758

					}
M
Mr.doob 已提交
1759

1760 1761
				}

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

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

1766
						uvi = uv[ i ];
M
Mr.doob 已提交
1767

1768 1769
						uvArray[ offset_uv ]     = uvi.u;
						uvArray[ offset_uv + 1 ] = uvi.v;
M
Mr.doob 已提交
1770

1771
						offset_uv += 2;
M
Mr.doob 已提交
1772

M
Mr.doob 已提交
1773
					}
1774 1775

				}
1776

A
alteredq 已提交
1777
				if ( dirtyUvs && uv2 !== undefined && uvType ) {
1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790

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

1792
				if ( dirtyElements ) {
M
Mr.doob 已提交
1793

1794
					faceArray[ offset_face ]     = vertexIndex;
1795 1796
					faceArray[ offset_face + 1 ] = vertexIndex + 1;
					faceArray[ offset_face + 2 ] = vertexIndex + 3;
M
Mr.doob 已提交
1797

1798 1799 1800
					faceArray[ offset_face + 3 ] = vertexIndex + 1;
					faceArray[ offset_face + 4 ] = vertexIndex + 2;
					faceArray[ offset_face + 5 ] = vertexIndex + 3;
M
Mr.doob 已提交
1801

1802
					offset_face += 6;
M
Mr.doob 已提交
1803

1804 1805
					lineArray[ offset_line ]     = vertexIndex;
					lineArray[ offset_line + 1 ] = vertexIndex + 1;
M
Mr.doob 已提交
1806

1807
					lineArray[ offset_line + 2 ] = vertexIndex;
1808
					lineArray[ offset_line + 3 ] = vertexIndex + 3;
M
Mr.doob 已提交
1809

1810 1811
					lineArray[ offset_line + 4 ] = vertexIndex + 1;
					lineArray[ offset_line + 5 ] = vertexIndex + 2;
M
Mr.doob 已提交
1812

1813 1814
					lineArray[ offset_line + 6 ] = vertexIndex + 2;
					lineArray[ offset_line + 7 ] = vertexIndex + 3;
M
Mr.doob 已提交
1815

1816
					offset_line += 8;
M
Mr.doob 已提交
1817

1818
					vertexIndex += 4;
M
Mr.doob 已提交
1819

1820
				}
M
Mr.doob 已提交
1821

1822
			}
M
Mr.doob 已提交
1823

1824 1825
		}

1826 1827 1828 1829
		if ( obj_edgeFaces ) {

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

M
Mikael Emtinger 已提交
1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840
				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;
			}

1841
		}
M
Mikael Emtinger 已提交
1842

1843
		if ( dirtyVertices ) {
M
Mr.doob 已提交
1844

1845
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
1846
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
M
Mr.doob 已提交
1847

1848
		}
M
Mr.doob 已提交
1849

1850
		if ( customAttributes ) {
M
Mr.doob 已提交
1851

1852
			for ( a in customAttributes ) {
M
Mr.doob 已提交
1853

1854 1855
				customAttribute = customAttributes[ a ];

1856
				if ( customAttribute.__original.needsUpdate ) {
1857 1858 1859 1860 1861 1862 1863 1864 1865 1866

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

				}

			}

		}

1867
		if ( dirtyMorphTargets ) {
1868 1869 1870 1871

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

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

1874 1875 1876
			}
		}

1877
		if ( dirtyColors && offset_color > 0 ) {
1878

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

		}
1883

1884
		if ( dirtyNormals ) {
M
Mr.doob 已提交
1885

1886
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
1887
			_gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
M
Mr.doob 已提交
1888

1889 1890
		}

1891
		if ( dirtyTangents && geometry.hasTangents ) {
1892

1893
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
1894
			_gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint );
M
Mr.doob 已提交
1895

1896
		}
1897

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

1900
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
1901
			_gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
M
Mr.doob 已提交
1902

1903
		}
M
Mr.doob 已提交
1904

1905 1906
		if ( dirtyUvs && offset_uv2 > 0 ) {

1907
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
1908 1909 1910 1911
			_gl.bufferData( _gl.ARRAY_BUFFER, uv2Array, hint );

		}

1912
		if ( dirtyElements ) {
M
Mr.doob 已提交
1913

1914
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
1915
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint );
1916

1917
			_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
1918
			_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
M
Mr.doob 已提交
1919

1920
		}
1921

1922
		if ( offset_skin > 0 ) {
1923

1924
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
A
alteredq 已提交
1925 1926
			_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexAArray, hint );

1927
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
A
alteredq 已提交
1928 1929
			_gl.bufferData( _gl.ARRAY_BUFFER, skinVertexBArray, hint );

1930
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
A
alteredq 已提交
1931 1932
			_gl.bufferData( _gl.ARRAY_BUFFER, skinIndexArray, hint );

1933
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
A
alteredq 已提交
1934
			_gl.bufferData( _gl.ARRAY_BUFFER, skinWeightArray, hint );
1935

A
alteredq 已提交
1936
		}
1937

1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954
		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;

		}
1955

1956
	};
1957

1958
	function setLineBuffers ( geometry, hint ) {
M
Mr.doob 已提交
1959

1960
		var v, c, vertex, offset,
1961 1962 1963 1964
		vertices = geometry.vertices,
		colors = geometry.colors,
		vl = vertices.length,
		cl = colors.length,
M
Mr.doob 已提交
1965

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

1969 1970
		dirtyVertices = geometry.__dirtyVertices,
		dirtyColors = geometry.__dirtyColors;
M
Mr.doob 已提交
1971

1972
		if ( dirtyVertices ) {
M
Mr.doob 已提交
1973

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

1976
				vertex = vertices[ v ].position;
M
Mr.doob 已提交
1977

1978
				offset = v * 3;
M
Mr.doob 已提交
1979

1980 1981 1982
				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;
M
Mr.doob 已提交
1983

1984 1985
			}

1986
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
A
alteredq 已提交
1987 1988
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );

1989
		}
M
Mr.doob 已提交
1990

1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004
		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;

			}

2005
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
2006 2007 2008 2009
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );

		}

2010
	};
M
Mr.doob 已提交
2011

2012
	function setRibbonBuffers ( geometry, hint ) {
A
alteredq 已提交
2013 2014

		var v, c, vertex, offset,
2015 2016 2017 2018
		vertices = geometry.vertices,
		colors = geometry.colors,
		vl = vertices.length,
		cl = colors.length,
A
alteredq 已提交
2019

2020 2021
		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,
2022

2023 2024
		dirtyVertices = geometry.__dirtyVertices,
		dirtyColors = geometry.__dirtyColors;
A
alteredq 已提交
2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039

		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;

			}

2040
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
A
alteredq 已提交
2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058
			_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;

			}

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

		}

	};
2065

2066
	function setParticleBuffers ( geometry, hint, object ) {
2067

A
alteredq 已提交
2068
		var v, c, vertex, offset,
2069 2070
		vertices = geometry.vertices,
		vl = vertices.length,
2071

2072 2073
		colors = geometry.colors,
		cl = colors.length,
2074

2075 2076
		vertexArray = geometry.__vertexArray,
		colorArray = geometry.__colorArray,
2077

2078
		sortArray = geometry.__sortArray,
2079

2080 2081 2082
		dirtyVertices = geometry.__dirtyVertices,
		dirtyElements = geometry.__dirtyElements,
		dirtyColors = geometry.__dirtyColors;
2083

2084
		if ( object.sortParticles ) {
2085

2086
			_projScreenMatrix.multiplySelf( object.matrixWorld );
2087

2088 2089 2090
			for ( v = 0; v < vl; v++ ) {

				vertex = vertices[ v ].position;
2091

2092 2093
				_vector3.copy( vertex );
				_projScreenMatrix.multiplyVector3( _vector3 );
2094

2095
				sortArray[ v ] = [ _vector3.z, v ];
2096

2097
			}
2098

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

2101
			for ( v = 0; v < vl; v++ ) {
2102

2103
				vertex = vertices[ sortArray[v][1] ].position;
2104

2105
				offset = v * 3;
2106

2107 2108 2109
				vertexArray[ offset ]     = vertex.x;
				vertexArray[ offset + 1 ] = vertex.y;
				vertexArray[ offset + 2 ] = vertex.z;
2110

2111
			}
2112

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

A
alteredq 已提交
2115
				offset = c * 3;
2116

A
alteredq 已提交
2117 2118 2119 2120 2121
				color = colors[ sortArray[c][1] ];

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

2123
			}
2124 2125


2126
		} else {
2127

2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140
			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;

				}
2141 2142

			}
2143

A
alteredq 已提交
2144
			if ( dirtyColors ) {
2145

A
alteredq 已提交
2146 2147 2148 2149 2150 2151 2152 2153 2154 2155
				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;

2156
				}
2157

A
alteredq 已提交
2158
			}
2159 2160

		}
2161

A
alteredq 已提交
2162
		if ( dirtyVertices || object.sortParticles ) {
2163

2164
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
A
alteredq 已提交
2165
			_gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
2166

A
alteredq 已提交
2167
		}
2168

A
alteredq 已提交
2169
		if ( dirtyColors || object.sortParticles ) {
2170

2171
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
A
alteredq 已提交
2172
			_gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
2173

A
alteredq 已提交
2174
		}
2175

2176
	};
M
Mr.doob 已提交
2177

2178
	function setMaterialShaders( material, shaders ) {
2179

2180
		material.uniforms = THREE.UniformsUtils.clone( shaders.uniforms );
2181 2182
		material.vertexShader = shaders.vertexShader;
		material.fragmentShader = shaders.fragmentShader;
2183

M
Mr.doob 已提交
2184
	};
2185

2186
	function refreshUniformsCommon( uniforms, material ) {
M
Mr.doob 已提交
2187

M
Mr.doob 已提交
2188
		uniforms.diffuse.value = material.color;
A
alteredq 已提交
2189
		uniforms.opacity.value = material.opacity;
M
Mr.doob 已提交
2190

A
alteredq 已提交
2191
		uniforms.map.texture = material.map;
2192
		if ( material.map ) {
M
Mr.doob 已提交
2193

2194 2195 2196
			uniforms.offsetRepeat.value.set( material.map.offset.x, material.map.offset.y, material.map.repeat.x, material.map.repeat.y );

		}
2197

2198
		uniforms.lightMap.texture = material.lightMap;
2199

2200
		uniforms.envMap.texture = material.envMap;
A
alteredq 已提交
2201
		uniforms.reflectivity.value = material.reflectivity;
2202
		uniforms.refractionRatio.value = material.refractionRatio;
A
alteredq 已提交
2203
		uniforms.combine.value = material.combine;
2204
		uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
2205

2206
	};
2207

2208
	function refreshUniformsLine( uniforms, material ) {
2209

M
Mr.doob 已提交
2210
		uniforms.diffuse.value = material.color;
A
alteredq 已提交
2211
		uniforms.opacity.value = material.opacity;
2212 2213

	};
M
Mr.doob 已提交
2214

2215
	function refreshUniformsParticle( uniforms, material ) {
2216

M
Mr.doob 已提交
2217
		uniforms.psColor.value = material.color;
A
alteredq 已提交
2218 2219
		uniforms.opacity.value = material.opacity;
		uniforms.size.value = material.size;
M
Mr.doob 已提交
2220
		uniforms.scale.value = _canvas.height / 2.0; // TODO: Cache this.
2221

A
alteredq 已提交
2222
		uniforms.map.texture = material.map;
2223

A
alteredq 已提交
2224
	};
2225

2226
	function refreshUniformsFog( uniforms, fog ) {
2227

M
Mr.doob 已提交
2228
		uniforms.fogColor.value = fog.color;
2229

A
alteredq 已提交
2230
		if ( fog instanceof THREE.Fog ) {
2231

A
alteredq 已提交
2232 2233
			uniforms.fogNear.value = fog.near;
			uniforms.fogFar.value = fog.far;
2234

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

A
alteredq 已提交
2237
			uniforms.fogDensity.value = fog.density;
2238 2239

		}
2240

2241 2242
	};

2243
	function refreshUniformsPhong( uniforms, material ) {
M
Mr.doob 已提交
2244

M
Mr.doob 已提交
2245 2246
		uniforms.ambient.value = material.ambient;
		uniforms.specular.value = material.specular;
A
alteredq 已提交
2247
		uniforms.shininess.value = material.shininess;
M
Mr.doob 已提交
2248

2249
	};
M
Mr.doob 已提交
2250 2251


2252
	function refreshUniformsLights( uniforms, lights ) {
M
Mr.doob 已提交
2253

A
alteredq 已提交
2254 2255
		uniforms.enableLighting.value = lights.directional.length + lights.point.length;
		uniforms.ambientLightColor.value = lights.ambient;
2256

A
alteredq 已提交
2257 2258
		uniforms.directionalLightColor.value = lights.directional.colors;
		uniforms.directionalLightDirection.value = lights.directional.positions;
2259

A
alteredq 已提交
2260 2261
		uniforms.pointLightColor.value = lights.point.colors;
		uniforms.pointLightPosition.value = lights.point.positions;
2262
		uniforms.pointLightDistance.value = lights.point.distances;
M
Mr.doob 已提交
2263

A
alteredq 已提交
2264
	};
M
Mr.doob 已提交
2265

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

2268
		var u, a, identifiers, i, parameters, maxLightCount, maxBones, shaderID;
2269

A
alteredq 已提交
2270
		if ( material instanceof THREE.MeshDepthMaterial ) {
2271

2272
			shaderID = 'depth';
2273

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

2276
			shaderID = 'shadowVolumeDynamic';
M
Mikael Emtinger 已提交
2277

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

2280
			shaderID = 'normal';
2281

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

2284
			shaderID = 'basic';
2285

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

2288
			shaderID = 'lambert';
M
Mr.doob 已提交
2289

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

2292
			shaderID = 'phong';
M
Mr.doob 已提交
2293

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

2296
			shaderID = 'basic';
2297

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

2300 2301 2302 2303 2304 2305 2306
			shaderID = 'particle_basic';

		}

		if ( shaderID ) {

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

A
alteredq 已提交
2308
		}
2309

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

2313
		maxLightCount = allocateLights( lights, 4 );
2314

2315
		maxBones = allocateBones( object );
M
Mr.doob 已提交
2316

2317
		parameters = {
M
Mr.doob 已提交
2318
			map: !!material.map, envMap: !!material.envMap, lightMap: !!material.lightMap,
2319
			vertexColors: material.vertexColors,
2320 2321 2322
			fog: fog, sizeAttenuation: material.sizeAttenuation,
			skinning: material.skinning,
			morphTargets: material.morphTargets,
2323
			maxMorphTargets: this.maxMorphTargets,
2324 2325 2326
			maxDirLights: maxLightCount.directional, maxPointLights: maxLightCount.point,
			maxBones: maxBones
		};
M
Mikael Emtinger 已提交
2327

2328
		material.program = buildProgram( shaderID, material.fragmentShader, material.vertexShader, material.uniforms, material.attributes, parameters );
2329

2330
		var attributes = material.program.attributes;
2331

2332
		if ( attributes.position >= 0 ) _gl.enableVertexAttribArray( attributes.position );
2333 2334 2335
		if ( attributes.color >= 0 ) _gl.enableVertexAttribArray( attributes.color );
		if ( attributes.normal >= 0 ) _gl.enableVertexAttribArray( attributes.normal );
		if ( attributes.tangent >= 0 ) _gl.enableVertexAttribArray( attributes.tangent );
2336

2337 2338 2339
		if ( material.skinning &&
			 attributes.skinVertexA >=0 && attributes.skinVertexB >= 0 &&
			 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
2340

2341 2342 2343 2344
			_gl.enableVertexAttribArray( attributes.skinVertexA );
			_gl.enableVertexAttribArray( attributes.skinVertexB );
			_gl.enableVertexAttribArray( attributes.skinIndex );
			_gl.enableVertexAttribArray( attributes.skinWeight );
2345

2346
		}
2347

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

2350
			for ( a in material.attributes ) {
M
Mr.doob 已提交
2351

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

2354
			}
M
Mr.doob 已提交
2355

2356
		}
2357 2358


2359

2360
		if ( material.morphTargets ) {
2361

2362
			material.numSupportedMorphTargets = 0;
2363

2364

2365
			if ( attributes.morphTarget0 >= 0 ) {
2366

2367 2368
				_gl.enableVertexAttribArray( attributes.morphTarget0 );
				material.numSupportedMorphTargets ++;
2369

2370
			}
2371

2372
			if ( attributes.morphTarget1 >= 0 ) {
2373

2374 2375
				_gl.enableVertexAttribArray( attributes.morphTarget1 );
				material.numSupportedMorphTargets ++;
2376

2377
			}
2378

2379
			if ( attributes.morphTarget2 >= 0 ) {
2380

2381 2382
				_gl.enableVertexAttribArray( attributes.morphTarget2 );
				material.numSupportedMorphTargets ++;
2383

2384
			}
2385

2386
			if ( attributes.morphTarget3 >= 0 ) {
2387

2388 2389
				_gl.enableVertexAttribArray( attributes.morphTarget3 );
				material.numSupportedMorphTargets ++;
2390

2391
			}
2392

2393
			if ( attributes.morphTarget4 >= 0 ) {
2394

2395 2396
				_gl.enableVertexAttribArray( attributes.morphTarget4 );
				material.numSupportedMorphTargets ++;
2397

2398
			}
2399

2400
			if ( attributes.morphTarget5 >= 0 ) {
2401

2402 2403
				_gl.enableVertexAttribArray( attributes.morphTarget5 );
				material.numSupportedMorphTargets ++;
2404

2405
			}
2406

2407
			if ( attributes.morphTarget6 >= 0 ) {
2408

2409 2410
				_gl.enableVertexAttribArray( attributes.morphTarget6 );
				material.numSupportedMorphTargets ++;
2411

2412
			}
2413

2414
			if ( attributes.morphTarget7 >= 0 ) {
2415

2416 2417
				_gl.enableVertexAttribArray( attributes.morphTarget7 );
				material.numSupportedMorphTargets ++;
2418

2419
			}
2420

2421
			object.__webglMorphTargetInfluences = new Float32Array( this.maxMorphTargets );
2422

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

2425
				object.__webglMorphTargetInfluences[ i ] = 0;
2426 2427 2428

			}

2429
		}
M
Mr.doob 已提交
2430

2431
	};
2432

2433
	function setProgram( camera, lights, fog, material, object ) {
2434

2435
		if ( ! material.program ) {
2436 2437 2438 2439

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

		}
M
Mr.doob 已提交
2440

2441
		var program = material.program,
A
alteredq 已提交
2442 2443
			p_uniforms = program.uniforms,
			m_uniforms = material.uniforms;
2444

2445
		if ( program != _currentProgram ) {
M
Mr.doob 已提交
2446

M
Mr.doob 已提交
2447
			_gl.useProgram( program );
2448
			_currentProgram = program;
2449

M
Mr.doob 已提交
2450
		}
2451

2452 2453
		_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, _projectionMatrixArray );

A
alteredq 已提交
2454
		// refresh uniforms common to several materials
2455 2456

		if ( fog && (
A
alteredq 已提交
2457 2458
			 material instanceof THREE.MeshBasicMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
2459
			 material instanceof THREE.MeshPhongMaterial ||
A
alteredq 已提交
2460
			 material instanceof THREE.LineBasicMaterial ||
2461 2462
			 material instanceof THREE.ParticleBasicMaterial ||
			 material.fog )
A
alteredq 已提交
2463
			) {
2464

A
alteredq 已提交
2465
			refreshUniformsFog( m_uniforms, fog );
2466 2467

		}
M
Mr.doob 已提交
2468

M
Mr.doob 已提交
2469
		if ( material instanceof THREE.MeshPhongMaterial ||
2470 2471
			 material instanceof THREE.MeshLambertMaterial ||
			 material.lights ) {
2472

A
alteredq 已提交
2473
			setupLights( program, lights );
A
alteredq 已提交
2474
			refreshUniformsLights( m_uniforms, _lights );
M
Mr.doob 已提交
2475 2476 2477

		}

2478 2479 2480
		if ( material instanceof THREE.MeshBasicMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
			 material instanceof THREE.MeshPhongMaterial ) {
M
Mr.doob 已提交
2481

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

A
alteredq 已提交
2484
		}
M
Mr.doob 已提交
2485

A
alteredq 已提交
2486
		// refresh single material specific uniforms
2487

2488
		if ( material instanceof THREE.LineBasicMaterial ) {
M
Mr.doob 已提交
2489

A
alteredq 已提交
2490
			refreshUniformsLine( m_uniforms, material );
2491

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

A
alteredq 已提交
2494
			refreshUniformsParticle( m_uniforms, material );
2495

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

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

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

2502 2503
			m_uniforms.mNear.value = camera.near;
			m_uniforms.mFar.value = camera.far;
A
alteredq 已提交
2504
			m_uniforms.opacity.value = material.opacity;
2505

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

A
alteredq 已提交
2508
			m_uniforms.opacity.value = material.opacity;
2509
		}
2510

A
alteredq 已提交
2511
		// load common uniforms
2512

A
alteredq 已提交
2513 2514
		loadUniformsGeneric( program, m_uniforms );
		loadUniformsMatrices( p_uniforms, object );
2515

A
alteredq 已提交
2516 2517
		// load material specific uniforms
		// (shader material also gets them for the sake of genericity)
2518

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

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

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

2527
			}
2528

2529
		}
2530

A
alteredq 已提交
2531
		if ( material instanceof THREE.MeshShaderMaterial ||
2532
			 material.envMap ||
2533
			 material.skinning ) {
2534

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

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

2539
			}
2540

A
alteredq 已提交
2541
		}
2542

A
alteredq 已提交
2543 2544
		if ( material instanceof THREE.MeshPhongMaterial ||
			 material instanceof THREE.MeshLambertMaterial ||
A
alteredq 已提交
2545
			 material instanceof THREE.MeshShaderMaterial ||
2546 2547
			 material.skinning ) {

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

2550
				_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, _viewMatrixArray );
M
Mr.doob 已提交
2551 2552

			}
2553

A
alteredq 已提交
2554
		}
2555

2556 2557
		if ( material instanceof THREE.ShadowVolumeDynamicMaterial ) {

M
Mikael Emtinger 已提交
2558
			var dirLight = m_uniforms.directionalLightDirection.value;
2559

2560 2561 2562
			dirLight[ 0 ] = -lights[ 1 ].position.x;
			dirLight[ 1 ] = -lights[ 1 ].position.y;
			dirLight[ 2 ] = -lights[ 1 ].position.z;
2563

M
Mikael Emtinger 已提交
2564 2565 2566 2567 2568 2569
			_gl.uniform3fv( p_uniforms.directionalLightDirection, dirLight );
			_gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object._objectMatrixArray );
			_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, _viewMatrixArray );
		}


2570
		if ( material.skinning ) {
2571

2572
			loadUniformsSkinning( p_uniforms, object );
2573

A
alteredq 已提交
2574
		}
2575

A
alteredq 已提交
2576
		return program;
2577

A
alteredq 已提交
2578
	};
2579

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

2582 2583
		if ( material.opacity == 0 ) return;

2584
		var program, attributes, linewidth, primitives, a, attribute;
A
alteredq 已提交
2585

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

2588
		attributes = program.attributes;
M
Mr.doob 已提交
2589

2590
		// vertices
M
Mr.doob 已提交
2591

2592
		if ( !material.morphTargets && attributes.position >= 0 ) {
2593 2594

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

2597
		} else {
2598

M
Mikael Emtinger 已提交
2599
			setupMorphTargets( material, geometryGroup, object );
2600

2601 2602
		}

2603 2604 2605

		// custom attributes

2606 2607
		// Use the per-geometryGroup custom attribute arrays which are setup in initMeshBuffers

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

2610
			for( a in geometryGroup.__webglCustomAttributes ) {
M
Mr.doob 已提交
2611

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

2614
					attribute = geometryGroup.__webglCustomAttributes[ a ];
M
Mr.doob 已提交
2615

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

2619
				}
M
Mr.doob 已提交
2620

2621
			}
M
Mr.doob 已提交
2622

2623
		}
2624 2625


2626
/*		if ( material.attributes ) {
2627 2628 2629

			for( a in material.attributes ) {

2630
				if( attributes[ a ] !== undefined && attributes[ a ] >= 0 ) {
2631 2632 2633

					attribute = material.attributes[ a ];

2634
					if( attribute.buffer ) {
M
Mr.doob 已提交
2635

2636 2637 2638 2639
						_gl.bindBuffer( _gl.ARRAY_BUFFER, attribute.buffer );
						_gl.vertexAttribPointer( attributes[ a ], attribute.size, _gl.FLOAT, false, 0, 0 );

					}
2640 2641 2642 2643 2644

				}

			}

2645
		}*/
2646 2647


2648

A
alteredq 已提交
2649 2650 2651 2652
		// colors

		if ( attributes.color >= 0 ) {

2653
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
2654
			_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
A
alteredq 已提交
2655 2656 2657

		}

2658
		// normals
M
Mr.doob 已提交
2659

2660
		if ( attributes.normal >= 0 ) {
2661

2662
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
2663
			_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
2664

2665
		}
2666

2667 2668 2669
		// tangents

		if ( attributes.tangent >= 0 ) {
2670

2671
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
2672
			_gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
2673

2674
		}
2675

2676
		// uvs
M
Mr.doob 已提交
2677

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

2680
			if ( geometryGroup.__webglUVBuffer ) {
2681

2682
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
2683
				_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
2684

2685
				_gl.enableVertexAttribArray( attributes.uv );
2686

2687
			} else {
2688

2689
				_gl.disableVertexAttribArray( attributes.uv );
M
Mr.doob 已提交
2690

2691
			}
2692 2693 2694

		}

2695 2696
		if ( attributes.uv2 >= 0 ) {

2697
			if ( geometryGroup.__webglUV2Buffer ) {
2698

2699
				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711
				_gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );

				_gl.enableVertexAttribArray( attributes.uv2 );

			} else {

				_gl.disableVertexAttribArray( attributes.uv2 );

			}

		}

2712
		if ( material.skinning &&
2713
			 attributes.skinVertexA >= 0 && attributes.skinVertexB >= 0 &&
A
alteredq 已提交
2714
			 attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
2715

2716
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexABuffer );
A
alteredq 已提交
2717 2718
			_gl.vertexAttribPointer( attributes.skinVertexA, 4, _gl.FLOAT, false, 0, 0 );

2719
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinVertexBBuffer );
A
alteredq 已提交
2720 2721
			_gl.vertexAttribPointer( attributes.skinVertexB, 4, _gl.FLOAT, false, 0, 0 );

2722
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
A
alteredq 已提交
2723 2724
			_gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 );

2725
			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
A
alteredq 已提交
2726
			_gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 );
2727

A
alteredq 已提交
2728
		}
2729

2730
		// render mesh
M
Mr.doob 已提交
2731

2732
		if ( object instanceof THREE.Mesh ) {
2733

2734
			// wireframe
2735

2736
			if ( material.wireframe ) {
M
Mr.doob 已提交
2737

2738
				_gl.lineWidth( material.wireframeLinewidth );
2739 2740
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
				_gl.drawElements( _gl.LINES, geometryGroup.__webglLineCount, _gl.UNSIGNED_SHORT, 0 );
2741

2742
			// triangles
2743

2744
			} else {
2745

2746 2747 2748
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
				_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );

2749
			}
2750

2751 2752
			_this.data.vertices += geometryGroup.__webglFaceCount;
			_this.data.faces += geometryGroup.__webglFaceCount / 3;
2753
			_this.data.drawCalls ++;
2754

2755
		// render lines
2756

2757
		} else if ( object instanceof THREE.Line ) {
2758

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

2761
			_gl.lineWidth( material.linewidth );
2762
			_gl.drawArrays( primitives, 0, geometryGroup.__webglLineCount );
2763

2764 2765
			_this.data.drawCalls ++;

2766
		// render particles
2767

2768
		} else if ( object instanceof THREE.ParticleSystem ) {
2769

2770
			_gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webglParticleCount );
2771

2772 2773
			_this.data.drawCalls ++;

A
alteredq 已提交
2774
		// render ribbon
2775

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

2778
			_gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webglVertexCount );
2779

2780 2781
			_this.data.drawCalls ++;

2782 2783 2784 2785
		}

	};

M
Mikael Emtinger 已提交
2786

M
Mikael Emtinger 已提交
2787
	function setupMorphTargets( material, geometryGroup, object ) {
2788

M
Mikael Emtinger 已提交
2789
		// set base
2790

M
Mikael Emtinger 已提交
2791
		var attributes = material.program.attributes;
2792

2793
		if (  object.morphTargetBase !== - 1 ) {
2794 2795

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

2798
		} else if ( attributes.position >= 0 ) {
2799 2800

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

M
Mikael Emtinger 已提交
2803
		}
2804

2805
		if ( object.morphTargetForcedOrder.length ) {
M
Mikael Emtinger 已提交
2806 2807

			// set forced order
2808

M
Mikael Emtinger 已提交
2809 2810 2811
			var m = 0;
			var order = object.morphTargetForcedOrder;
			var influences = object.morphTargetInfluences;
2812 2813 2814 2815

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

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

2818 2819 2820 2821
				object.__webglMorphTargetInfluences[ m ] = influences[ order[ m ]];

				m ++;
			}
2822

M
Mikael Emtinger 已提交
2823
		} else {
2824

M
Mikael Emtinger 已提交
2825
			// find most influencing
2826

M
Mikael Emtinger 已提交
2827
			var used = [];
2828
			var candidateInfluence = - 1;
M
Mikael Emtinger 已提交
2829 2830 2831 2832
			var candidate = 0;
			var influences = object.morphTargetInfluences;
			var i, il = influences.length;
			var m = 0;
2833

2834
			if ( object.morphTargetBase !== - 1 ) {
2835

M
Mikael Emtinger 已提交
2836
				used[ object.morphTargetBase ] = true;
2837

M
Mikael Emtinger 已提交
2838
			}
2839 2840 2841

			while ( m < material.numSupportedMorphTargets ) {

2842
				for ( i = 0; i < il; i ++ ) {
2843 2844 2845

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

M
Mikael Emtinger 已提交
2846 2847
						candidate = i;
						candidateInfluence = influences[ candidate ];
2848

M
Mikael Emtinger 已提交
2849 2850
					}
				}
2851 2852

				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ candidate ] );
M
Mikael Emtinger 已提交
2853
				_gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
2854 2855 2856

				object.__webglMorphTargetInfluences[ m ] = candidateInfluence;

M
Mikael Emtinger 已提交
2857 2858
				used[ candidate ] = 1;
				candidateInfluence = -1;
2859
				m ++;
M
Mikael Emtinger 已提交
2860 2861 2862 2863
			}
		}

		// load updated influences uniform
2864

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

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

2869 2870
		}

M
Mikael Emtinger 已提交
2871 2872 2873
	}


2874
	function renderBufferImmediate( object, program, shading ) {
2875

2876 2877
		if ( ! object.__webglVertexBuffer ) object.__webglVertexBuffer = _gl.createBuffer();
		if ( ! object.__webglNormalBuffer ) object.__webglNormalBuffer = _gl.createBuffer();
2878

A
alteredq 已提交
2879
		if ( object.hasPos ) {
2880

2881 2882 2883 2884
			_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 );
2885

A
alteredq 已提交
2886
		}
2887

A
alteredq 已提交
2888
		if ( object.hasNormal ) {
2889

2890
			_gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglNormalBuffer );
2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918

			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 已提交
2919
					normalArray[ i ] 	 = nx;
2920 2921 2922
					normalArray[ i + 1 ] = ny;
					normalArray[ i + 2 ] = nz;

M
Mr.doob 已提交
2923
					normalArray[ i + 3 ] = nx;
2924 2925 2926
					normalArray[ i + 4 ] = ny;
					normalArray[ i + 5 ] = nz;

M
Mr.doob 已提交
2927
					normalArray[ i + 6 ] = nx;
2928 2929 2930 2931 2932 2933 2934
					normalArray[ i + 7 ] = ny;
					normalArray[ i + 8 ] = nz;

				}

			}

2935 2936 2937
			_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 );
2938

A
alteredq 已提交
2939
		}
2940

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

A
alteredq 已提交
2943
		object.count = 0;
2944

A
alteredq 已提交
2945
	};
2946

2947
	function setObjectFaces( object ) {
2948

2949
		if ( _oldDoubleSided != object.doubleSided ) {
2950

2951
			if( object.doubleSided ) {
2952

2953
				_gl.disable( _gl.CULL_FACE );
2954

2955
			} else {
2956

A
alteredq 已提交
2957
				_gl.enable( _gl.CULL_FACE );
2958

A
alteredq 已提交
2959
			}
2960

2961
			_oldDoubleSided = object.doubleSided;
2962

2963
		}
2964

2965
		if ( _oldFlipSided != object.flipSided ) {
2966

2967 2968 2969 2970
			if( object.flipSided ) {

				_gl.frontFace( _gl.CW );

2971
			} else {
2972 2973 2974 2975

				_gl.frontFace( _gl.CCW );

			}
2976

2977
			_oldFlipSided = object.flipSided;
2978 2979

		}
2980

2981
	};
2982

2983
	function setDepthTest( test ) {
2984

A
alteredq 已提交
2985 2986 2987
		if ( _oldDepth != test ) {

			if( test ) {
2988

A
alteredq 已提交
2989
				_gl.enable( _gl.DEPTH_TEST );
2990

A
alteredq 已提交
2991
			} else {
2992

A
alteredq 已提交
2993
				_gl.disable( _gl.DEPTH_TEST );
2994

A
alteredq 已提交
2995
			}
2996

A
alteredq 已提交
2997 2998 2999
			_oldDepth = test;

		}
3000

A
alteredq 已提交
3001
	};
M
Mr.doob 已提交
3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030

	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;

		}

	};
3031

3032
	function computeFrustum( m ) {
3033 3034 3035 3036 3037 3038 3039 3040 3041

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

A
alteredq 已提交
3043
		for ( i = 0; i < 6; i ++ ) {
3044 3045 3046 3047 3048 3049 3050

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

		}

	};
3051

3052
	function isInFrustum( object ) {
3053

3054
		var distance, matrix = object.matrixWorld,
3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066
		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;

	};
3067

3068
	function addToFixedArray( where, what ) {
3069

3070 3071
		where.list[ where.count ] = what;
		where.count += 1;
3072

3073
	};
3074

3075
	function unrollImmediateBufferMaterials( globject ) {
3076

3077 3078 3079 3080 3081 3082 3083
		var i, l, m, ml, material,
			object = globject.object,
			opaque = globject.opaque,
			transparent = globject.transparent;

		transparent.count = 0;
		opaque.count = 0;
3084

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

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

3090
		}
3091

3092
	};
3093

3094
	function unrollBufferMaterials( globject ) {
3095

3096 3097 3098 3099 3100 3101 3102 3103
		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;
3104

3105 3106 3107 3108 3109 3110 3111 3112 3113
		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 ];
3114
					if ( material ) material.transparent ? addToFixedArray( transparent, material ) : addToFixedArray( opaque, material );
3115 3116 3117 3118 3119 3120

				}

			} else {

				material = meshMaterial;
3121
				if ( material ) material.transparent ? addToFixedArray( transparent, material ) : addToFixedArray( opaque, material );
3122

3123 3124 3125
			}

		}
3126

3127
	};
3128 3129


3130
	function painterSort( a, b ) {
3131

3132
		return b.z - a.z;
3133 3134

	};
3135

3136
	this.render = function( scene, camera, renderTarget, forceClear ) {
3137

A
alteredq 已提交
3138
		var i, program, opaque, transparent, material,
3139
			o, ol, oil, webglObject, object, buffer,
A
alteredq 已提交
3140
			lights = scene.lights,
N
Nicholas Kinsey 已提交
3141
			fog = scene.fog;
3142

3143 3144
		_this.data.vertices = 0;
		_this.data.faces = 0;
3145
		_this.data.drawCalls = 0;
3146

3147
		camera.matrixAutoUpdate && camera.update( undefined, true );
3148

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

M
Mr.doob 已提交
3151
		camera.matrixWorldInverse.flattenToArray( _viewMatrixArray );
3152
		camera.projectionMatrix.flattenToArray( _projectionMatrixArray );
M
Mr.doob 已提交
3153

M
Mr.doob 已提交
3154
		_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
3155
		computeFrustum( _projScreenMatrix );
3156

A
alteredq 已提交
3157
		this.initWebGLObjects( scene );
M
Mr.doob 已提交
3158

A
alteredq 已提交
3159
		setRenderTarget( renderTarget );
M
Mr.doob 已提交
3160

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

3163
			this.clear();
M
Mr.doob 已提交
3164

3165 3166
		}

3167
		// set matrices
3168

3169
		ol = scene.__webglObjects.length;
3170

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

3173 3174
			webglObject = scene.__webglObjects[ o ];
			object = webglObject.object;
M
Mr.doob 已提交
3175

3176
			if ( object.visible ) {
3177 3178

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

3180
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
3181

3182
					setupMatrices( object, camera );
3183

3184
					unrollBufferMaterials( webglObject );
3185

3186
					webglObject.render = true;
3187

3188
					if ( this.sortObjects ) {
3189

3190
						if ( webglObject.object.renderDepth ) {
M
Mr.doob 已提交
3191

3192
							webglObject.z = webglObject.object.renderDepth;
M
Mr.doob 已提交
3193

3194
						} else {
M
Mr.doob 已提交
3195

3196 3197
							_vector3.copy( object.position );
							_projScreenMatrix.multiplyVector3( _vector3 );
M
Mr.doob 已提交
3198

3199
							webglObject.z = _vector3.z;
M
Mr.doob 已提交
3200

3201
						}
3202

3203
					}
3204

3205
				} else {
3206

3207
					webglObject.render = false;
3208

3209
				}
3210

3211
			} else {
3212

3213
				webglObject.render = false;
3214

3215
			}
3216

3217
		}
3218

3219
		if ( this.sortObjects ) {
3220

3221
			scene.__webglObjects.sort( painterSort );
3222

3223
		}
3224

3225
		oil = scene.__webglObjectsImmediate.length;
3226

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

3229 3230
			webglObject = scene.__webglObjectsImmediate[ o ];
			object = webglObject.object;
3231

3232
			if ( object.visible ) {
3233 3234 3235

				if( object.matrixAutoUpdate ) {

3236
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
3237

A
alteredq 已提交
3238
				}
3239

3240
				setupMatrices( object, camera );
3241

3242
				unrollImmediateBufferMaterials( webglObject );
3243

3244
			}
3245

3246
		}
A
alteredq 已提交
3247

M
Mr.doob 已提交
3248
		if ( scene.overrideMaterial ) {
3249

M
Mr.doob 已提交
3250 3251
			setDepthTest( scene.overrideMaterial.depthTest );
			setBlending( scene.overrideMaterial.blending );
3252

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

M
Mr.doob 已提交
3255 3256 3257
				webglObject = scene.__webglObjects[ o ];

				if ( webglObject.render ) {
3258

M
Mr.doob 已提交
3259 3260
					object = webglObject.object;
					buffer = webglObject.buffer;
3261

M
Mr.doob 已提交
3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272
					setObjectFaces( object );

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

				}

			}

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

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

M
Mr.doob 已提交
3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302
				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 );
3303

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

M
Mr.doob 已提交
3306
						material = opaque.list[ i ];
3307

M
Mr.doob 已提交
3308 3309 3310 3311 3312
						setDepthTest( material.depthTest );
						setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
						renderBuffer( camera, lights, fog, material, buffer, object );

					}
3313

3314
				}
3315 3316 3317

			}

M
Mr.doob 已提交
3318
			// opaque pass (immediate simulator)
3319

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

M
Mr.doob 已提交
3322 3323
				webglObject = scene.__webglObjectsImmediate[ o ];
				object = webglObject.object;
3324

M
Mr.doob 已提交
3325
				if ( object.visible ) {
3326

M
Mr.doob 已提交
3327
					opaque = webglObject.opaque;
3328

M
Mr.doob 已提交
3329
					setObjectFaces( object );
3330

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

M
Mr.doob 已提交
3333
						material = opaque.list[ i ];
3334

M
Mr.doob 已提交
3335 3336
						setDepthTest( material.depthTest );
						setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
3337

M
Mr.doob 已提交
3338 3339
						program = setProgram( camera, lights, fog, material, object );
						object.render( function( object ) { renderBufferImmediate( object, program, material.shading ); } );
3340

M
Mr.doob 已提交
3341
					}
3342

3343
				}
3344

A
alteredq 已提交
3345
			}
3346

M
Mr.doob 已提交
3347
			// transparent pass
A
alteredq 已提交
3348

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

M
Mr.doob 已提交
3351
				webglObject = scene.__webglObjects[ o ];
3352

M
Mr.doob 已提交
3353
				if ( webglObject.render ) {
3354

M
Mr.doob 已提交
3355 3356 3357
					object = webglObject.object;
					buffer = webglObject.buffer;
					transparent = webglObject.transparent;
3358

M
Mr.doob 已提交
3359
					setObjectFaces( object );
3360

M
Mr.doob 已提交
3361
					for ( i = 0; i < transparent.count; i ++ ) {
3362

M
Mr.doob 已提交
3363
						material = transparent.list[ i ];
3364

M
Mr.doob 已提交
3365 3366 3367
						setBlending( material.blending );
						setDepthTest( material.depthTest );
						setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
3368

M
Mr.doob 已提交
3369
						renderBuffer( camera, lights, fog, material, buffer, object );
3370

M
Mr.doob 已提交
3371
					}
3372

3373
				}
3374

3375
			}
M
Mr.doob 已提交
3376

M
Mr.doob 已提交
3377
			// transparent pass (immediate simulator)
M
Mr.doob 已提交
3378

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

M
Mr.doob 已提交
3381 3382
				webglObject = scene.__webglObjectsImmediate[ o ];
				object = webglObject.object;
3383

M
Mr.doob 已提交
3384
				if ( object.visible ) {
3385

M
Mr.doob 已提交
3386
					transparent = webglObject.transparent;
3387

M
Mr.doob 已提交
3388
					setObjectFaces( object );
3389

M
Mr.doob 已提交
3390
					for ( i = 0; i < transparent.count; i ++ ) {
3391

M
Mr.doob 已提交
3392
						material = transparent.list[ i ];
3393

M
Mr.doob 已提交
3394 3395 3396
						setBlending( material.blending );
						setDepthTest( material.depthTest );
						setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
3397

M
Mr.doob 已提交
3398 3399
						program = setProgram( camera, lights, fog, material, object );
						object.render( function( object ) { renderBufferImmediate( object, program, material.shading ); } );
3400

M
Mr.doob 已提交
3401
					}
3402

3403
				}
3404

3405
			}
3406

3407
		}
3408

M
Mikael Emtinger 已提交
3409
		// render 2d
3410

M
Mikael Emtinger 已提交
3411
		if ( scene.__webglSprites.length ) {
3412

3413
			renderSprites( scene, camera );
3414

M
Mikael Emtinger 已提交
3415 3416
		}

M
Mikael Emtinger 已提交
3417
		// render stencil shadows
M
Mikael Emtinger 已提交
3418

3419
		if ( _stencil && scene.__webglShadowVolumes.length && scene.lights.length ) {
M
Mikael Emtinger 已提交
3420 3421

			renderStencilShadows( scene );
3422

M
Mikael Emtinger 已提交
3423 3424
		}

3425

3426
		// render lens flares
3427 3428 3429

		if ( scene.__webglLensFlares.length ) {

3430
			renderLensFlares( scene, camera );
3431

3432 3433
		}

M
Mikael Emtinger 已提交
3434 3435 3436 3437 3438 3439 3440 3441 3442

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

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

			updateRenderTargetMipmap( renderTarget );

		}

3443
		//_gl.finish();
3444

M
Mikael Emtinger 已提交
3445 3446 3447 3448 3449 3450 3451
	};



	/*
	 * Stencil Shadows
	 * method: we're rendering the world in light, then the shadow
M
Mr.doob 已提交
3452
	 *         volumes into the stencil and last a big darkening
M
Mikael Emtinger 已提交
3453 3454
	 *         quad over the whole thing. This is not how "you're
	 *	       supposed to" do stencil shadows but is much faster
M
Mr.doob 已提交
3455
	 *
M
Mikael Emtinger 已提交
3456 3457 3458
	 */

	function renderStencilShadows( scene ) {
3459

M
Mikael Emtinger 已提交
3460 3461 3462 3463 3464
		// setup stencil

		_gl.enable( _gl.POLYGON_OFFSET_FILL );
		_gl.polygonOffset( 0.1, 1.0 );
		_gl.enable( _gl.STENCIL_TEST );
3465
		_gl.enable( _gl.DEPTH_TEST );
M
Mikael Emtinger 已提交
3466 3467
		_gl.depthMask( false );
		_gl.colorMask( false, false, false, false );
3468

M
Mikael Emtinger 已提交
3469 3470 3471 3472
		_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 );

3473

M
Mikael Emtinger 已提交
3474
		// loop through all directional lights
3475

M
Mikael Emtinger 已提交
3476 3477
		var l, ll = scene.lights.length;
		var p;
M
Mikael Emtinger 已提交
3478
		var light, lights = scene.lights;
3479
		var dirLight = [];
M
Mikael Emtinger 已提交
3480
		var object, geometryGroup, material;
3481
		var program;
M
Mikael Emtinger 已提交
3482
		var p_uniforms;
3483 3484
		var m_uniforms;
		var attributes;
M
Mikael Emtinger 已提交
3485
		var o, ol = scene.__webglShadowVolumes.length;
3486 3487 3488

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

M
Mikael Emtinger 已提交
3489
			light = scene.lights[ l ];
3490

3491
			if ( light instanceof THREE.DirectionalLight && light.castShadow ) {
M
Mikael Emtinger 已提交
3492 3493 3494 3495 3496 3497

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

				// render all volumes
3498 3499 3500

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

M
Mikael Emtinger 已提交
3501 3502 3503
					object        = scene.__webglShadowVolumes[ o ].object;
					geometryGroup = scene.__webglShadowVolumes[ o ].buffer;
					material      = object.materials[ 0 ];
3504

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

M
Mikael Emtinger 已提交
3507
					program = material.program,
3508
					p_uniforms = program.uniforms,
3509 3510
					m_uniforms = material.uniforms,
					attributes = program.attributes;
3511

3512
					if ( _currentProgram !== program ) {
3513

M
Mikael Emtinger 已提交
3514
						_gl.useProgram( program );
M
Mikael Emtinger 已提交
3515
						_currentProgram = program;
3516

M
Mikael Emtinger 已提交
3517 3518 3519 3520
						_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, _projectionMatrixArray );
						_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, _viewMatrixArray );
						_gl.uniform3fv( p_uniforms.directionalLightDirection, dirLight );
					}
3521 3522


M
Mikael Emtinger 已提交
3523 3524
					object.matrixWorld.flattenToArray( object._objectMatrixArray );
					_gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object._objectMatrixArray );
3525 3526


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

M
Mikael Emtinger 已提交
3530
					_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
M
Mikael Emtinger 已提交
3531
					_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
3532

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

M
Mikael Emtinger 已提交
3535
					_gl.cullFace( _gl.FRONT );
M
Mikael Emtinger 已提交
3536
					_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );
3537

M
Mikael Emtinger 已提交
3538
					_gl.cullFace( _gl.BACK );
M
Mikael Emtinger 已提交
3539
					_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );
3540

M
Mikael Emtinger 已提交
3541
				}
M
Mikael Emtinger 已提交
3542

M
Mikael Emtinger 已提交
3543
			}
M
Mikael Emtinger 已提交
3544

M
Mikael Emtinger 已提交
3545 3546
		}

3547

M
Mikael Emtinger 已提交
3548
		// setup color+stencil
M
Mikael Emtinger 已提交
3549

M
Mikael Emtinger 已提交
3550 3551 3552 3553
		_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 );
3554
		_gl.disable( _gl.DEPTH_TEST );
M
Mikael Emtinger 已提交
3555 3556


3557
		// draw darkening polygon
M
Mr.doob 已提交
3558

3559
		_oldBlending = -1;
M
Mikael Emtinger 已提交
3560
		_currentProgram = _stencilShadow.program;
M
Mr.doob 已提交
3561

M
Mikael Emtinger 已提交
3562 3563 3564
		_gl.useProgram( _stencilShadow.program );
		_gl.uniformMatrix4fv( _stencilShadow.projectionLocation, false, _projectionMatrixArray );
		_gl.uniform1f( _stencilShadow.darknessLocation, _stencilShadow.darkness );
3565

M
Mikael Emtinger 已提交
3566 3567 3568
		_gl.bindBuffer( _gl.ARRAY_BUFFER, _stencilShadow.vertexBuffer );
		_gl.vertexAttribPointer( _stencilShadow.vertexLocation, 3, _gl.FLOAT, false, 0, 0 );
		_gl.enableVertexAttribArray( _stencilShadow.vertexLocation );
M
Mr.doob 已提交
3569

M
Mikael Emtinger 已提交
3570 3571
		_gl.blendFunc( _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
		_gl.blendEquation( _gl.FUNC_ADD );
3572

M
Mikael Emtinger 已提交
3573
		_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _stencilShadow.elementBuffer );
M
Mikael Emtinger 已提交
3574 3575 3576 3577 3578
		_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );


		// disable stencil

3579 3580 3581 3582
		_gl.disable( _gl.STENCIL_TEST );
		_gl.enable( _gl.DEPTH_TEST );
		_gl.depthMask( _currentDepthMask );

M
Mikael Emtinger 已提交
3583
	}
3584

3585

3586 3587
	/*
	 * Render sprites
M
Mr.doob 已提交
3588
	 *
3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604
	 */

	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
3605

3606 3607
		_gl.useProgram( _sprite.program );
		_currentProgram = _sprite.program;
3608
		_oldBlending = -1;
3609

M
Mr.doob 已提交
3610
		if ( !_spriteAttributesEnabled ) {
3611

M
Mr.doob 已提交
3612 3613
			_gl.enableVertexAttribArray( _sprite.attributes.position );
			_gl.enableVertexAttribArray( _sprite.attributes.uv );
3614

M
Mr.doob 已提交
3615 3616 3617
			_spriteAttributesEnabled = true;

		}
3618

3619
		_gl.disable( _gl.CULL_FACE );
3620
		_gl.enable( _gl.BLEND );
3621
		_gl.depthMask( true );
3622 3623 3624 3625 3626 3627

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

3629 3630 3631 3632
		_gl.uniformMatrix4fv( uniforms.projectionMatrix, false, _projectionMatrixArray );

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

3634
		// update positions and sort
3635

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

3638
			object = scene.__webglSprites[ o ];
3639

3640
			if( !object.useScreenCoordinates ) {
3641

3642 3643
				object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
				object.z = -object._modelViewMatrix.n34;
3644

3645
			} else {
3646

3647
				object.z = -object.position.z;
3648

3649
			}
3650

3651 3652 3653
		}

		scene.__webglSprites.sort( painterSort );
3654 3655

		// render all non-custom shader sprites
3656 3657

		for ( o = 0, ol = scene.__webglSprites.length; o < ol; o++ ) {
3658 3659 3660

			object = scene.__webglSprites[ o ];

3661 3662 3663 3664 3665
			if ( object.material === undefined ) {

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

					if ( object.useScreenCoordinates ) {
3666 3667

						_gl.uniform1i( uniforms.useScreenCoordinates, 1 );
M
Mr.doob 已提交
3668
						_gl.uniform3f( uniforms.screenPosition, ( object.position.x - halfViewportWidth  ) / halfViewportWidth,
3669 3670
																( halfViewportHeight - object.position.y ) / halfViewportHeight,
																  Math.max( 0, Math.min( 1, object.position.z )));
3671

3672 3673
					} else {

3674

3675 3676 3677 3678

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

3680
					}
3681

3682
					size = object.map.image.width / ( object.scaleByViewport ? _viewportHeight : 1 );
3683
					scale[ 0 ] = size * invAspect * object.scale.x;
3684
					scale[ 1 ] = size * object.scale.y;
3685

3686 3687 3688 3689 3690 3691 3692
					_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 );

3693 3694
					if ( object.mergeWith3D && !mergeWith3D ) {

3695 3696
						_gl.enable( _gl.DEPTH_TEST );
						mergeWith3D = true;
3697 3698 3699

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

3700 3701
						_gl.disable( _gl.DEPTH_TEST );
						mergeWith3D = false;
3702

3703
					}
3704

3705 3706
					setBlending( object.blending );
					setTexture( object.map, 0 );
3707

3708 3709
					_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
				}
3710

3711
			} else {
3712

3713
				anyCustom = true;
3714

3715
			}
3716

3717 3718 3719 3720 3721
		}


		// loop through all custom

3722 3723 3724
		/*
		if( anyCustom ) {

3725
		}
3726
		*/
3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737

		// restore gl

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

	}



3738 3739
	/*
	 * Render lens flares
M
Mr.doob 已提交
3740 3741 3742
	 * 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
3743
	 *         update transparency of flares. Then they are rendered.
M
Mr.doob 已提交
3744
	 *
3745 3746 3747
	 */

	function renderLensFlares( scene, camera ) {
3748

3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770
		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 已提交
3771
		_currentProgram = _lensFlare.program;
3772
		_oldBlending = -1;
3773 3774


M
Mr.doob 已提交
3775
		if ( ! _lensFlareAttributesEnabled ) {
M
Mr.doob 已提交
3776

M
Mr.doob 已提交
3777 3778
			_gl.enableVertexAttribArray( _lensFlare.attributes.vertex );
			_gl.enableVertexAttribArray( _lensFlare.attributes.uv );
M
Mr.doob 已提交
3779

M
Mr.doob 已提交
3780 3781 3782 3783
			_lensFlareAttributesEnabled = true;

		}

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

3787 3788
		_gl.uniform1i( uniforms.occlusionMap, 0 );
		_gl.uniform1i( uniforms.map, 1 );
3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799

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

3800 3801 3802 3803
		_gl.activeTexture( _gl.TEXTURE0 );
		_gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.occlusionTexture );

		_gl.activeTexture( _gl.TEXTURE1 );
3804

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

3807
			// calc object screen position
3808

3809
			object = scene.__webglLensFlares[ o ].object;
3810

3811
			tempPosition.set( object.matrixWorld.n14, object.matrixWorld.n24, object.matrixWorld.n34 );
3812

3813 3814 3815
			camera.matrixWorldInverse.multiplyVector3( tempPosition );
			objectZ = tempPosition.z;
			camera.projectionMatrix.multiplyVector3( tempPosition );
3816 3817


3818
			// setup arrays for gl programs
3819

3820 3821 3822
			screenPosition[ 0 ] = tempPosition.x;
			screenPosition[ 1 ] = tempPosition.y;
			screenPosition[ 2 ] = tempPosition.z;
3823

3824 3825
			screenPositionPixels[ 0 ] = screenPosition[ 0 ] * halfViewportWidth + halfViewportWidth;
			screenPositionPixels[ 1 ] = screenPosition[ 1 ] * halfViewportHeight + halfViewportHeight;
3826

3827

M
Mr.doob 已提交
3828
			// screen cull
3829 3830

			if ( _lensFlare.hasVertexTexture || ( screenPositionPixels[ 0 ] > 0 &&
3831 3832
				screenPositionPixels[ 0 ] < _viewportWidth &&
				screenPositionPixels[ 1 ] > 0 &&
3833
				screenPositionPixels[ 1 ] < _viewportHeight )) {
3834 3835


3836
				// save current RGB to temp texture
3837

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

3841

3842
				// render pink quad
3843

3844 3845 3846
				_gl.uniform1i( uniforms.renderType, 0 );
				_gl.uniform2fv( uniforms.scale, scale );
				_gl.uniform3fv( uniforms.screenPosition, screenPosition );
3847

3848 3849
				_gl.disable( _gl.BLEND );
				_gl.enable( _gl.DEPTH_TEST );
3850

3851
				_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
3852 3853


3854
				// copy result to occlusionMap
3855

3856
				_gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.occlusionTexture );
3857
				_gl.copyTexImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, screenPositionPixels[ 0 ] - 8, screenPositionPixels[ 1 ] - 8, 16, 16, 0 );
3858 3859


3860
				// restore graphics
3861

3862 3863 3864 3865
				_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 );
3866 3867


3868
				// update object positions
3869

3870 3871 3872
				object.positionScreen.x = screenPosition[ 0 ];
				object.positionScreen.y = screenPosition[ 1 ];
				object.positionScreen.z = screenPosition[ 2 ];
3873

3874
				if ( object.customUpdateCallback ) {
3875

3876
					object.customUpdateCallback( object );
3877

3878
				} else {
3879

3880
					object.updateLensFlares();
3881

3882
				}
3883 3884


3885
				// render flares
3886

3887 3888
				_gl.uniform1i( uniforms.renderType, 2 );
				_gl.enable( _gl.BLEND );
3889

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

3892
					flare = object.lensFlares[ f ];
3893

3894
					if ( flare.opacity > 0.001 && flare.scale > 0.001 ) {
3895

3896 3897 3898
						screenPosition[ 0 ] = flare.x;
						screenPosition[ 1 ] = flare.y;
						screenPosition[ 2 ] = flare.z;
3899

3900 3901 3902
						size = flare.size * flare.scale / _viewportHeight;
						scale[ 0 ] = size * invAspect;
						scale[ 1 ] = size;
3903

3904 3905 3906 3907
						_gl.uniform3fv( uniforms.screenPosition, screenPosition );
						_gl.uniform2fv( uniforms.scale, scale );
						_gl.uniform1f( uniforms.rotation, flare.rotation );
						_gl.uniform1f( uniforms.opacity, flare.opacity );
3908

3909 3910
						setBlending( flare.blending );
						setTexture( flare.texture, 1 );
3911

3912
						_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
3913

3914
					}
3915

3916
				}
3917

3918
			}
M
Mr.doob 已提交
3919

3920 3921 3922
		}

		// restore gl
3923

3924 3925
		_gl.enable( _gl.CULL_FACE );
		_gl.enable( _gl.DEPTH_TEST );
3926
		_gl.depthMask( _currentDepthMask );
3927

3928
	};
3929 3930


3931
	function setupMatrices( object, camera ) {
3932

3933 3934
		object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
		THREE.Matrix4.makeInvert3x3( object._modelViewMatrix ).transposeIntoArray( object._normalMatrixArray );
3935

3936
	};
3937

A
alteredq 已提交
3938
	this.initWebGLObjects = function ( scene ) {
3939

3940
		if ( !scene.__webglObjects ) {
3941

3942 3943
			scene.__webglObjects = [];
			scene.__webglObjectsImmediate = [];
M
Mikael Emtinger 已提交
3944
			scene.__webglShadowVolumes = [];
M
Mikael Emtinger 已提交
3945
			scene.__webglLensFlares = [];
M
Mikael Emtinger 已提交
3946
			scene.__webglSprites = [];
3947

3948 3949
		}

M
Mr.doob 已提交
3950
		while ( scene.__objectsAdded.length ) {
3951

M
Mr.doob 已提交
3952 3953
			addObject( scene.__objectsAdded[ 0 ], scene );
			scene.__objectsAdded.splice( 0, 1 );
3954 3955 3956

		}

M
Mr.doob 已提交
3957
		while ( scene.__objectsRemoved.length ) {
3958

M
Mr.doob 已提交
3959 3960
			removeObject( scene.__objectsRemoved[ 0 ], scene );
			scene.__objectsRemoved.splice( 0, 1 );
3961 3962

		}
3963

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

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

M
Mr.doob 已提交
3968
			updateObject( scene.__webglObjects[ o ].object, scene );
A
alteredq 已提交
3969 3970

		}
3971

M
Mikael Emtinger 已提交
3972 3973 3974 3975 3976
		for ( var o = 0, ol = scene.__webglShadowVolumes.length; o < ol; o ++ ) {

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

		}
3977

M
Mikael Emtinger 已提交
3978 3979 3980 3981 3982
		for ( var o = 0, ol = scene.__webglLensFlares.length; o < ol; o ++ ) {

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

		}
A
alteredq 已提交
3983

3984 3985
		/*
		for ( var o = 0, ol = scene.__webglSprites.length; o < ol; o ++ ) {
M
Mikael Emtinger 已提交
3986 3987 3988

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

3989 3990
		}
		*/
M
Mikael Emtinger 已提交
3991

3992
	};
3993

3994
	function addObject( object, scene ) {
3995

3996
		var g, geometry, geometryGroup;
M
Mr.doob 已提交
3997

3998
		if ( object._modelViewMatrix == undefined ) {
3999

4000
			object._modelViewMatrix = new THREE.Matrix4();
4001

4002 4003 4004
			object._normalMatrixArray = new Float32Array( 9 );
			object._modelViewMatrixArray = new Float32Array( 16 );
			object._objectMatrixArray = new Float32Array( 16 );
4005

4006
			object.matrixWorld.flattenToArray( object._objectMatrixArray );
M
Mr.doob 已提交
4007

4008
		}
A
alteredq 已提交
4009

4010
		if ( object instanceof THREE.Mesh ) {
A
alteredq 已提交
4011

4012 4013 4014 4015 4016 4017 4018 4019
			geometry = object.geometry;

			if ( geometry.geometryGroups == undefined ) {

				sortFacesByMaterial( geometry );

			}

4020
			// create separate VBOs per geometry chunk
A
alteredq 已提交
4021

4022
			for ( g in geometry.geometryGroups ) {
A
alteredq 已提交
4023

4024
				geometryGroup = geometry.geometryGroups[ g ];
M
Mr.doob 已提交
4025

4026
				// initialise VBO on the first access
M
Mr.doob 已提交
4027

4028
				if ( ! geometryGroup.__webglVertexBuffer ) {
M
Mr.doob 已提交
4029

4030 4031
					createMeshBuffers( geometryGroup );
					initMeshBuffers( geometryGroup, object );
A
alteredq 已提交
4032

4033
					geometry.__dirtyVertices = true;
4034
					geometry.__dirtyMorphTargets = true;
4035 4036 4037 4038 4039
					geometry.__dirtyElements = true;
					geometry.__dirtyUvs = true;
					geometry.__dirtyNormals = true;
					geometry.__dirtyTangents = true;
					geometry.__dirtyColors = true;
M
Mr.doob 已提交
4040

4041
				}
4042

4043
				// create separate wrapper per each use of VBO
4044

4045 4046
				if ( object instanceof THREE.ShadowVolume ) {

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

M
Mikael Emtinger 已提交
4049
				} else {
4050

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

M
Mikael Emtinger 已提交
4053
				}
4054

4055
			}
M
Mr.doob 已提交
4056

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

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

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

4063 4064
			geometry = object.geometry;

4065
			if( ! geometry.__webglVertexBuffer ) {
A
alteredq 已提交
4066 4067 4068 4069 4070 4071 4072 4073 4074

				createRibbonBuffers( geometry );
				initRibbonBuffers( geometry );

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

			}

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

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

4079 4080
			geometry = object.geometry;

4081
			if( ! geometry.__webglVertexBuffer ) {
M
Mr.doob 已提交
4082

4083 4084
				createLineBuffers( geometry );
				initLineBuffers( geometry );
M
Mr.doob 已提交
4085

4086 4087
				geometry.__dirtyVertices = true;
				geometry.__dirtyColors = true;
M
Mr.doob 已提交
4088

4089
			}
M
Mr.doob 已提交
4090

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

A
alteredq 已提交
4093 4094 4095 4096
		} else if ( object instanceof THREE.ParticleSystem ) {

			geometry = object.geometry;

4097
			if ( ! geometry.__webglVertexBuffer ) {
A
alteredq 已提交
4098 4099 4100 4101 4102 4103

				createParticleBuffers( geometry );
				initParticleBuffers( geometry );

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

4105
			}
4106

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

A
alteredq 已提交
4109 4110 4111 4112
		} else if ( THREE.MarchingCubes !== undefined && object instanceof THREE.MarchingCubes ) {

			addBufferImmediate( scene.__webglObjectsImmediate, object );

4113
		} else if ( object instanceof THREE.Sprite ) {
4114

4115
			scene.__webglSprites.push( object );
4116

4117
		}
4118

4119
		/*else if ( object instanceof THREE.Particle ) {
A
alteredq 已提交
4120 4121 4122 4123 4124

		}*/

	};

4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175
	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;

				}

			}

		}

	};

4176
	function updateObject( object, scene ) {
A
alteredq 已提交
4177

4178
		var g, geometry, geometryGroup, a, customAttributeDirty;
A
alteredq 已提交
4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189

		if ( object instanceof THREE.Mesh ) {

			geometry = object.geometry;

			// check all geometry groups

			for ( g in geometry.geometryGroups ) {

				geometryGroup = geometry.geometryGroups[ g ];

4190
				customAttributeDirty = areCustomAttributesDirty( geometryGroup );
4191

4192
				if ( geometry.__dirtyVertices || geometry.__dirtyMorphTargets || geometry.__dirtyElements ||
4193 4194
					 geometry.__dirtyUvs || geometry.__dirtyNormals ||
					 geometry.__dirtyColors || geometry.__dirtyTangents || customAttributeDirty ) {
A
alteredq 已提交
4195 4196 4197 4198 4199 4200 4201

					setMeshBuffers( geometryGroup, object, _gl.DYNAMIC_DRAW );

				}

			}

4202
			geometry.__dirtyVertices = false;
4203
			geometry.__dirtyMorphTargets = false;
A
alteredq 已提交
4204 4205 4206 4207
			geometry.__dirtyElements = false;
			geometry.__dirtyUvs = false;
			geometry.__dirtyNormals = false;
			geometry.__dirtyTangents = false;
4208
			geometry.__dirtyColors = false;
M
Mr.doob 已提交
4209

4210 4211
			clearCustomAttributes( geometryGroup );

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

4214 4215
			geometry = object.geometry;

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

A
alteredq 已提交
4218
				setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
4219

A
alteredq 已提交
4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231
			}

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

4233
			}
4234

A
alteredq 已提交
4235 4236 4237 4238 4239 4240 4241
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;

		} else if ( object instanceof THREE.ParticleSystem ) {

			geometry = object.geometry;

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

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

4246
			}
M
Mr.doob 已提交
4247

4248 4249
			geometry.__dirtyVertices = false;
			geometry.__dirtyColors = false;
M
Mr.doob 已提交
4250

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

A
alteredq 已提交
4253
			// it updates itself in render callback
4254 4255

		} else if ( object instanceof THREE.Particle ) {
4256 4257

		}*/
4258

4259 4260 4261 4262 4263 4264
		/*
		delete geometry.vertices;
		delete geometry.faces;
		delete geometryGroup.faces;
		*/

4265
	};
4266

4267
	function removeInstances( objlist, object ) {
M
Mr.doob 已提交
4268

4269
		var o, ol;
M
Mr.doob 已提交
4270

4271
		for ( o = objlist.length - 1; o >= 0; o -- ) {
4272

4273
			if ( objlist[ o ].object == object ) {
4274

4275
				objlist.splice( o, 1 );
4276

4277
			}
4278

4279
		}
M
Mr.doob 已提交
4280

4281
	};
4282

4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298
	function removeInstancesDirect( objlist, object ) {

		var o, ol;

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

			if ( objlist[ o ] == object ) {

				objlist.splice( o, 1 );

			}

		}

	};

4299
	function removeObject( object, scene ) {
4300

4301
		// must check as shadow volume before mesh (as they are also meshes)
4302

4303
		if ( object instanceof THREE.ShadowVolume ) {
M
Mr.doob 已提交
4304

4305
			removeInstances( scene.__webglShadowVolumes, object );
M
Mr.doob 已提交
4306

4307 4308 4309
		} else if ( object instanceof THREE.Mesh  ||
			 object instanceof THREE.ParticleSystem ||
			 object instanceof THREE.Ribbon ||
4310
			 object instanceof THREE.Line ) {
4311

4312
			removeInstances( scene.__webglObjects, object );
4313

4314
		} else if ( object instanceof THREE.Sprite ) {
M
Mr.doob 已提交
4315

4316
			removeInstancesDirect( scene.__webglSprites, object );
M
Mr.doob 已提交
4317

4318 4319 4320 4321 4322
		} else if ( object instanceof THREE.LensFlare ) {

			removeInstances( scene.__webglLensFlares, object );

		} else if ( object instanceof THREE.MarchingCubes ) {
4323

4324 4325 4326
			removeInstances( scene.__webglObjectsImmediate, object );

		}
M
Mr.doob 已提交
4327 4328 4329

	};

4330
	function sortFacesByMaterial( geometry ) {
4331 4332 4333 4334 4335 4336 4337

		// 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 = {};
4338
		var numMorphTargets = geometry.morphTargets !== undefined ? geometry.morphTargets.length : 0;
4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380

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

4381
				geometry.geometryGroups[ ghash ] = { 'faces': [], 'materials': materials, 'vertices': 0, 'numMorphTargets': numMorphTargets };
4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393

			}

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

4394
					geometry.geometryGroups[ ghash ] = { 'faces': [], 'materials': materials, 'vertices': 0, 'numMorphTargets': numMorphTargets };
4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406

				}

			}

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

		}

	};

4407
	function addBuffer( objlist, buffer, object ) {
4408

4409 4410 4411 4412 4413
		objlist.push( {
			buffer: buffer, object: object,
			opaque: { list: [], count: 0 },
			transparent: { list: [], count: 0 }
		} );
M
Mr.doob 已提交
4414

4415
	};
4416

4417
	function addBufferImmediate( objlist, object ) {
4418

4419 4420 4421 4422 4423
		objlist.push( {
			object: object,
			opaque: { list: [], count: 0 },
			transparent: { list: [], count: 0 }
		} );
4424

4425
	};
4426

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

4429
		if ( cullFace ) {
M
Mr.doob 已提交
4430

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

4433
				_gl.frontFace( _gl.CCW );
M
Mr.doob 已提交
4434

4435
			} else {
M
Mr.doob 已提交
4436

4437
				_gl.frontFace( _gl.CW );
M
Mr.doob 已提交
4438

4439
			}
M
Mr.doob 已提交
4440

4441
			if( cullFace == "back" ) {
M
Mr.doob 已提交
4442

4443
				_gl.cullFace( _gl.BACK );
M
Mr.doob 已提交
4444

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

4447
				_gl.cullFace( _gl.FRONT );
M
Mr.doob 已提交
4448

4449
			} else {
M
Mr.doob 已提交
4450

4451
				_gl.cullFace( _gl.FRONT_AND_BACK );
M
Mr.doob 已提交
4452

4453
			}
M
Mr.doob 已提交
4454

4455
			_gl.enable( _gl.CULL_FACE );
M
Mr.doob 已提交
4456

4457
		} else {
M
Mr.doob 已提交
4458

4459
			_gl.disable( _gl.CULL_FACE );
M
Mr.doob 已提交
4460

4461 4462 4463
		}

	};
N
Nicolas Garcia Belmonte 已提交
4464

4465
	this.supportsVertexTextures = function () {
4466

A
alteredq 已提交
4467
		return _supportsVertexTextures;
4468

4469
	};
4470

4471
	function maxVertexTextures() {
4472

4473 4474 4475
		return _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );

	};
4476

4477
	function buildProgram( shaderID, fragmentShader, vertexShader, uniforms, attributes, parameters ) {
4478

4479
		var p, pl, program, code;
4480
		var chunks = [];
4481 4482 4483

		// Generate code

4484 4485 4486 4487 4488 4489 4490 4491 4492 4493
		if ( shaderID ) {

			chunks.push( shaderID );

		} else {

			chunks.push( fragmentShader );
			chunks.push( vertexShader );

		}
4494 4495 4496

		for ( p in parameters ) {

4497 4498
			chunks.push( p );
			chunks.push( parameters[ p ] );
4499 4500 4501

		}

4502 4503
		code = chunks.join();

4504 4505 4506 4507 4508 4509 4510
		// 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*/ );
4511

4512 4513 4514 4515 4516
				return _programs[ p ].program;

			}

		}
4517

4518
		//console.log( "building new program " );
4519 4520 4521

		//

4522
		program = _gl.createProgram();
M
Mr.doob 已提交
4523

4524
		var prefix_vertex = [
M
Mr.doob 已提交
4525

A
alteredq 已提交
4526
			_supportsVertexTextures ? "#define VERTEX_TEXTURES" : "",
4527

4528 4529 4530
			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

4531 4532
			"#define MAX_BONES " + parameters.maxBones,

4533
			parameters.map ? "#define USE_MAP" : "",
4534 4535 4536
			parameters.envMap ? "#define USE_ENVMAP" : "",
			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
			parameters.vertexColors ? "#define USE_COLOR" : "",
4537
			parameters.skinning ? "#define USE_SKINNING" : "",
4538
			parameters.morphTargets ? "#define USE_MORPHTARGETS" : "",
4539

4540 4541
			parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",

M
Mr.doob 已提交
4542 4543 4544
			"uniform mat4 objectMatrix;",
			"uniform mat4 modelViewMatrix;",
			"uniform mat4 projectionMatrix;",
4545 4546
			"uniform mat4 viewMatrix;",
			"uniform mat3 normalMatrix;",
M
Mr.doob 已提交
4547
			"uniform vec3 cameraPosition;",
A
alteredq 已提交
4548 4549 4550

			"uniform mat4 cameraInverseMatrix;",

M
Mr.doob 已提交
4551 4552 4553
			"attribute vec3 position;",
			"attribute vec3 normal;",
			"attribute vec2 uv;",
4554
			"attribute vec2 uv2;",
4555

4556
			"#ifdef USE_COLOR",
4557

4558
				"attribute vec3 color;",
4559

4560 4561
			"#endif",

4562
			"#ifdef USE_MORPHTARGETS",
4563

4564 4565 4566 4567 4568 4569 4570 4571
				"attribute vec3 morphTarget0;",
				"attribute vec3 morphTarget1;",
				"attribute vec3 morphTarget2;",
				"attribute vec3 morphTarget3;",
				"attribute vec3 morphTarget4;",
				"attribute vec3 morphTarget5;",
				"attribute vec3 morphTarget6;",
				"attribute vec3 morphTarget7;",
4572

4573 4574 4575
			"#endif",

			"#ifdef USE_SKINNING",
4576

4577 4578 4579 4580
				"attribute vec4 skinVertexA;",
				"attribute vec4 skinVertexB;",
				"attribute vec4 skinIndex;",
				"attribute vec4 skinWeight;",
4581

4582
			"#endif",
4583

M
Mr.doob 已提交
4584
			""
A
alteredq 已提交
4585

M
Mr.doob 已提交
4586
		].join("\n");
4587

M
Mr.doob 已提交
4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610
		var prefix_fragment = [

			"#ifdef GL_ES",
			"precision highp float;",
			"#endif",

			"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
			"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,

			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" : "",

			"uniform mat4 viewMatrix;",
			"uniform vec3 cameraPosition;",
			""

		].join("\n");

4611 4612
		_gl.attachShader( program, getShader( "fragment", prefix_fragment + fragmentShader ) );
		_gl.attachShader( program, getShader( "vertex", prefix_vertex + vertexShader ) );
M
Mr.doob 已提交
4613

M
Mr.doob 已提交
4614
		_gl.linkProgram( program );
N
Nicolas Garcia Belmonte 已提交
4615

M
Mr.doob 已提交
4616
		if ( !_gl.getProgramParameter( program, _gl.LINK_STATUS ) ) {
N
Nicolas Garcia Belmonte 已提交
4617

4618
			console.error( "Could not initialise shader\n" + "VALIDATE_STATUS: " + _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) + ", gl error [" + _gl.getError() + "]" );
M
Mr.doob 已提交
4619

N
Nicolas Garcia Belmonte 已提交
4620
		}
4621

4622 4623
		//console.log( prefix_fragment + fragmentShader );
		//console.log( prefix_vertex + vertexShader );
M
Mr.doob 已提交
4624

M
Mr.doob 已提交
4625
		program.uniforms = {};
4626
		program.attributes = {};
M
Mr.doob 已提交
4627

4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645
		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 );
4646

4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669
		// 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 );

4670 4671
		_programs.push( { program: program, code: code } );

M
Mr.doob 已提交
4672
		return program;
M
Mr.doob 已提交
4673

M
Mr.doob 已提交
4674
	};
M
Mr.doob 已提交
4675

4676
	function loadUniformsSkinning( uniforms, object ) {
4677

M
Mr.doob 已提交
4678
		_gl.uniformMatrix4fv( uniforms.cameraInverseMatrix, false, _viewMatrixArray );
A
alteredq 已提交
4679
		_gl.uniformMatrix4fv( uniforms.boneGlobalMatrices, false, object.boneMatrices );
4680

4681
	};
4682

4683

4684
	function loadUniformsMatrices( uniforms, object ) {
4685

A
alteredq 已提交
4686 4687 4688 4689
		_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray );
		_gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrixArray );

	};
4690

4691
	function loadUniformsGeneric( program, uniforms ) {
M
Mr.doob 已提交
4692

4693
		var u, uniform, value, type, location, texture;
M
Mr.doob 已提交
4694

M
Mr.doob 已提交
4695
		for( u in uniforms ) {
M
Mr.doob 已提交
4696

4697 4698
			location = program.uniforms[u];
			if ( !location ) continue;
M
Mr.doob 已提交
4699

4700
			uniform = uniforms[u];
M
Mr.doob 已提交
4701

4702 4703
			type = uniform.type;
			value = uniform.value;
M
Mr.doob 已提交
4704

M
Mr.doob 已提交
4705
			if( type == "i" ) {
M
Mr.doob 已提交
4706

M
Mr.doob 已提交
4707
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
4708

M
Mr.doob 已提交
4709
			} else if( type == "f" ) {
M
Mr.doob 已提交
4710

M
Mr.doob 已提交
4711
				_gl.uniform1f( location, value );
4712

A
alteredq 已提交
4713 4714 4715
			} else if( type == "fv1" ) {

				_gl.uniform1fv( location, value );
M
Mr.doob 已提交
4716

4717 4718 4719 4720
			} else if( type == "fv" ) {

				_gl.uniform3fv( location, value );

4721 4722 4723 4724
			} else if( type == "v2" ) {

				_gl.uniform2f( location, value.x, value.y );

4725 4726 4727
			} else if( type == "v3" ) {

				_gl.uniform3f( location, value.x, value.y, value.z );
4728

4729 4730 4731 4732
			} else if( type == "v4" ) {

				_gl.uniform4f( location, value.x, value.y, value.z, value.w );

4733 4734 4735
			} else if( type == "c" ) {

				_gl.uniform3f( location, value.r, value.g, value.b );
M
Mr.doob 已提交
4736

M
Mr.doob 已提交
4737
			} else if( type == "t" ) {
M
Mr.doob 已提交
4738

M
Mr.doob 已提交
4739
				_gl.uniform1i( location, value );
M
Mr.doob 已提交
4740

4741
				texture = uniform.texture;
M
Mr.doob 已提交
4742

4743
				if ( !texture ) continue;
M
Mr.doob 已提交
4744

4745
				if ( texture.image instanceof Array && texture.image.length == 6 ) {
M
Mr.doob 已提交
4746

4747
					setCubeTexture( texture, value );
M
Mr.doob 已提交
4748

4749
				} else {
M
Mr.doob 已提交
4750

4751
					setTexture( texture, value );
M
Mr.doob 已提交
4752

4753
				}
M
Mr.doob 已提交
4754

4755
			}
M
Mr.doob 已提交
4756

4757
		}
M
Mr.doob 已提交
4758

4759
	};
M
Mr.doob 已提交
4760

4761
	function setBlending( blending ) {
A
alteredq 已提交
4762 4763

		if ( blending != _oldBlending ) {
4764

A
alteredq 已提交
4765 4766 4767 4768 4769
			switch ( blending ) {

				case THREE.AdditiveBlending:

					_gl.blendEquation( _gl.FUNC_ADD );
4770
					_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE );
A
alteredq 已提交
4771 4772 4773 4774 4775

					break;

				case THREE.SubtractiveBlending:

4776 4777 4778 4779
					// TODO: Find blendFuncSeparate() combination

					_gl.blendEquation( _gl.FUNC_ADD );
					_gl.blendFunc( _gl.ZERO, _gl.ONE_MINUS_SRC_COLOR );
A
alteredq 已提交
4780 4781 4782

					break;

4783 4784 4785
				case THREE.MultiplyBlending:

					// TODO: Find blendFuncSeparate() combination
A
alteredq 已提交
4786 4787

					_gl.blendEquation( _gl.FUNC_ADD );
4788
					_gl.blendFunc( _gl.ZERO, _gl.SRC_COLOR );
A
alteredq 已提交
4789 4790 4791 4792 4793

					break;

				default:

4794 4795
					_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 已提交
4796 4797

					break;
4798

A
alteredq 已提交
4799
			}
4800

A
alteredq 已提交
4801
			_oldBlending = blending;
4802

A
alteredq 已提交
4803 4804 4805
		}

	};
4806

4807
	function setTextureParameters( textureType, texture, image ) {
4808

4809
		if ( isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ) ) {
M
Mr.doob 已提交
4810

4811 4812
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
M
Mr.doob 已提交
4813

4814 4815
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
M
Mr.doob 已提交
4816

4817
			_gl.generateMipmap( textureType );
M
Mr.doob 已提交
4818

4819
		} else {
M
Mr.doob 已提交
4820

4821 4822
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
4823

4824 4825
			_gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
			_gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
M
Mr.doob 已提交
4826

4827
		}
M
Mr.doob 已提交
4828

4829
	};
4830

4831
	function setTexture( texture, slot ) {
4832

4833
		if ( texture.needsUpdate ) {
A
alteredq 已提交
4834

4835
			if ( !texture.__webglInit ) {
M
Mr.doob 已提交
4836

4837
				texture.__webglTexture = _gl.createTexture();
A
alteredq 已提交
4838

4839
				_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
M
Mr.doob 已提交
4840
				// _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, true );
4841
				_gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image );
M
Mr.doob 已提交
4842

4843
				texture.__webglInit = true;
M
Mr.doob 已提交
4844

A
alteredq 已提交
4845
			} else {
M
Mr.doob 已提交
4846

4847
				_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
M
Mr.doob 已提交
4848 4849 4850
				// _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 已提交
4851 4852 4853

			}

4854
			setTextureParameters( _gl.TEXTURE_2D, texture, texture.image );
M
Mr.doob 已提交
4855

4856
			_gl.bindTexture( _gl.TEXTURE_2D, null );
4857

A
alteredq 已提交
4858
			texture.needsUpdate = false;
4859 4860 4861

		}

4862
		/*
4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882
		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;

		}
4883
		*/
M
Mr.doob 已提交
4884

4885
		_gl.activeTexture( _gl.TEXTURE0 + slot );
4886
		_gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
M
Mr.doob 已提交
4887

4888

4889
	};
M
Mr.doob 已提交
4890

4891
	function setCubeTexture( texture, slot ) {
4892 4893 4894 4895 4896

		if ( texture.image.length == 6 ) {

			if ( texture.needsUpdate ) {

4897 4898 4899
				if ( !texture.__webglInit ) {

					texture.image.__webglTextureCube = _gl.createTexture();
4900

4901
					_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
4902

4903
					for ( var i = 0; i < 6; ++i ) {
4904

4905
						_gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image[ i ] );
4906

4907
					}
4908 4909

					texture.__webglInit = true;
4910 4911 4912

				} else {

4913
					_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
4914

4915
					for ( var i = 0; i < 6; ++i ) {
4916

M
Mr.doob 已提交
4917
						// _gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image[ i ] );
4918
						_gl.texSubImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image[ i ] );
4919

4920
					}
4921 4922 4923

				}

4924
				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, texture.image[0] );
4925 4926 4927
				_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );

				texture.needsUpdate = false;
4928

4929 4930 4931
			}

			_gl.activeTexture( _gl.TEXTURE0 + slot );
4932
			_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
4933 4934 4935 4936 4937

		}

	};

4938
	function setRenderTarget( renderTexture ) {
4939

4940
		if ( renderTexture && !renderTexture.__webglFramebuffer ) {
M
Mr.doob 已提交
4941

M
Mikael Emtinger 已提交
4942 4943 4944
			if( renderTexture.depthBuffer === undefined ) renderTexture.depthBuffer = true;
			if( renderTexture.stencilBuffer === undefined ) renderTexture.stencilBuffer = true;

4945 4946 4947
			renderTexture.__webglFramebuffer = _gl.createFramebuffer();
			renderTexture.__webglRenderbuffer = _gl.createRenderbuffer();
			renderTexture.__webglTexture = _gl.createTexture();
4948 4949 4950


			// Setup texture
M
Mr.doob 已提交
4951

4952
			_gl.bindTexture( _gl.TEXTURE_2D, renderTexture.__webglTexture );
4953 4954 4955 4956
			_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 ) );
4957
			_gl.texImage2D( _gl.TEXTURE_2D, 0, paramThreeToGL( renderTexture.format ), renderTexture.width, renderTexture.height, 0, paramThreeToGL( renderTexture.format ), paramThreeToGL( renderTexture.type ), null );
4958

M
Mikael Emtinger 已提交
4959
			// Setup render and frame buffer
M
Mr.doob 已提交
4960

M
Mikael Emtinger 已提交
4961
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderTexture.__webglRenderbuffer );
4962
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTexture.__webglFramebuffer );
M
Mikael Emtinger 已提交
4963

4964
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, renderTexture.__webglTexture, 0 );
4965 4966 4967

			if ( renderTexture.depthBuffer && !renderTexture.stencilBuffer ) {

M
Mikael Emtinger 已提交
4968 4969
				_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTexture.width, renderTexture.height );
				_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderTexture.__webglRenderbuffer );
4970

M
Mr.doob 已提交
4971
			/* For some reason this is not working. Defaulting to RGBA4.
M
Mikael Emtinger 已提交
4972
			} else if( !renderTexture.depthBuffer && renderTexture.stencilBuffer ) {
4973

M
Mikael Emtinger 已提交
4974 4975 4976 4977
				_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 ) {
4978

M
Mikael Emtinger 已提交
4979 4980
				_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTexture.width, renderTexture.height );
				_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderTexture.__webglRenderbuffer );
4981

M
Mikael Emtinger 已提交
4982
			} else {
4983

M
Mikael Emtinger 已提交
4984
				_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTexture.width, renderTexture.height );
4985

M
Mikael Emtinger 已提交
4986
			}
4987

4988 4989

			// Release everything
M
Mr.doob 已提交
4990

4991 4992 4993
			_gl.bindTexture( _gl.TEXTURE_2D, null );
			_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
M
Mr.doob 已提交
4994

4995 4996
		}

4997
		var framebuffer, width, height;
M
Mr.doob 已提交
4998

4999
		if ( renderTexture ) {
M
Mr.doob 已提交
5000

5001
			framebuffer = renderTexture.__webglFramebuffer;
5002 5003
			width = renderTexture.width;
			height = renderTexture.height;
M
Mr.doob 已提交
5004

5005
		} else {
M
Mr.doob 已提交
5006

5007
			framebuffer = null;
5008 5009
			width = _viewportWidth;
			height = _viewportHeight;
M
Mr.doob 已提交
5010

5011
		}
M
Mr.doob 已提交
5012

5013
		if ( framebuffer != _currentFramebuffer ) {
M
Mr.doob 已提交
5014

5015
			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
5016
			_gl.viewport( _viewportX, _viewportY, width, height );
M
Mr.doob 已提交
5017

5018
			_currentFramebuffer = framebuffer;
M
Mr.doob 已提交
5019

5020
		}
5021

5022
	};
M
Mr.doob 已提交
5023

5024
	function updateRenderTargetMipmap( renderTarget ) {
M
Mr.doob 已提交
5025

5026
		_gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
5027 5028
		_gl.generateMipmap( _gl.TEXTURE_2D );
		_gl.bindTexture( _gl.TEXTURE_2D, null );
M
Mr.doob 已提交
5029 5030

	};
5031

5032
	function cacheUniformLocations( program, identifiers ) {
M
Mr.doob 已提交
5033

M
Mr.doob 已提交
5034
		var i, l, id;
M
Mr.doob 已提交
5035

M
Mr.doob 已提交
5036
		for( i = 0, l = identifiers.length; i < l; i++ ) {
M
Mr.doob 已提交
5037

5038 5039
			id = identifiers[ i ];
			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
M
Mr.doob 已提交
5040

M
Mr.doob 已提交
5041
		}
M
Mr.doob 已提交
5042

M
Mr.doob 已提交
5043
	};
M
Mr.doob 已提交
5044

5045
	function cacheAttributeLocations( program, identifiers ) {
5046

5047
		var i, l, id;
M
Mr.doob 已提交
5048

5049
		for( i = 0, l = identifiers.length; i < l; i++ ) {
M
Mr.doob 已提交
5050

5051 5052
			id = identifiers[ i ];
			program.attributes[ id ] = _gl.getAttribLocation( program, id );
M
Mr.doob 已提交
5053

5054
		}
M
Mr.doob 已提交
5055

M
Mr.doob 已提交
5056
	};
M
Mr.doob 已提交
5057

5058
	function getShader( type, string ) {
N
Nicolas Garcia Belmonte 已提交
5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076

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

5077
			console.error( _gl.getShaderInfoLog( shader ) );
5078
			console.error( string );
N
Nicolas Garcia Belmonte 已提交
5079 5080 5081 5082 5083
			return null;

		}

		return shader;
M
Mr.doob 已提交
5084

5085
	};
N
Nicolas Garcia Belmonte 已提交
5086

5087
	// fallback filters for non-power-of-2 textures
5088

5089
	function filterFallback( f ) {
5090

5091 5092 5093 5094 5095 5096 5097 5098
		switch ( f ) {

			case THREE.NearestFilter:
			case THREE.NearestMipMapNearestFilter:
			case THREE.NearestMipMapLinearFilter: return _gl.NEAREST; break;

			case THREE.LinearFilter:
			case THREE.LinearMipMapNearestFilter:
M
Mr.doob 已提交
5099
			case THREE.LinearMipMapLinearFilter:
M
Mikael Emtinger 已提交
5100
			default:
5101

M
Mikael Emtinger 已提交
5102
				return _gl.LINEAR; break;
5103 5104

		}
5105

5106
	};
5107 5108

	function paramThreeToGL( p ) {
M
Mr.doob 已提交
5109

5110
		switch ( p ) {
M
Mr.doob 已提交
5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123

			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;

5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137
			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;

5138
		}
M
Mr.doob 已提交
5139

5140
		return 0;
M
Mr.doob 已提交
5141

5142 5143
	};

5144
	function isPowerOfTwo( value ) {
5145 5146 5147 5148 5149

		return ( value & ( value - 1 ) ) == 0;

	};

5150
	function materialNeedsSmoothNormals( material ) {
5151 5152 5153

		return material && material.shading != undefined && material.shading == THREE.SmoothShading;

5154
	};
M
Mr.doob 已提交
5155

5156
	function bufferNeedsSmoothNormals( geometryGroup, object ) {
M
Mr.doob 已提交
5157

5158
		var m, ml, i, l, meshMaterial, needsSmoothNormals = false;
M
Mr.doob 已提交
5159

M
Mr.doob 已提交
5160
		for ( m = 0, ml = object.materials.length; m < ml; m++ ) {
5161

M
Mr.doob 已提交
5162
			meshMaterial = object.materials[ m ];
5163 5164 5165

			if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {

5166
				for ( i = 0, l = geometryGroup.materials.length; i < l; i++ ) {
5167

5168
					if ( materialNeedsSmoothNormals( geometryGroup.materials[ i ] ) ) {
5169

5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190
						needsSmoothNormals = true;
						break;

					}

				}

			} else {

				if ( materialNeedsSmoothNormals( meshMaterial ) ) {

					needsSmoothNormals = true;
					break;

				}

			}

			if ( needsSmoothNormals ) break;

		}
M
Mr.doob 已提交
5191

5192
		return needsSmoothNormals;
M
Mr.doob 已提交
5193

5194
	};
M
Mr.doob 已提交
5195

5196
	function unrollGroupMaterials( geometryGroup, object ) {
5197

5198 5199 5200
		var m, ml, i, il,
			material, meshMaterial,
			materials = [];
5201

5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212
		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 ) {
5213

5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232
						materials.push( material );

					}

				}

			} else {

				material = meshMaterial;

				if ( material ) {

					materials.push( material );

				}

			}

		}
5233

5234 5235 5236
		return materials;

	};
5237

5238
	function bufferGuessVertexColorType( materials, geometryGroup, object ) {
5239

5240
		var i, m, ml = materials.length;
5241

5242
		// use vertexColor type from the first material in unrolled materials
5243

5244
		for ( i = 0; i < ml; i++ ) {
5245

5246
			m = materials[ i ];
5247

5248
			if ( m.vertexColors ) {
5249

5250 5251 5252
				return m.vertexColors;

			}
5253

5254
		}
5255

5256
		return false;
5257

5258 5259
	};

5260
	function bufferGuessNormalType( materials, geometryGroup, object ) {
5261

5262
		var i, m, ml = materials.length;
5263

5264
		// only MeshBasicMaterial and MeshDepthMaterial don't need normals
5265

5266
		for ( i = 0; i < ml; i++ ) {
5267

5268
			m = materials[ i ];
5269

A
alteredq 已提交
5270
			if ( ( m instanceof THREE.MeshBasicMaterial && !m.envMap ) || m instanceof THREE.MeshDepthMaterial ) continue;
5271

5272
			if ( materialNeedsSmoothNormals( m ) ) {
5273

5274 5275 5276 5277 5278 5279 5280 5281 5282
				return THREE.SmoothShading;

			} else {

				return THREE.FlatShading;

			}

		}
5283

5284
		return false;
5285

5286 5287
	};

5288
	function bufferGuessUVType( materials, geometryGroup, object ) {
5289

5290
		var i, m, ml = materials.length;
5291

5292
		// material must use some texture to require uvs
5293

5294
		for ( i = 0; i < ml; i++ ) {
5295

5296
			m = materials[ i ];
5297

A
alteredq 已提交
5298
			if ( m.map || m.lightMap || m instanceof THREE.MeshShaderMaterial ) {
5299

5300
				return true;
5301

5302
			}
5303

5304
		}
5305

5306
		return false;
5307

5308
	};
5309

5310
	function allocateBones( object ) {
5311

5312 5313 5314 5315 5316 5317 5318
		// 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)
5319

5320
		var maxBones = 50;
5321

5322
		if ( object !== undefined && object instanceof THREE.SkinnedMesh ) {
5323

5324 5325 5326 5327 5328
			maxBones = object.bones.length;

		}

		return maxBones;
5329

5330
	};
5331

5332
	function allocateLights( lights, maxLights ) {
5333

5334 5335
		var l, ll, light, dirLights, pointLights, maxDirLights, maxPointLights;
		dirLights = pointLights = maxDirLights = maxPointLights = 0;
5336

5337
		for ( l = 0, ll = lights.length; l < ll; l++ ) {
5338

5339
			light = lights[ l ];
5340

5341 5342
			if ( light instanceof THREE.DirectionalLight ) dirLights++;
			if ( light instanceof THREE.PointLight ) pointLights++;
5343

5344
		}
5345

5346
		if ( ( pointLights + dirLights ) <= maxLights ) {
5347

5348 5349
			maxDirLights = dirLights;
			maxPointLights = pointLights;
5350

5351
		} else {
5352

5353 5354
			maxDirLights = Math.ceil( maxLights * dirLights / ( pointLights + dirLights ) );
			maxPointLights = maxLights - maxDirLights;
5355 5356 5357

		}

5358
		return { 'directional' : maxDirLights, 'point' : maxPointLights };
5359 5360

	};
M
Mr.doob 已提交
5361

A
alteredq 已提交
5362
	/* DEBUG
5363
	function getGLParams() {
M
Mr.doob 已提交
5364

5365
		var params  = {
M
Mr.doob 已提交
5366

5367 5368
			'MAX_VARYING_VECTORS': _gl.getParameter( _gl.MAX_VARYING_VECTORS ),
			'MAX_VERTEX_ATTRIBS': _gl.getParameter( _gl.MAX_VERTEX_ATTRIBS ),
M
Mr.doob 已提交
5369

5370 5371 5372
			'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 已提交
5373

5374 5375 5376
			'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 已提交
5377

5378 5379
		return params;
	};
M
Mr.doob 已提交
5380

5381
	function dumpObject( obj ) {
M
Mr.doob 已提交
5382

5383 5384
		var p, str = "";
		for ( p in obj ) {
M
Mr.doob 已提交
5385

5386
			str += p + ": " + obj[p] + "\n";
M
Mr.doob 已提交
5387

5388
		}
M
Mr.doob 已提交
5389

5390 5391
		return str;
	}
A
alteredq 已提交
5392
	*/
5393
};
5394