WebGLRenderer.js 57.5 KB
Newer Older
M
Mugen87 已提交
1
import { REVISION, RGBAFormat, HalfFloatType, FloatType, UnsignedByteType, FrontFaceDirectionCW, TriangleFanDrawMode, TriangleStripDrawMode, TrianglesDrawMode, NoColors, LinearToneMapping } from '../constants.js';
B
bentok 已提交
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
import { _Math } from '../math/Math.js';
import { Matrix4 } from '../math/Matrix4.js';
import { DataTexture } from '../textures/DataTexture.js';
import { WebGLUniforms } from './webgl/WebGLUniforms.js';
import { UniformsLib } from './shaders/UniformsLib.js';
import { UniformsUtils } from './shaders/UniformsUtils.js';
import { ShaderLib } from './shaders/ShaderLib.js';
import { WebGLFlareRenderer } from './webgl/WebGLFlareRenderer.js';
import { WebGLSpriteRenderer } from './webgl/WebGLSpriteRenderer.js';
import { WebGLShadowMap } from './webgl/WebGLShadowMap.js';
import { WebGLAttributes } from './webgl/WebGLAttributes.js';
import { WebGLBackground } from './webgl/WebGLBackground.js';
import { WebGLRenderLists } from './webgl/WebGLRenderLists.js';
import { WebGLMorphtargets } from './webgl/WebGLMorphtargets.js';
import { WebGLIndexedBufferRenderer } from './webgl/WebGLIndexedBufferRenderer.js';
import { WebGLBufferRenderer } from './webgl/WebGLBufferRenderer.js';
import { WebGLGeometries } from './webgl/WebGLGeometries.js';
import { WebGLLights } from './webgl/WebGLLights.js';
import { WebGLObjects } from './webgl/WebGLObjects.js';
import { WebGLPrograms } from './webgl/WebGLPrograms.js';
import { WebGLTextures } from './webgl/WebGLTextures.js';
import { WebGLProperties } from './webgl/WebGLProperties.js';
import { WebGLState } from './webgl/WebGLState.js';
import { WebGLCapabilities } from './webgl/WebGLCapabilities.js';
import { WebVRManager } from './webvr/WebVRManager.js';
import { WebGLExtensions } from './webgl/WebGLExtensions.js';
import { Vector3 } from '../math/Vector3.js';
import { WebGLClipping } from './webgl/WebGLClipping.js';
import { Frustum } from '../math/Frustum.js';
import { Vector4 } from '../math/Vector4.js';
import { WebGLUtils } from './webgl/WebGLUtils.js';
R
Rich Harris 已提交
33

M
Mr.doob 已提交
34 35 36 37 38
/**
 * @author supereggbert / http://www.paulbrunt.co.uk/
 * @author mrdoob / http://mrdoob.com/
 * @author alteredq / http://alteredqualia.com/
 * @author szimek / https://github.com/szimek/
T
tschw 已提交
39
 * @author tschw
M
Mr.doob 已提交
40 41
 */

M
Mr.doob 已提交
42
function WebGLRenderer( parameters ) {
M
Mr.doob 已提交
43

M
Mr.doob 已提交
44
	console.log( 'THREE.WebGLRenderer', REVISION );
M
Mr.doob 已提交
45 46 47

	parameters = parameters || {};

E
Eli Grey 已提交
48
	var _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ),
49
		_context = parameters.context !== undefined ? parameters.context : null,
M
Mr.doob 已提交
50

51 52 53 54 55
		_alpha = parameters.alpha !== undefined ? parameters.alpha : false,
		_depth = parameters.depth !== undefined ? parameters.depth : true,
		_stencil = parameters.stencil !== undefined ? parameters.stencil : true,
		_antialias = parameters.antialias !== undefined ? parameters.antialias : false,
		_premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,
56 57
		_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false,
		_powerPreference = parameters.powerPreference !== undefined ? parameters.powerPreference : 'default';
M
Mr.doob 已提交
58

59 60
	var lightsArray = [];
	var shadowsArray = [];
M
Mr.doob 已提交
61

62
	var currentRenderList = null;
63

64 65
	var spritesArray = [];
	var flaresArray = [];
M
Mr.doob 已提交
66

M
Mr.doob 已提交
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
	// public properties

	this.domElement = _canvas;
	this.context = null;

	// clearing

	this.autoClear = true;
	this.autoClearColor = true;
	this.autoClearDepth = true;
	this.autoClearStencil = true;

	// scene graph

	this.sortObjects = true;

T
tschw 已提交
83 84 85 86 87
	// user-defined clipping

	this.clippingPlanes = [];
	this.localClippingEnabled = false;

M
Mr.doob 已提交
88 89
	// physically based shading

90
	this.gammaFactor = 2.0;	// for backwards compatibility
M
Mr.doob 已提交
91 92 93
	this.gammaInput = false;
	this.gammaOutput = false;

94 95
	// physical lights

96
	this.physicallyCorrectLights = false;
97

B
Ben Houston 已提交
98 99
	// tone mapping

R
Rich Harris 已提交
100
	this.toneMapping = LinearToneMapping;
B
Ben Houston 已提交
101 102 103
	this.toneMappingExposure = 1.0;
	this.toneMappingWhitePoint = 1.0;

M
Mr.doob 已提交
104 105 106 107 108 109 110 111 112
	// morphs

	this.maxMorphTargets = 8;
	this.maxMorphNormals = 4;

	// internal properties

	var _this = this,

113 114
		_isContextLost = false,

115
		// internal state cache
M
Mr.doob 已提交
116

117 118 119 120
		_currentRenderTarget = null,
		_currentFramebuffer = null,
		_currentMaterialId = - 1,
		_currentGeometryProgram = '',
121

122
		_currentCamera = null,
123
		_currentArrayCamera = null,
M
Mr.doob 已提交
124

M
Mr.doob 已提交
125
		_currentViewport = new Vector4(),
126 127
		_currentScissor = new Vector4(),
		_currentScissorTest = null,
128

129
		//
130

131
		_usedTextureUnits = 0,
M
Mr.doob 已提交
132

133
		//
M
Mr.doob 已提交
134

135 136
		_width = _canvas.width,
		_height = _canvas.height,
M
Mr.doob 已提交
137

138
		_pixelRatio = 1,
M
Mr.doob 已提交
139

M
Mr.doob 已提交
140
		_viewport = new Vector4( 0, 0, _width, _height ),
141 142
		_scissor = new Vector4( 0, 0, _width, _height ),
		_scissorTest = false,
143

144
		// frustum
M
Mr.doob 已提交
145

146
		_frustum = new Frustum(),
M
Mr.doob 已提交
147

148
		// clipping
T
tschw 已提交
149

150 151 152
		_clipping = new WebGLClipping(),
		_clippingEnabled = false,
		_localClippingEnabled = false,
T
tschw 已提交
153

154
		// camera matrices cache
M
Mr.doob 已提交
155

156
		_projScreenMatrix = new Matrix4(),
M
Mr.doob 已提交
157

A
aardgoose 已提交
158
		_vector3 = new Vector3(),
159

160
		// info
M
Mr.doob 已提交
161

M
Mr.doob 已提交
162 163 164 165 166
		_infoMemory = {
			geometries: 0,
			textures: 0
		},

167
		_infoRender = {
168

169
			frame: 0,
170 171 172 173
			calls: 0,
			vertices: 0,
			faces: 0,
			points: 0
174

175
		};
M
Mr.doob 已提交
176

M
Mr.doob 已提交
177
	this.info = {
178

M
Mr.doob 已提交
179
		render: _infoRender,
M
Mr.doob 已提交
180
		memory: _infoMemory,
181
		programs: null
M
Mr.doob 已提交
182 183

	};
184

185 186 187 188 189
	function getTargetPixelRatio() {

		return _currentRenderTarget === null ? _pixelRatio : 1;

	}
190

M
Mr.doob 已提交
191 192 193 194
	// initialize

	var _gl;

M
Mr.doob 已提交
195 196
	try {

197
		var contextAttributes = {
M
Mr.doob 已提交
198 199 200 201 202
			alpha: _alpha,
			depth: _depth,
			stencil: _stencil,
			antialias: _antialias,
			premultipliedAlpha: _premultipliedAlpha,
203
			preserveDrawingBuffer: _preserveDrawingBuffer,
L
Luigi De Rosa 已提交
204
			powerPreference: _powerPreference
M
Mr.doob 已提交
205 206
		};

207 208
		// event listeners must be registered before WebGL context is created, see #12753

209
		_canvas.addEventListener( 'webglcontextlost', onContextLost, false );
210
		_canvas.addEventListener( 'webglcontextrestored', onContextRestore, false );
211

212
		_gl = _context || _canvas.getContext( 'webgl', contextAttributes ) || _canvas.getContext( 'experimental-webgl', contextAttributes );
M
Mr.doob 已提交
213 214 215

		if ( _gl === null ) {

G
gero3 已提交
216
			if ( _canvas.getContext( 'webgl' ) !== null ) {
217

D
Daniel Hritzkiv 已提交
218
				throw new Error( 'Error creating WebGL context with your selected attributes.' );
219 220 221

			} else {

D
Daniel Hritzkiv 已提交
222
				throw new Error( 'Error creating WebGL context.' );
223 224

			}
M
Mr.doob 已提交
225 226 227

		}

228 229 230 231 232 233 234 235 236 237 238 239
		// Some experimental-webgl implementations do not have getShaderPrecisionFormat

		if ( _gl.getShaderPrecisionFormat === undefined ) {

			_gl.getShaderPrecisionFormat = function () {

				return { 'rangeMin': 1, 'rangeMax': 1, 'precision': 1 };

			};

		}

M
Mr.doob 已提交
240 241
	} catch ( error ) {

D
Daniel Hritzkiv 已提交
242
		console.error( 'THREE.WebGLRenderer: ' + error.message );
M
Mr.doob 已提交
243 244 245

	}

246
	var extensions, capabilities, state;
247 248
	var properties, textures, attributes, geometries, objects, lights;
	var programCache, renderLists;
249

250
	var background, morphtargets, bufferRenderer, indexedBufferRenderer;
251
	var flareRenderer, spriteRenderer;
252

253
	var utils;
254

255
	function initGLContext() {
256

257 258 259 260 261 262 263
		extensions = new WebGLExtensions( _gl );
		extensions.get( 'WEBGL_depth_texture' );
		extensions.get( 'OES_texture_float' );
		extensions.get( 'OES_texture_float_linear' );
		extensions.get( 'OES_texture_half_float' );
		extensions.get( 'OES_texture_half_float_linear' );
		extensions.get( 'OES_standard_derivatives' );
M
Mugen87 已提交
264
		extensions.get( 'OES_element_index_uint' );
265
		extensions.get( 'ANGLE_instanced_arrays' );
266

267
		utils = new WebGLUtils( _gl, extensions );
M
Mr.doob 已提交
268

269
		capabilities = new WebGLCapabilities( _gl, extensions, parameters );
M
Mr.doob 已提交
270

271
		state = new WebGLState( _gl, extensions, utils );
272 273
		state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );
		state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );
M
Mr.doob 已提交
274

275
		properties = new WebGLProperties();
276
		textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, utils, _infoMemory );
277 278
		attributes = new WebGLAttributes( _gl );
		geometries = new WebGLGeometries( _gl, attributes, _infoMemory );
M
Mr.doob 已提交
279
		objects = new WebGLObjects( geometries, _infoRender );
280
		morphtargets = new WebGLMorphtargets( _gl );
281
		programCache = new WebGLPrograms( _this, extensions, capabilities );
282
		lights = new WebGLLights();
283
		renderLists = new WebGLRenderLists();
M
Mr.doob 已提交
284

M
Mr.doob 已提交
285
		background = new WebGLBackground( _this, state, geometries, _premultipliedAlpha );
286

287 288
		bufferRenderer = new WebGLBufferRenderer( _gl, extensions, _infoRender );
		indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );
289

290 291
		flareRenderer = new WebGLFlareRenderer( _this, _gl, state, textures, capabilities );
		spriteRenderer = new WebGLSpriteRenderer( _this, _gl, state, textures, capabilities );
292

293
		_this.info.programs = programCache.programs;
294

295 296 297 298 299 300
		_this.context = _gl;
		_this.capabilities = capabilities;
		_this.extensions = extensions;
		_this.properties = properties;
		_this.renderLists = renderLists;
		_this.state = state;
M
Mr.doob 已提交
301

302
	}
M
Mr.doob 已提交
303

304
	initGLContext();
M
Mr.doob 已提交
305

306
	// vr
M
Mr.doob 已提交
307

308
	var vr = new WebVRManager( _this );
M
Mr.doob 已提交
309

310
	this.vr = vr;
M
Mr.doob 已提交
311 312

	// shadow map
M
Mr.doob 已提交
313

314
	var shadowMap = new WebGLShadowMap( _this, objects, capabilities.maxTextureSize );
M
Mr.doob 已提交
315

316
	this.shadowMap = shadowMap;
M
Mr.doob 已提交
317

M
Mr.doob 已提交
318 319 320 321 322 323 324 325
	// API

	this.getContext = function () {

		return _gl;

	};

326 327 328 329 330 331
	this.getContextAttributes = function () {

		return _gl.getContextAttributes();

	};

332 333
	this.forceContextLoss = function () {

M
Michael Bond 已提交
334 335
		var extension = extensions.get( 'WEBGL_lose_context' );
		if ( extension ) extension.loseContext();
336 337 338

	};

339
	this.forceContextRestore = function () {
M
Mr.doob 已提交
340

341 342
		var extension = extensions.get( 'WEBGL_lose_context' );
		if ( extension ) extension.restoreContext();
M
Mr.doob 已提交
343 344 345

	};

346 347
	this.getPixelRatio = function () {

348
		return _pixelRatio;
349 350 351 352 353

	};

	this.setPixelRatio = function ( value ) {

354 355 356 357
		if ( value === undefined ) return;

		_pixelRatio = value;

M
Mr.doob 已提交
358
		this.setSize( _width, _height, false );
359 360 361

	};

362 363 364
	this.getSize = function () {

		return {
365 366
			width: _width,
			height: _height
367 368 369 370
		};

	};

371
	this.setSize = function ( width, height, updateStyle ) {
M
Mr.doob 已提交
372

373 374 375 376 377 378 379 380 381
		var device = vr.getDevice();

		if ( device && device.isPresenting ) {

			console.warn( 'THREE.WebGLRenderer: Can\'t change size while VR device is presenting.' );
			return;

		}

382 383 384
		_width = width;
		_height = height;

385 386
		_canvas.width = width * _pixelRatio;
		_canvas.height = height * _pixelRatio;
387

388
		if ( updateStyle !== false ) {
389

G
gero3 已提交
390 391
			_canvas.style.width = width + 'px';
			_canvas.style.height = height + 'px';
392

G
gero3 已提交
393
		}
M
Mr.doob 已提交
394

395
		this.setViewport( 0, 0, width, height );
M
Mr.doob 已提交
396 397 398

	};

M
Mr.doob 已提交
399 400 401 402 403 404 405 406 407
	this.getDrawingBufferSize = function () {

		return {
			width: _width * _pixelRatio,
			height: _height * _pixelRatio
		};

	};

408 409 410 411 412 413 414 415 416 417 418 419 420 421
	this.setDrawingBufferSize = function ( width, height, pixelRatio ) {

		_width = width;
		_height = height;

		_pixelRatio = pixelRatio;

		_canvas.width = width * pixelRatio;
		_canvas.height = height * pixelRatio;

		this.setViewport( 0, 0, width, height );

	};

M
Mr.doob 已提交
422 423
	this.setViewport = function ( x, y, width, height ) {

M
Mugen87 已提交
424
		_viewport.set( x, _height - y - height, width, height );
425
		state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );
426

M
Mr.doob 已提交
427 428
	};

429
	this.setScissor = function ( x, y, width, height ) {
M
Mr.doob 已提交
430

M
Mugen87 已提交
431
		_scissor.set( x, _height - y - height, width, height );
432
		state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );
433

M
Mr.doob 已提交
434 435
	};

436 437
	this.setScissorTest = function ( boolean ) {

438
		state.setScissorTest( _scissorTest = boolean );
M
Mr.doob 已提交
439 440 441 442 443

	};

	// Clearing

M
Mr.doob 已提交
444
	this.getClearColor = function () {
M
Mr.doob 已提交
445

446
		return background.getClearColor();
M
Mr.doob 已提交
447 448 449

	};

450
	this.setClearColor = function () {
451

452
		background.setClearColor.apply( background, arguments );
M
Mr.doob 已提交
453 454 455

	};

M
Mr.doob 已提交
456
	this.getClearAlpha = function () {
M
Mr.doob 已提交
457

458
		return background.getClearAlpha();
M
Mr.doob 已提交
459 460 461

	};

M
Mugen87 已提交
462
	this.setClearAlpha = function () {
M
Mr.doob 已提交
463

464
		background.setClearAlpha.apply( background, arguments );
M
Mr.doob 已提交
465 466 467 468 469 470 471 472 473 474 475 476

	};

	this.clear = function ( color, depth, stencil ) {

		var bits = 0;

		if ( color === undefined || color ) bits |= _gl.COLOR_BUFFER_BIT;
		if ( depth === undefined || depth ) bits |= _gl.DEPTH_BUFFER_BIT;
		if ( stencil === undefined || stencil ) bits |= _gl.STENCIL_BUFFER_BIT;

		_gl.clear( bits );
477 478 479 480 481

	};

	this.clearColor = function () {

M
Mr.doob 已提交
482
		this.clear( true, false, false );
483 484 485 486 487

	};

	this.clearDepth = function () {

M
Mr.doob 已提交
488
		this.clear( false, true, false );
489 490 491 492 493

	};

	this.clearStencil = function () {

M
Mr.doob 已提交
494
		this.clear( false, false, true );
M
Mr.doob 已提交
495 496 497 498 499 500 501 502 503 504

	};

	this.clearTarget = function ( renderTarget, color, depth, stencil ) {

		this.setRenderTarget( renderTarget );
		this.clear( color, depth, stencil );

	};

M
Mr.doob 已提交
505
	//
M
Mr.doob 已提交
506

M
Mr.doob 已提交
507
	this.dispose = function () {
D
dubejf 已提交
508 509

		_canvas.removeEventListener( 'webglcontextlost', onContextLost, false );
510
		_canvas.removeEventListener( 'webglcontextrestored', onContextRestore, false );
D
dubejf 已提交
511

512 513
		renderLists.dispose();

514
		vr.dispose();
515

D
dubejf 已提交
516 517
	};

M
Mr.doob 已提交
518
	// Events
M
Mr.doob 已提交
519

D
dubejf 已提交
520 521 522 523
	function onContextLost( event ) {

		event.preventDefault();

524
		console.log( 'THREE.WebGLRenderer: Context Lost.' );
D
dubejf 已提交
525

526 527 528 529
		_isContextLost = true;

	}

M
Mugen87 已提交
530
	function onContextRestore( /* event */ ) {
D
dubejf 已提交
531

532
		console.log( 'THREE.WebGLRenderer: Context Restored.' );
533 534

		_isContextLost = false;
D
dubejf 已提交
535

536
		initGLContext();
D
dubejf 已提交
537

M
Mr.doob 已提交
538
	}
D
dubejf 已提交
539

540
	function onMaterialDispose( event ) {
M
Mr.doob 已提交
541 542 543 544 545 546 547

		var material = event.target;

		material.removeEventListener( 'dispose', onMaterialDispose );

		deallocateMaterial( material );

548
	}
M
Mr.doob 已提交
549 550 551

	// Buffer deallocation

552
	function deallocateMaterial( material ) {
M
Mr.doob 已提交
553

554 555
		releaseMaterialProgramReference( material );

556
		properties.remove( material );
557

558
	}
559 560


561
	function releaseMaterialProgramReference( material ) {
562

563
		var programInfo = properties.get( material ).program;
M
Mr.doob 已提交
564 565 566

		material.program = undefined;

567
		if ( programInfo !== undefined ) {
M
Mr.doob 已提交
568

569
			programCache.releaseProgram( programInfo );
M
Mr.doob 已提交
570

M
Mr.doob 已提交
571 572
		}

573
	}
M
Mr.doob 已提交
574 575 576

	// Buffer rendering

M
Mr.doob 已提交
577 578 579 580 581 582 583 584 585 586
	function renderObjectImmediate( object, program, material ) {

		object.render( function ( object ) {

			_this.renderBufferImmediate( object, program, material );

		} );

	}

M
Mr.doob 已提交
587 588
	this.renderBufferImmediate = function ( object, program, material ) {

589
		state.initAttributes();
590

591
		var buffers = properties.get( object );
592

593 594 595 596
		if ( object.hasPositions && ! buffers.position ) buffers.position = _gl.createBuffer();
		if ( object.hasNormals && ! buffers.normal ) buffers.normal = _gl.createBuffer();
		if ( object.hasUvs && ! buffers.uv ) buffers.uv = _gl.createBuffer();
		if ( object.hasColors && ! buffers.color ) buffers.color = _gl.createBuffer();
M
Mr.doob 已提交
597

598
		var programAttributes = program.getAttributes();
599

M
Mr.doob 已提交
600 601
		if ( object.hasPositions ) {

602
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );
M
Mr.doob 已提交
603
			_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );
604

605 606
			state.enableAttribute( programAttributes.position );
			_gl.vertexAttribPointer( programAttributes.position, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
607 608 609 610 611

		}

		if ( object.hasNormals ) {

612
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.normal );
M
Mr.doob 已提交
613

614
			if ( ! material.isMeshPhongMaterial &&
615
				! material.isMeshStandardMaterial &&
616
				! material.isMeshNormalMaterial &&
617
				material.flatShading === true ) {
M
Mr.doob 已提交
618

619
				for ( var i = 0, l = object.count * 3; i < l; i += 9 ) {
M
Mr.doob 已提交
620

621
					var array = object.normalArray;
M
Mr.doob 已提交
622

623 624 625
					var nx = ( array[ i + 0 ] + array[ i + 3 ] + array[ i + 6 ] ) / 3;
					var ny = ( array[ i + 1 ] + array[ i + 4 ] + array[ i + 7 ] ) / 3;
					var nz = ( array[ i + 2 ] + array[ i + 5 ] + array[ i + 8 ] ) / 3;
M
Mr.doob 已提交
626

627 628 629
					array[ i + 0 ] = nx;
					array[ i + 1 ] = ny;
					array[ i + 2 ] = nz;
M
Mr.doob 已提交
630

631 632 633
					array[ i + 3 ] = nx;
					array[ i + 4 ] = ny;
					array[ i + 5 ] = nz;
M
Mr.doob 已提交
634

635 636 637
					array[ i + 6 ] = nx;
					array[ i + 7 ] = ny;
					array[ i + 8 ] = nz;
M
Mr.doob 已提交
638 639 640 641 642 643

				}

			}

			_gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );
644

645
			state.enableAttribute( programAttributes.normal );
646

647
			_gl.vertexAttribPointer( programAttributes.normal, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
648 649 650 651 652

		}

		if ( object.hasUvs && material.map ) {

653
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );
M
Mr.doob 已提交
654
			_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );
655

656
			state.enableAttribute( programAttributes.uv );
657

658
			_gl.vertexAttribPointer( programAttributes.uv, 2, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
659 660 661

		}

R
Rich Harris 已提交
662
		if ( object.hasColors && material.vertexColors !== NoColors ) {
M
Mr.doob 已提交
663

664
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );
M
Mr.doob 已提交
665
			_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );
666

667
			state.enableAttribute( programAttributes.color );
668

669
			_gl.vertexAttribPointer( programAttributes.color, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
670 671 672

		}

673
		state.disableUnusedAttributes();
674

M
Mr.doob 已提交
675 676 677 678 679 680
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );

		object.count = 0;

	};

681
	this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {
682

683 684 685
		var frontFaceCW = ( object.isMesh && object.matrixWorld.determinant() < 0 );

		state.setMaterial( material, frontFaceCW );
M
Mr.doob 已提交
686

M
Mr.doob 已提交
687
		var program = setProgram( camera, fog, material, object );
M
Mr.doob 已提交
688
		var geometryProgram = geometry.id + '_' + program.id + '_' + ( material.wireframe === true );
M
Mr.doob 已提交
689

M
Mr.doob 已提交
690
		var updateBuffers = false;
M
Mr.doob 已提交
691 692 693 694 695 696 697 698

		if ( geometryProgram !== _currentGeometryProgram ) {

			_currentGeometryProgram = geometryProgram;
			updateBuffers = true;

		}

699
		if ( object.morphTargetInfluences ) {
700

701
			morphtargets.update( object, geometry, material, program );
M
Mr.doob 已提交
702 703 704 705 706

			updateBuffers = true;

		}

707 708
		//

709
		var index = geometry.index;
710
		var position = geometry.attributes.position;
711
		var rangeFactor = 1;
712

713 714
		if ( material.wireframe === true ) {

715
			index = geometries.getWireframeAttribute( geometry );
716
			rangeFactor = 2;
717 718 719

		}

M
Mr.doob 已提交
720
		var attribute;
M
Mr.doob 已提交
721
		var renderer = bufferRenderer;
722

723
		if ( index !== null ) {
724

M
Mr.doob 已提交
725
			attribute = attributes.get( index );
726

727
			renderer = indexedBufferRenderer;
M
Mr.doob 已提交
728
			renderer.setIndex( attribute );
729

730
		}
M
Mr.doob 已提交
731

732
		if ( updateBuffers ) {
M
Mr.doob 已提交
733

734
			setupVertexAttributes( material, program, geometry );
M
Mr.doob 已提交
735

736
			if ( index !== null ) {
737

M
Mr.doob 已提交
738
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, attribute.buffer );
739 740 741

			}

742
		}
743

744 745
		//

746
		var dataCount = 0;
747

M
Mr.doob 已提交
748
		if ( index !== null ) {
749

M
Mr.doob 已提交
750
			dataCount = index.count;
751

M
Mr.doob 已提交
752
		} else if ( position !== undefined ) {
753

M
Mr.doob 已提交
754
			dataCount = position.count;
755

M
Mr.doob 已提交
756
		}
757

M
Mr.doob 已提交
758 759
		var rangeStart = geometry.drawRange.start * rangeFactor;
		var rangeCount = geometry.drawRange.count * rangeFactor;
760

M
Mr.doob 已提交
761 762
		var groupStart = group !== null ? group.start * rangeFactor : 0;
		var groupCount = group !== null ? group.count * rangeFactor : Infinity;
763

M
Mr.doob 已提交
764 765
		var drawStart = Math.max( rangeStart, groupStart );
		var drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1;
M
Mr.doob 已提交
766 767 768

		var drawCount = Math.max( 0, drawEnd - drawStart + 1 );

769 770
		if ( drawCount === 0 ) return;

M
Mr.doob 已提交
771
		//
772

773
		if ( object.isMesh ) {
774

775
			if ( material.wireframe === true ) {
776

777
				state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );
778
				renderer.setMode( _gl.LINES );
779

780
			} else {
M
Mr.doob 已提交
781 782

				switch ( object.drawMode ) {
783

R
Rich Harris 已提交
784
					case TrianglesDrawMode:
B
Ben Adams 已提交
785 786 787
						renderer.setMode( _gl.TRIANGLES );
						break;

R
Rich Harris 已提交
788
					case TriangleStripDrawMode:
B
Ben Adams 已提交
789 790 791
						renderer.setMode( _gl.TRIANGLE_STRIP );
						break;

R
Rich Harris 已提交
792
					case TriangleFanDrawMode:
B
Ben Adams 已提交
793 794 795 796
						renderer.setMode( _gl.TRIANGLE_FAN );
						break;

				}
797

798
			}
799

800

801
		} else if ( object.isLine ) {
802

803
			var lineWidth = material.linewidth;
804

805
			if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material
806

807
			state.setLineWidth( lineWidth * getTargetPixelRatio() );
808

809
			if ( object.isLineSegments ) {
810

811
				renderer.setMode( _gl.LINES );
812

813 814 815 816
			} else if ( object.isLineLoop ) {

				renderer.setMode( _gl.LINE_LOOP );

817
			} else {
818

819
				renderer.setMode( _gl.LINE_STRIP );
820 821

			}
M
Mr.doob 已提交
822

823
		} else if ( object.isPoints ) {
824 825

			renderer.setMode( _gl.POINTS );
826 827

		}
828

T
Takahiro 已提交
829
		if ( geometry && geometry.isInstancedBufferGeometry ) {
M
Mr.doob 已提交
830 831 832

			if ( geometry.maxInstancedCount > 0 ) {

J
jfranc 已提交
833
				renderer.renderInstances( geometry, drawStart, drawCount );
M
Mr.doob 已提交
834

J
jfranc 已提交
835
			}
836 837 838

		} else {

M
Mr.doob 已提交
839
			renderer.render( drawStart, drawCount );
840

M
Mr.doob 已提交
841 842 843 844
		}

	};

845
	function setupVertexAttributes( material, program, geometry, startIndex ) {
M
Mr.doob 已提交
846

T
Takahiro 已提交
847
		if ( geometry && geometry.isInstancedBufferGeometry ) {
B
Ben Adams 已提交
848

849
			if ( extensions.get( 'ANGLE_instanced_arrays' ) === null ) {
B
Ben Adams 已提交
850

851
				console.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
M
Mr.doob 已提交
852
				return;
B
Ben Adams 已提交
853

M
Mr.doob 已提交
854 855 856
			}

		}
B
Ben Adams 已提交
857

858 859
		if ( startIndex === undefined ) startIndex = 0;

860 861
		state.initAttributes();

862
		var geometryAttributes = geometry.attributes;
863

864
		var programAttributes = program.getAttributes();
865

866
		var materialDefaultAttributeValues = material.defaultAttributeValues;
867

868
		for ( var name in programAttributes ) {
869

870
			var programAttribute = programAttributes[ name ];
M
Mr.doob 已提交
871

M
Mr.doob 已提交
872
			if ( programAttribute >= 0 ) {
M
Mr.doob 已提交
873

874
				var geometryAttribute = geometryAttributes[ name ];
875

M
Mr.doob 已提交
876
				if ( geometryAttribute !== undefined ) {
M
Mr.doob 已提交
877

878
					var normalized = geometryAttribute.normalized;
879
					var size = geometryAttribute.itemSize;
880

M
Mr.doob 已提交
881
					var attribute = attributes.get( geometryAttribute );
882

883 884 885 886
					// TODO Attribute may not be available on context restore

					if ( attribute === undefined ) continue;

M
Mr.doob 已提交
887 888 889
					var buffer = attribute.buffer;
					var type = attribute.type;
					var bytesPerElement = attribute.bytesPerElement;
890

A
aardgoose 已提交
891
					if ( geometryAttribute.isInterleavedBufferAttribute ) {
892

M
Mr.doob 已提交
893 894 895 896
						var data = geometryAttribute.data;
						var stride = data.stride;
						var offset = geometryAttribute.offset;

T
Takahiro 已提交
897
						if ( data && data.isInstancedInterleavedBuffer ) {
M
Mr.doob 已提交
898

899
							state.enableAttributeAndDivisor( programAttribute, data.meshPerAttribute );
B
Ben Adams 已提交
900

M
Mr.doob 已提交
901
							if ( geometry.maxInstancedCount === undefined ) {
902

D
dubejf 已提交
903
								geometry.maxInstancedCount = data.meshPerAttribute * data.count;
B
Ben Adams 已提交
904

M
Mr.doob 已提交
905
							}
B
Ben Adams 已提交
906

M
Mr.doob 已提交
907
						} else {
B
Ben Adams 已提交
908

M
Mr.doob 已提交
909
							state.enableAttribute( programAttribute );
B
Ben Adams 已提交
910

M
Mr.doob 已提交
911
						}
B
Ben Adams 已提交
912

M
Mr.doob 已提交
913
						_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
914
						_gl.vertexAttribPointer( programAttribute, size, type, normalized, stride * bytesPerElement, ( startIndex * stride + offset ) * bytesPerElement );
B
Ben Adams 已提交
915

M
Mr.doob 已提交
916
					} else {
B
Ben Adams 已提交
917

A
aardgoose 已提交
918
						if ( geometryAttribute.isInstancedBufferAttribute ) {
B
Ben Adams 已提交
919

920
							state.enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute );
B
Ben Adams 已提交
921

M
Mr.doob 已提交
922
							if ( geometry.maxInstancedCount === undefined ) {
B
Ben Adams 已提交
923

D
dubejf 已提交
924
								geometry.maxInstancedCount = geometryAttribute.meshPerAttribute * geometryAttribute.count;
B
Ben Adams 已提交
925

M
Mr.doob 已提交
926
							}
B
Ben Adams 已提交
927

M
Mr.doob 已提交
928 929 930 931
						} else {

							state.enableAttribute( programAttribute );

M
Mr.doob 已提交
932
						}
B
Ben Adams 已提交
933

M
Mr.doob 已提交
934
						_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
935
						_gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, startIndex * size * bytesPerElement );
M
Mr.doob 已提交
936

B
Ben Adams 已提交
937
					}
M
Mr.doob 已提交
938

939 940
				} else if ( materialDefaultAttributeValues !== undefined ) {

T
tschw 已提交
941
					var value = materialDefaultAttributeValues[ name ];
942

943
					if ( value !== undefined ) {
M
Mr.doob 已提交
944

945
						switch ( value.length ) {
M
Mr.doob 已提交
946

947 948 949
							case 2:
								_gl.vertexAttrib2fv( programAttribute, value );
								break;
M
Mr.doob 已提交
950

951 952 953
							case 3:
								_gl.vertexAttrib3fv( programAttribute, value );
								break;
M
Mr.doob 已提交
954

955 956 957
							case 4:
								_gl.vertexAttrib4fv( programAttribute, value );
								break;
958

959 960
							default:
								_gl.vertexAttrib1fv( programAttribute, value );
961 962

						}
M
Mr.doob 已提交
963 964 965 966 967 968 969 970

					}

				}

			}

		}
971

972
		state.disableUnusedAttributes();
973

M
Mr.doob 已提交
974 975
	}

M
Mr.doob 已提交
976
	// Compile
M
Mr.doob 已提交
977

M
Mr.doob 已提交
978
	this.compile = function ( scene, camera ) {
979

980 981
		lightsArray.length = 0;
		shadowsArray.length = 0;
982

M
Mr.doob 已提交
983
		scene.traverse( function ( object ) {
G
gero3 已提交
984 985

			if ( object.isLight ) {
M
Mr.doob 已提交
986

987 988 989 990 991 992 993
				lightsArray.push( object );

				if ( object.castShadow ) {

					shadowsArray.push( object );

				}
M
Mr.doob 已提交
994

G
gero3 已提交
995
			}
M
Mr.doob 已提交
996 997 998

		} );

999
		lights.setup( lightsArray, shadowsArray, camera );
M
Mr.doob 已提交
1000 1001 1002 1003 1004

		scene.traverse( function ( object ) {

			if ( object.material ) {

G
gero3 已提交
1005
				if ( Array.isArray( object.material ) ) {
M
Mr.doob 已提交
1006

G
gero3 已提交
1007
					for ( var i = 0; i < object.material.length; i ++ ) {
M
Mr.doob 已提交
1008 1009 1010

						initMaterial( object.material[ i ], scene.fog, object );

G
gero3 已提交
1011
					}
M
Mr.doob 已提交
1012

G
gero3 已提交
1013
				} else {
M
Mr.doob 已提交
1014 1015 1016

					initMaterial( object.material, scene.fog, object );

G
gero3 已提交
1017
				}
M
Mr.doob 已提交
1018

G
gero3 已提交
1019
			}
M
Mr.doob 已提交
1020 1021

		} );
G
gero3 已提交
1022 1023

	};
1024

1025
	// Animation Loop
M
Mr.doob 已提交
1026

1027 1028
	var isAnimating = false;
	var onAnimationFrame = null;
1029

1030
	function start() {
1031

1032
		if ( isAnimating ) return;
1033 1034

		var device = vr.getDevice();
M
Mugen87 已提交
1035

1036
		if ( device && device.isPresenting ) {
1037 1038 1039 1040 1041 1042 1043 1044

			device.requestAnimationFrame( loop );

		} else {

			window.requestAnimationFrame( loop );

		}
1045

1046
		isAnimating = true;
1047

1048
	}
1049

1050
	function loop( time ) {
1051

1052
		if ( onAnimationFrame !== null ) onAnimationFrame( time );
1053 1054

		var device = vr.getDevice();
M
Mugen87 已提交
1055

1056
		if ( device && device.isPresenting ) {
1057 1058 1059 1060 1061 1062 1063 1064

			device.requestAnimationFrame( loop );

		} else {

			window.requestAnimationFrame( loop );

		}
1065

1066 1067 1068
	}

	this.animate = function ( callback ) {
1069

1070 1071
		onAnimationFrame = callback;
		start();
1072 1073 1074

	};

M
Mr.doob 已提交
1075 1076 1077
	// Rendering

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

0
06wj 已提交
1079
		if ( ! ( camera && camera.isCamera ) ) {
M
Mr.doob 已提交
1080

1081
			console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );
M
Mr.doob 已提交
1082 1083 1084 1085
			return;

		}

1086 1087
		if ( _isContextLost ) return;

M
Mr.doob 已提交
1088 1089
		// reset caching for this frame

1090
		_currentGeometryProgram = '';
1091
		_currentMaterialId = - 1;
1092
		_currentCamera = null;
M
Mr.doob 已提交
1093 1094 1095

		// update scene graph

1096
		if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
M
Mr.doob 已提交
1097 1098 1099

		// update camera matrices and frustum

1100
		if ( camera.parent === null ) camera.updateMatrixWorld();
M
Mr.doob 已提交
1101

1102 1103 1104 1105 1106 1107
		if ( vr.enabled ) {

			camera = vr.getCamera( camera );

		}

M
Mr.doob 已提交
1108 1109 1110
		_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
		_frustum.setFromMatrix( _projScreenMatrix );

1111 1112 1113
		lightsArray.length = 0;
		shadowsArray.length = 0;

1114 1115
		spritesArray.length = 0;
		flaresArray.length = 0;
M
Mr.doob 已提交
1116

T
tschw 已提交
1117
		_localClippingEnabled = this.localClippingEnabled;
M
Mr.doob 已提交
1118
		_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );
T
tschw 已提交
1119

1120 1121 1122
		currentRenderList = renderLists.get( scene, camera );
		currentRenderList.init();

M
Mr.doob 已提交
1123
		projectObject( scene, camera, _this.sortObjects );
M
Mr.doob 已提交
1124

M
Mr.doob 已提交
1125
		if ( _this.sortObjects === true ) {
1126

1127
			currentRenderList.sort();
M
Mr.doob 已提交
1128

1129 1130
		}

M
Mr.doob 已提交
1131
		//
M
Mr.doob 已提交
1132

M
Mugen87 已提交
1133 1134 1135 1136
		textures.updateVideoTextures();

		//

T
tschw 已提交
1137
		if ( _clippingEnabled ) _clipping.beginShadows();
T
tschw 已提交
1138

1139
		shadowMap.render( shadowsArray, scene, camera );
1140

1141
		lights.setup( lightsArray, shadowsArray, camera );
1142

T
tschw 已提交
1143
		if ( _clippingEnabled ) _clipping.endShadows();
T
tschw 已提交
1144

M
Mr.doob 已提交
1145 1146
		//

M
Mr.doob 已提交
1147
		_infoRender.frame ++;
1148 1149 1150 1151
		_infoRender.calls = 0;
		_infoRender.vertices = 0;
		_infoRender.faces = 0;
		_infoRender.points = 0;
M
Mr.doob 已提交
1152

1153 1154 1155 1156 1157 1158
		if ( renderTarget === undefined ) {

			renderTarget = null;

		}

M
Mr.doob 已提交
1159 1160
		this.setRenderTarget( renderTarget );

M
Mr.doob 已提交
1161 1162
		//

1163
		background.render( currentRenderList, scene, camera, forceClear );
M
Mr.doob 已提交
1164

1165
		// render scene
M
Mr.doob 已提交
1166

1167 1168 1169
		var opaqueObjects = currentRenderList.opaque;
		var transparentObjects = currentRenderList.transparent;

M
Mr.doob 已提交
1170 1171
		if ( scene.overrideMaterial ) {

1172
			var overrideMaterial = scene.overrideMaterial;
M
Mr.doob 已提交
1173

M
Mr.doob 已提交
1174 1175
			if ( opaqueObjects.length ) renderObjects( opaqueObjects, scene, camera, overrideMaterial );
			if ( transparentObjects.length ) renderObjects( transparentObjects, scene, camera, overrideMaterial );
1176

M
Mr.doob 已提交
1177 1178 1179 1180
		} else {

			// opaque pass (front-to-back order)

M
Mr.doob 已提交
1181
			if ( opaqueObjects.length ) renderObjects( opaqueObjects, scene, camera );
M
Mr.doob 已提交
1182 1183 1184

			// transparent pass (back-to-front order)

M
Mr.doob 已提交
1185
			if ( transparentObjects.length ) renderObjects( transparentObjects, scene, camera );
M
Mr.doob 已提交
1186 1187 1188

		}

1189
		// custom renderers
M
Mr.doob 已提交
1190

1191 1192
		spriteRenderer.render( spritesArray, scene, camera );
		flareRenderer.render( flaresArray, scene, camera, _currentViewport );
M
Mr.doob 已提交
1193 1194 1195

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

M
Mr.doob 已提交
1196 1197
		if ( renderTarget ) {

1198
			textures.updateRenderTargetMipmap( renderTarget );
M
Mr.doob 已提交
1199 1200 1201

		}

1202
		// Ensure depth buffer writing is enabled so it can be cleared on next render
M
Mr.doob 已提交
1203

1204 1205 1206
		state.buffers.depth.setTest( true );
		state.buffers.depth.setMask( true );
		state.buffers.color.setMask( true );
M
Mr.doob 已提交
1207

1208
		state.setPolygonOffset( false );
1209

M
Mr.doob 已提交
1210
		if ( vr.enabled ) {
1211

M
Mr.doob 已提交
1212
			vr.submitFrame();
1213

M
Mr.doob 已提交
1214
		}
M
Mr.doob 已提交
1215

M
Mr.doob 已提交
1216 1217 1218
		// _gl.finish();

	};
M
Mr.doob 已提交
1219

1220
	/*
M
Mr.doob 已提交
1221 1222
	// TODO Duplicated code (Frustum)

1223 1224
	var _sphere = new Sphere();

T
tschw 已提交
1225 1226 1227 1228 1229 1230 1231
	function isObjectViewable( object ) {

		var geometry = object.geometry;

		if ( geometry.boundingSphere === null )
			geometry.computeBoundingSphere();

M
Mr.doob 已提交
1232
		_sphere.copy( geometry.boundingSphere ).
1233
		applyMatrix4( object.matrixWorld );
M
Mr.doob 已提交
1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249

		return isSphereViewable( _sphere );

	}

	function isSpriteViewable( sprite ) {

		_sphere.center.set( 0, 0, 0 );
		_sphere.radius = 0.7071067811865476;
		_sphere.applyMatrix4( sprite.matrixWorld );

		return isSphereViewable( _sphere );

	}

	function isSphereViewable( sphere ) {
T
tschw 已提交
1250 1251

		if ( ! _frustum.intersectsSphere( sphere ) ) return false;
T
tschw 已提交
1252 1253 1254 1255

		var numPlanes = _clipping.numPlanes;

		if ( numPlanes === 0 ) return true;
T
tschw 已提交
1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267

		var planes = _this.clippingPlanes,

			center = sphere.center,
			negRad = - sphere.radius,
			i = 0;

		do {

			// out when deeper than radius in the negative halfspace
			if ( planes[ i ].distanceToPoint( center ) < negRad ) return false;

T
tschw 已提交
1268
		} while ( ++ i !== numPlanes );
T
tschw 已提交
1269 1270 1271 1272

		return true;

	}
1273
	*/
T
tschw 已提交
1274

M
Mr.doob 已提交
1275
	function projectObject( object, camera, sortObjects ) {
M
Mr.doob 已提交
1276

1277
		if ( object.visible === false ) return;
M
Mr.doob 已提交
1278

1279
		var visible = object.layers.test( camera.layers );
M
Mr.doob 已提交
1280

1281
		if ( visible ) {
1282

1283
			if ( object.isLight ) {
M
Mr.doob 已提交
1284

1285 1286 1287 1288 1289 1290 1291
				lightsArray.push( object );

				if ( object.castShadow ) {

					shadowsArray.push( object );

				}
M
Mr.doob 已提交
1292

1293
			} else if ( object.isSprite ) {
M
Mr.doob 已提交
1294

1295
				if ( ! object.frustumCulled || _frustum.intersectsSprite( object ) ) {
1296

1297
					spritesArray.push( object );
M
Mr.doob 已提交
1298

1299
				}
M
Mr.doob 已提交
1300

1301
			} else if ( object.isLensFlare ) {
M
Mr.doob 已提交
1302

1303
				flaresArray.push( object );
M
Mr.doob 已提交
1304

1305
			} else if ( object.isImmediateRenderObject ) {
M
Mr.doob 已提交
1306

1307
				if ( sortObjects ) {
M
Mr.doob 已提交
1308

1309 1310
					_vector3.setFromMatrixPosition( object.matrixWorld )
						.applyMatrix4( _projScreenMatrix );
M
Mr.doob 已提交
1311

1312
				}
M
Mr.doob 已提交
1313

1314
				currentRenderList.push( object, null, object.material, _vector3.z, null );
1315

1316
			} else if ( object.isMesh || object.isLine || object.isPoints ) {
1317

1318
				if ( object.isSkinnedMesh ) {
1319

1320
					object.skeleton.update();
1321

1322
				}
1323

1324
				if ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) {
1325

1326 1327 1328 1329 1330 1331
					if ( sortObjects ) {

						_vector3.setFromMatrixPosition( object.matrixWorld )
							.applyMatrix4( _projScreenMatrix );

					}
1332

1333 1334
					var geometry = objects.update( object );
					var material = object.material;
1335

1336
					if ( Array.isArray( material ) ) {
1337

1338
						var groups = geometry.groups;
1339

1340
						for ( var i = 0, l = groups.length; i < l; i ++ ) {
M
Mr.doob 已提交
1341

1342 1343
							var group = groups[ i ];
							var groupMaterial = material[ group.materialIndex ];
1344

1345
							if ( groupMaterial && groupMaterial.visible ) {
1346

1347 1348 1349
								currentRenderList.push( object, geometry, groupMaterial, _vector3.z, group );

							}
M
Mr.doob 已提交
1350

M
Mr.doob 已提交
1351
						}
M
Mr.doob 已提交
1352

1353
					} else if ( material.visible ) {
1354

1355
						currentRenderList.push( object, geometry, material, _vector3.z, null );
O
OpenShift guest 已提交
1356

1357
					}
M
Mr.doob 已提交
1358

1359
				}
M
Mr.doob 已提交
1360

1361
			}
M
Mr.doob 已提交
1362

M
Mr.doob 已提交
1363
		}
M
Mr.doob 已提交
1364

M
Mr.doob 已提交
1365
		var children = object.children;
M
Mr.doob 已提交
1366

M
Mr.doob 已提交
1367 1368
		for ( var i = 0, l = children.length; i < l; i ++ ) {

M
Mr.doob 已提交
1369
			projectObject( children[ i ], camera, sortObjects );
M
Mr.doob 已提交
1370

1371
		}
1372

1373
	}
M
Mr.doob 已提交
1374

1375
	function renderObjects( renderList, scene, camera, overrideMaterial ) {
M
Mr.doob 已提交
1376

M
Mr.doob 已提交
1377
		for ( var i = 0, l = renderList.length; i < l; i ++ ) {
M
Mr.doob 已提交
1378

1379
			var renderItem = renderList[ i ];
M
Mr.doob 已提交
1380

1381
			var object = renderItem.object;
M
Mr.doob 已提交
1382 1383 1384
			var geometry = renderItem.geometry;
			var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;
			var group = renderItem.group;
M
Mr.doob 已提交
1385

M
Mr.doob 已提交
1386
			if ( camera.isArrayCamera ) {
M
Mr.doob 已提交
1387

1388 1389
				_currentArrayCamera = camera;

M
Mr.doob 已提交
1390
				var cameras = camera.cameras;
M
Mr.doob 已提交
1391

M
Mr.doob 已提交
1392
				for ( var j = 0, jl = cameras.length; j < jl; j ++ ) {
M
Mr.doob 已提交
1393

M
Mr.doob 已提交
1394
					var camera2 = cameras[ j ];
M
Mr.doob 已提交
1395

1396
					if ( object.layers.test( camera2.layers ) ) {
1397

1398
						var bounds = camera2.bounds;
1399

1400 1401 1402 1403
						var x = bounds.x * _width;
						var y = bounds.y * _height;
						var width = bounds.z * _width;
						var height = bounds.w * _height;
M
Mr.doob 已提交
1404

1405
						state.viewport( _currentViewport.set( x, y, width, height ).multiplyScalar( _pixelRatio ) );
1406 1407 1408 1409

						renderObject( object, scene, camera2, geometry, material, group );

					}
M
Mr.doob 已提交
1410

M
Mr.doob 已提交
1411
				}
1412

M
Mr.doob 已提交
1413
			} else {
M
Mr.doob 已提交
1414

1415 1416
				_currentArrayCamera = null;

M
Mr.doob 已提交
1417
				renderObject( object, scene, camera, geometry, material, group );
M
Mr.doob 已提交
1418

M
Mr.doob 已提交
1419
			}
M
Mr.doob 已提交
1420

1421
		}
M
Mr.doob 已提交
1422

1423
	}
G
gero3 已提交
1424

M
Mr.doob 已提交
1425 1426
	function renderObject( object, scene, camera, geometry, material, group ) {

1427 1428
		object.onBeforeRender( _this, scene, camera, geometry, material, group );

M
Mr.doob 已提交
1429 1430 1431 1432 1433
		object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
		object.normalMatrix.getNormalMatrix( object.modelViewMatrix );

		if ( object.isImmediateRenderObject ) {

1434 1435 1436
			var frontFaceCW = ( object.isMesh && object.matrixWorld.determinant() < 0 );

			state.setMaterial( material, frontFaceCW );
M
Mr.doob 已提交
1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449

			var program = setProgram( camera, scene.fog, material, object );

			_currentGeometryProgram = '';

			renderObjectImmediate( object, program, material );

		} else {

			_this.renderBufferDirect( camera, scene.fog, geometry, material, object, group );

		}

M
Mr.doob 已提交
1450 1451
		object.onAfterRender( _this, scene, camera, geometry, material, group );

M
Mr.doob 已提交
1452 1453
	}

1454
	function initMaterial( material, fog, object ) {
M
Mr.doob 已提交
1455

1456
		var materialProperties = properties.get( material );
G
gero3 已提交
1457

T
tschw 已提交
1458
		var parameters = programCache.getParameters(
1459
			material, lights.state, shadowsArray, fog, _clipping.numPlanes, _clipping.numIntersection, object );
T
tschw 已提交
1460

G
gero3 已提交
1461
		var code = programCache.getProgramCode( material, parameters );
G
gero3 已提交
1462

1463
		var program = materialProperties.program;
T
tschw 已提交
1464
		var programChange = true;
1465

1466
		if ( program === undefined ) {
B
Ben Adams 已提交
1467

M
Mr.doob 已提交
1468 1469
			// new material
			material.addEventListener( 'dispose', onMaterialDispose );
B
Ben Adams 已提交
1470

1471
		} else if ( program.code !== code ) {
B
Ben Adams 已提交
1472

M
Mr.doob 已提交
1473
			// changed glsl or parameters
1474
			releaseMaterialProgramReference( material );
B
Ben Adams 已提交
1475

G
gero3 已提交
1476
		} else if ( parameters.shaderID !== undefined ) {
B
Ben Adams 已提交
1477

T
tschw 已提交
1478
			// same glsl and uniform list
T
tschw 已提交
1479 1480
			return;

T
tschw 已提交
1481
		} else {
B
Ben Adams 已提交
1482

T
tschw 已提交
1483 1484
			// only rebuild uniform list
			programChange = false;
B
Ben Adams 已提交
1485 1486 1487

		}

1488
		if ( programChange ) {
B
Ben Adams 已提交
1489

1490
			if ( parameters.shaderID ) {
B
Ben Adams 已提交
1491

R
Rich Harris 已提交
1492
				var shader = ShaderLib[ parameters.shaderID ];
B
Ben Adams 已提交
1493

1494
				materialProperties.shader = {
1495
					name: material.type,
1496
					uniforms: UniformsUtils.clone( shader.uniforms ),
1497 1498 1499
					vertexShader: shader.vertexShader,
					fragmentShader: shader.fragmentShader
				};
B
Ben Adams 已提交
1500

1501
			} else {
B
Ben Adams 已提交
1502

1503
				materialProperties.shader = {
1504 1505 1506 1507 1508
					name: material.type,
					uniforms: material.uniforms,
					vertexShader: material.vertexShader,
					fragmentShader: material.fragmentShader
				};
G
gero3 已提交
1509

1510
			}
G
gero3 已提交
1511

1512
			material.onBeforeCompile( materialProperties.shader );
G
gero3 已提交
1513

1514
			program = programCache.acquireProgram( material, materialProperties.shader, parameters, code );
B
Ben Adams 已提交
1515

1516 1517
			materialProperties.program = program;
			material.program = program;
1518 1519 1520

		}

1521
		var programAttributes = program.getAttributes();
M
Mr.doob 已提交
1522 1523 1524 1525 1526

		if ( material.morphTargets ) {

			material.numSupportedMorphTargets = 0;

1527
			for ( var i = 0; i < _this.maxMorphTargets; i ++ ) {
M
Mr.doob 已提交
1528

1529
				if ( programAttributes[ 'morphTarget' + i ] >= 0 ) {
M
Mr.doob 已提交
1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542

					material.numSupportedMorphTargets ++;

				}

			}

		}

		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

M
Mr.doob 已提交
1543
			for ( var i = 0; i < _this.maxMorphNormals; i ++ ) {
M
Mr.doob 已提交
1544

1545
				if ( programAttributes[ 'morphNormal' + i ] >= 0 ) {
M
Mr.doob 已提交
1546 1547 1548 1549 1550 1551 1552 1553 1554

					material.numSupportedMorphNormals ++;

				}

			}

		}

1555
		var uniforms = materialProperties.shader.uniforms;
T
tschw 已提交
1556

1557
		if ( ! material.isShaderMaterial &&
1558 1559
			! material.isRawShaderMaterial ||
			material.clipping === true ) {
T
tschw 已提交
1560

T
tschw 已提交
1561
			materialProperties.numClippingPlanes = _clipping.numPlanes;
1562
			materialProperties.numIntersection = _clipping.numIntersection;
T
tschw 已提交
1563
			uniforms.clippingPlanes = _clipping.uniform;
T
tschw 已提交
1564 1565 1566

		}

1567
		materialProperties.fog = fog;
1568

1569
		// store the light setup it was created for
1570

1571
		materialProperties.lightsHash = lights.state.hash;
1572

M
Mr.doob 已提交
1573
		if ( material.lights ) {
1574 1575 1576

			// wire up the material to this renderer's lighting state

1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589
			uniforms.ambientLightColor.value = lights.state.ambient;
			uniforms.directionalLights.value = lights.state.directional;
			uniforms.spotLights.value = lights.state.spot;
			uniforms.rectAreaLights.value = lights.state.rectArea;
			uniforms.pointLights.value = lights.state.point;
			uniforms.hemisphereLights.value = lights.state.hemi;

			uniforms.directionalShadowMap.value = lights.state.directionalShadowMap;
			uniforms.directionalShadowMatrix.value = lights.state.directionalShadowMatrix;
			uniforms.spotShadowMap.value = lights.state.spotShadowMap;
			uniforms.spotShadowMatrix.value = lights.state.spotShadowMatrix;
			uniforms.pointShadowMap.value = lights.state.pointShadowMap;
			uniforms.pointShadowMatrix.value = lights.state.pointShadowMatrix;
1590
			// TODO (abelnation): add area lights shadow info to uniforms
1591

1592 1593
		}

T
tschw 已提交
1594 1595
		var progUniforms = materialProperties.program.getUniforms(),
			uniformsList =
1596
				WebGLUniforms.seqWithValue( progUniforms.seq, uniforms );
A
arose 已提交
1597

T
tschw 已提交
1598
		materialProperties.uniformsList = uniformsList;
A
arose 已提交
1599

M
Mr.doob 已提交
1600
	}
M
Mr.doob 已提交
1601

1602
	function setProgram( camera, fog, material, object ) {
M
Mr.doob 已提交
1603 1604 1605

		_usedTextureUnits = 0;

1606
		var materialProperties = properties.get( material );
1607

T
tschw 已提交
1608 1609 1610 1611 1612
		if ( _clippingEnabled ) {

			if ( _localClippingEnabled || camera !== _currentCamera ) {

				var useCache =
1613 1614
					camera === _currentCamera &&
					material.id === _currentMaterialId;
T
tschw 已提交
1615 1616 1617 1618

				// we might want to call this function with some ClippingGroup
				// object instead of the material, once it becomes feasible
				// (#8465, #8379)
T
tschw 已提交
1619
				_clipping.setState(
1620 1621
					material.clippingPlanes, material.clipIntersection, material.clipShadows,
					camera, materialProperties, useCache );
T
tschw 已提交
1622 1623 1624 1625 1626

			}

		}

1627
		if ( material.needsUpdate === false ) {
1628

1629
			if ( materialProperties.program === undefined ) {
1630

1631
				material.needsUpdate = true;
1632

1633
			} else if ( material.fog && materialProperties.fog !== fog ) {
1634

M
Mr.doob 已提交
1635
				material.needsUpdate = true;
1636

1637
			} else if ( material.lights && materialProperties.lightsHash !== lights.state.hash ) {
1638

1639
				material.needsUpdate = true;
1640

1641
			} else if ( materialProperties.numClippingPlanes !== undefined &&
1642
				( materialProperties.numClippingPlanes !== _clipping.numPlanes ||
M
Mr.doob 已提交
1643
				materialProperties.numIntersection !== _clipping.numIntersection ) ) {
1644 1645 1646

				material.needsUpdate = true;

1647
			}
1648 1649 1650 1651

		}

		if ( material.needsUpdate ) {
M
Mr.doob 已提交
1652

1653
			initMaterial( material, fog, object );
M
Mr.doob 已提交
1654 1655 1656 1657
			material.needsUpdate = false;

		}

1658
		var refreshProgram = false;
M
Mr.doob 已提交
1659
		var refreshMaterial = false;
1660
		var refreshLights = false;
M
Mr.doob 已提交
1661

1662
		var program = materialProperties.program,
1663
			p_uniforms = program.getUniforms(),
1664
			m_uniforms = materialProperties.shader.uniforms;
M
Mr.doob 已提交
1665

1666
		if ( state.useProgram( program.program ) ) {
M
Mr.doob 已提交
1667

1668
			refreshProgram = true;
M
Mr.doob 已提交
1669
			refreshMaterial = true;
1670
			refreshLights = true;
M
Mr.doob 已提交
1671 1672 1673 1674 1675 1676

		}

		if ( material.id !== _currentMaterialId ) {

			_currentMaterialId = material.id;
1677

M
Mr.doob 已提交
1678 1679 1680 1681
			refreshMaterial = true;

		}

1682
		if ( refreshProgram || camera !== _currentCamera ) {
M
Mr.doob 已提交
1683

M
Mr.doob 已提交
1684
			p_uniforms.setValue( _gl, 'projectionMatrix', camera.projectionMatrix );
M
Mr.doob 已提交
1685

G
gero3 已提交
1686
			if ( capabilities.logarithmicDepthBuffer ) {
1687

T
tschw 已提交
1688
				p_uniforms.setValue( _gl, 'logDepthBufFC',
1689
					2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
1690 1691 1692

			}

1693
			// Avoid unneeded uniform updates per ArrayCamera's sub-camera
1694

1695
			if ( _currentCamera !== ( _currentArrayCamera || camera ) ) {
1696

1697
				_currentCamera = ( _currentArrayCamera || camera );
1698 1699 1700 1701 1702 1703

				// lighting uniforms depend on the camera so enforce an update
				// now, in case this material supports lights - or later, when
				// the next material that does gets activated:

				refreshMaterial = true;		// set to true on material change
T
tschw 已提交
1704
				refreshLights = true;		// remains set until update done
1705 1706

			}
M
Mr.doob 已提交
1707

1708 1709 1710
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)

1711
			if ( material.isShaderMaterial ||
1712 1713 1714
				material.isMeshPhongMaterial ||
				material.isMeshStandardMaterial ||
				material.envMap ) {
1715

T
tschw 已提交
1716 1717 1718
				var uCamPos = p_uniforms.map.cameraPosition;

				if ( uCamPos !== undefined ) {
1719

T
tschw 已提交
1720
					uCamPos.setValue( _gl,
1721
						_vector3.setFromMatrixPosition( camera.matrixWorld ) );
1722 1723 1724 1725 1726

				}

			}

1727
			if ( material.isMeshPhongMaterial ||
1728 1729 1730 1731
				material.isMeshLambertMaterial ||
				material.isMeshBasicMaterial ||
				material.isMeshStandardMaterial ||
				material.isShaderMaterial ||
1732
				material.skinning ) {
1733

T
tschw 已提交
1734
				p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );
1735 1736 1737

			}

M
Mr.doob 已提交
1738 1739 1740 1741 1742 1743
		}

		// skinning uniforms must be set even if material didn't change
		// auto-setting of texture unit for bone texture must go before other textures
		// not sure why, but otherwise weird things happen

1744
		if ( material.skinning ) {
M
Mr.doob 已提交
1745

T
tschw 已提交
1746 1747
			p_uniforms.setOptional( _gl, object, 'bindMatrix' );
			p_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );
1748

T
tschw 已提交
1749
			var skeleton = object.skeleton;
1750

T
tschw 已提交
1751
			if ( skeleton ) {
1752

1753 1754
				var bones = skeleton.bones;

1755
				if ( capabilities.floatVertexTextures ) {
M
Mr.doob 已提交
1756

1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767
					if ( skeleton.boneTexture === undefined ) {

						// layout (1 matrix = 4 pixels)
						//      RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)
						//  with  8x8  pixel texture max   16 bones * 4 pixels =  (8 * 8)
						//       16x16 pixel texture max   64 bones * 4 pixels = (16 * 16)
						//       32x32 pixel texture max  256 bones * 4 pixels = (32 * 32)
						//       64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64)


						var size = Math.sqrt( bones.length * 4 ); // 4 pixels needed for 1 matrix
1768
						size = _Math.ceilPowerOfTwo( size );
1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781
						size = Math.max( size, 4 );

						var boneMatrices = new Float32Array( size * size * 4 ); // 4 floats per RGBA pixel
						boneMatrices.set( skeleton.boneMatrices ); // copy current values

						var boneTexture = new DataTexture( boneMatrices, size, size, RGBAFormat, FloatType );

						skeleton.boneMatrices = boneMatrices;
						skeleton.boneTexture = boneTexture;
						skeleton.boneTextureSize = size;

					}

M
Mr.doob 已提交
1782 1783
					p_uniforms.setValue( _gl, 'boneTexture', skeleton.boneTexture );
					p_uniforms.setValue( _gl, 'boneTextureSize', skeleton.boneTextureSize );
M
Mr.doob 已提交
1784

T
tschw 已提交
1785
				} else {
M
Mr.doob 已提交
1786

T
tschw 已提交
1787
					p_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );
M
Mr.doob 已提交
1788 1789 1790 1791 1792 1793 1794 1795 1796

				}

			}

		}

		if ( refreshMaterial ) {

1797 1798 1799
			p_uniforms.setValue( _gl, 'toneMappingExposure', _this.toneMappingExposure );
			p_uniforms.setValue( _gl, 'toneMappingWhitePoint', _this.toneMappingWhitePoint );

M
Mr.doob 已提交
1800
			if ( material.lights ) {
M
Mr.doob 已提交
1801

1802
				// the current material requires lighting info
M
Mr.doob 已提交
1803

T
tschw 已提交
1804 1805 1806 1807 1808 1809
				// note: all lighting uniforms are always set correctly
				// they simply reference the renderer's state for their
				// values
				//
				// use the current material's .needsUpdate flags to set
				// the GL state when required
M
Mr.doob 已提交
1810

T
tschw 已提交
1811
				markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
G
gero3 已提交
1812

T
tschw 已提交
1813
			}
G
gero3 已提交
1814

T
tschw 已提交
1815
			// refresh uniforms common to several materials
G
gero3 已提交
1816

T
tschw 已提交
1817
			if ( fog && material.fog ) {
G
gero3 已提交
1818

T
tschw 已提交
1819
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
1820 1821 1822

			}

1823
			if ( material.isMeshBasicMaterial ) {
M
Mr.doob 已提交
1824 1825 1826

				refreshUniformsCommon( m_uniforms, material );

1827
			} else if ( material.isMeshLambertMaterial ) {
M
Mr.doob 已提交
1828

1829 1830
				refreshUniformsCommon( m_uniforms, material );
				refreshUniformsLambert( m_uniforms, material );
M
Mr.doob 已提交
1831

1832
			} else if ( material.isMeshPhongMaterial ) {
M
Mr.doob 已提交
1833

1834
				refreshUniformsCommon( m_uniforms, material );
M
Mr.doob 已提交
1835

1836
				if ( material.isMeshToonMaterial ) {
M
Mr.doob 已提交
1837

1838
					refreshUniformsToon( m_uniforms, material );
M
Mr.doob 已提交
1839

1840
				} else {
1841

1842
					refreshUniformsPhong( m_uniforms, material );
1843

1844
				}
T
Takahiro 已提交
1845

1846
			} else if ( material.isMeshStandardMaterial ) {
T
Takahiro 已提交
1847

1848
				refreshUniformsCommon( m_uniforms, material );
1849

1850
				if ( material.isMeshPhysicalMaterial ) {
1851

1852
					refreshUniformsPhysical( m_uniforms, material );
W
WestLangley 已提交
1853

1854
				} else {
W
WestLangley 已提交
1855

1856
					refreshUniformsStandard( m_uniforms, material );
W
WestLangley 已提交
1857

1858
				}
W
WestLangley 已提交
1859

1860
			} else if ( material.isMeshDepthMaterial ) {
M
Mr.doob 已提交
1861

1862
				refreshUniformsCommon( m_uniforms, material );
W
WestLangley 已提交
1863
				refreshUniformsDepth( m_uniforms, material );
1864

W
WestLangley 已提交
1865
			} else if ( material.isMeshDistanceMaterial ) {
1866

1867
				refreshUniformsCommon( m_uniforms, material );
W
WestLangley 已提交
1868
				refreshUniformsDistance( m_uniforms, material );
1869

1870
			} else if ( material.isMeshNormalMaterial ) {
M
Mr.doob 已提交
1871

1872
				refreshUniformsCommon( m_uniforms, material );
1873
				refreshUniformsNormal( m_uniforms, material );
M
Mr.doob 已提交
1874

1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888
			} else if ( material.isLineBasicMaterial ) {

				refreshUniformsLine( m_uniforms, material );

				if ( material.isLineDashedMaterial ) {

					refreshUniformsDash( m_uniforms, material );

				}

			} else if ( material.isPointsMaterial ) {

				refreshUniformsPoints( m_uniforms, material );

1889 1890 1891 1892 1893
			} else if ( material.isShadowMaterial ) {

				m_uniforms.color.value = material.color;
				m_uniforms.opacity.value = material.opacity;

M
Mr.doob 已提交
1894 1895
			}

M
Mr.doob 已提交
1896 1897 1898
			// RectAreaLight Texture
			// TODO (mrdoob): Find a nicer implementation

1899 1900
			if ( m_uniforms.ltc_1 !== undefined ) m_uniforms.ltc_1.value = UniformsLib.LTC_1;
			if ( m_uniforms.ltc_2 !== undefined ) m_uniforms.ltc_2.value = UniformsLib.LTC_2;
M
Mr.doob 已提交
1901

1902
			WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, _this );
A
arose 已提交
1903 1904 1905

		}

M
Mr.doob 已提交
1906

T
tschw 已提交
1907
		// common matrices
M
Mr.doob 已提交
1908

M
Mr.doob 已提交
1909 1910
		p_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix );
		p_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix );
T
tschw 已提交
1911
		p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );
A
arose 已提交
1912

T
tschw 已提交
1913
		return program;
A
arose 已提交
1914 1915 1916

	}

M
Mr.doob 已提交
1917 1918
	// Uniforms (refresh uniforms objects)

M
Mr.doob 已提交
1919
	function refreshUniformsCommon( uniforms, material ) {
M
Mr.doob 已提交
1920 1921 1922

		uniforms.opacity.value = material.opacity;

1923 1924 1925 1926 1927
		if ( material.color ) {

			uniforms.diffuse.value = material.color;

		}
M
Mr.doob 已提交
1928

1929
		if ( material.emissive ) {
M
Mr.doob 已提交
1930

1931
			uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );
M
Mr.doob 已提交
1932 1933 1934

		}

1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966
		if ( material.map ) {

			uniforms.map.value = material.map;

		}

		if ( material.alphaMap ) {

			uniforms.alphaMap.value = material.alphaMap;

		}

		if ( material.specularMap ) {

			uniforms.specularMap.value = material.specularMap;

		}

		if ( material.envMap ) {

			uniforms.envMap.value = material.envMap;

			// don't flip CubeTexture envMaps, flip everything else:
			//  WebGLRenderTargetCube will be flipped for backwards compatibility
			//  WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture
			// this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future
			uniforms.flipEnvMap.value = ( ! ( material.envMap && material.envMap.isCubeTexture ) ) ? 1 : - 1;

			uniforms.reflectivity.value = material.reflectivity;
			uniforms.refractionRatio.value = material.refractionRatio;

		}
M
Mr.doob 已提交
1967

1968 1969 1970 1971 1972 1973 1974
		if ( material.lightMap ) {

			uniforms.lightMap.value = material.lightMap;
			uniforms.lightMapIntensity.value = material.lightMapIntensity;

		}

1975
		if ( material.aoMap ) {
1976

1977 1978
			uniforms.aoMap.value = material.aoMap;
			uniforms.aoMapIntensity.value = material.aoMapIntensity;
1979 1980 1981

		}

M
Mr.doob 已提交
1982
		// uv repeat and offset setting priorities
M
Mr.doob 已提交
1983 1984 1985 1986 1987
		// 1. color map
		// 2. specular map
		// 3. normal map
		// 4. bump map
		// 5. alpha map
1988
		// 6. emissive map
M
Mr.doob 已提交
1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999

		var uvScaleMap;

		if ( material.map ) {

			uvScaleMap = material.map;

		} else if ( material.specularMap ) {

			uvScaleMap = material.specularMap;

2000 2001 2002 2003
		} else if ( material.displacementMap ) {

			uvScaleMap = material.displacementMap;

M
Mr.doob 已提交
2004 2005 2006 2007 2008 2009 2010 2011
		} else if ( material.normalMap ) {

			uvScaleMap = material.normalMap;

		} else if ( material.bumpMap ) {

			uvScaleMap = material.bumpMap;

2012 2013 2014 2015 2016 2017 2018 2019
		} else if ( material.roughnessMap ) {

			uvScaleMap = material.roughnessMap;

		} else if ( material.metalnessMap ) {

			uvScaleMap = material.metalnessMap;

2020 2021 2022 2023
		} else if ( material.alphaMap ) {

			uvScaleMap = material.alphaMap;

2024 2025 2026 2027
		} else if ( material.emissiveMap ) {

			uvScaleMap = material.emissiveMap;

M
Mr.doob 已提交
2028 2029 2030 2031
		}

		if ( uvScaleMap !== undefined ) {

2032
			// backwards compatibility
2033
			if ( uvScaleMap.isWebGLRenderTarget ) {
M
Mr.doob 已提交
2034 2035 2036 2037 2038

				uvScaleMap = uvScaleMap.texture;

			}

W
WestLangley 已提交
2039
			if ( uvScaleMap.matrixAutoUpdate === true ) {
M
Mr.doob 已提交
2040

T
Tentone 已提交
2041 2042 2043 2044
				var offset = uvScaleMap.offset;
				var repeat = uvScaleMap.repeat;
				var rotation = uvScaleMap.rotation;
				var center = uvScaleMap.center;
M
Mr.doob 已提交
2045

T
Tentone 已提交
2046
				uvScaleMap.matrix.setUvTransform( offset.x, offset.y, repeat.x, repeat.y, rotation, center.x, center.y );
M
Mr.doob 已提交
2047

W
WestLangley 已提交
2048
			}
2049

2050
			uniforms.uvTransform.value.copy( uvScaleMap.matrix );
M
Mr.doob 已提交
2051 2052 2053

		}

M
Mr.doob 已提交
2054
	}
M
Mr.doob 已提交
2055

M
Mr.doob 已提交
2056
	function refreshUniformsLine( uniforms, material ) {
M
Mr.doob 已提交
2057 2058 2059 2060

		uniforms.diffuse.value = material.color;
		uniforms.opacity.value = material.opacity;

M
Mr.doob 已提交
2061
	}
M
Mr.doob 已提交
2062

M
Mr.doob 已提交
2063
	function refreshUniformsDash( uniforms, material ) {
M
Mr.doob 已提交
2064 2065 2066 2067 2068

		uniforms.dashSize.value = material.dashSize;
		uniforms.totalSize.value = material.dashSize + material.gapSize;
		uniforms.scale.value = material.scale;

M
Mr.doob 已提交
2069
	}
M
Mr.doob 已提交
2070

M
Mr.doob 已提交
2071
	function refreshUniformsPoints( uniforms, material ) {
M
Mr.doob 已提交
2072

2073
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
2074
		uniforms.opacity.value = material.opacity;
2075
		uniforms.size.value = material.size * _pixelRatio;
2076
		uniforms.scale.value = _height * 0.5;
M
Mr.doob 已提交
2077 2078 2079

		uniforms.map.value = material.map;

2080 2081
		if ( material.map !== null ) {

W
WestLangley 已提交
2082
			if ( material.map.matrixAutoUpdate === true ) {
2083

T
Tentone 已提交
2084 2085 2086 2087
				var offset = material.map.offset;
				var repeat = material.map.repeat;
				var rotation = material.map.rotation;
				var center = material.map.center;
2088

T
Tentone 已提交
2089
				material.map.matrix.setUvTransform( offset.x, offset.y, repeat.x, repeat.y, rotation, center.x, center.y );
W
WestLangley 已提交
2090 2091

			}
2092

2093
			uniforms.uvTransform.value.copy( material.map.matrix );
2094 2095 2096

		}

M
Mr.doob 已提交
2097
	}
M
Mr.doob 已提交
2098

M
Mr.doob 已提交
2099
	function refreshUniformsFog( uniforms, fog ) {
M
Mr.doob 已提交
2100 2101 2102

		uniforms.fogColor.value = fog.color;

2103
		if ( fog.isFog ) {
M
Mr.doob 已提交
2104 2105 2106 2107

			uniforms.fogNear.value = fog.near;
			uniforms.fogFar.value = fog.far;

2108
		} else if ( fog.isFogExp2 ) {
M
Mr.doob 已提交
2109 2110 2111 2112 2113

			uniforms.fogDensity.value = fog.density;

		}

M
Mr.doob 已提交
2114
	}
M
Mr.doob 已提交
2115

M
Mr.doob 已提交
2116
	function refreshUniformsLambert( uniforms, material ) {
2117 2118 2119 2120 2121 2122 2123 2124 2125

		if ( material.emissiveMap ) {

			uniforms.emissiveMap.value = material.emissiveMap;

		}

	}

M
Mr.doob 已提交
2126
	function refreshUniformsPhong( uniforms, material ) {
M
Mr.doob 已提交
2127

2128
		uniforms.specular.value = material.specular;
M
Mr.doob 已提交
2129
		uniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 )
M
Mr.doob 已提交
2130

2131
		if ( material.emissiveMap ) {
2132

2133
			uniforms.emissiveMap.value = material.emissiveMap;
2134

2135
		}
M
Mr.doob 已提交
2136

2137 2138 2139 2140
		if ( material.bumpMap ) {

			uniforms.bumpMap.value = material.bumpMap;
			uniforms.bumpScale.value = material.bumpScale;
M
Mr.doob 已提交
2141

2142
		}
M
Mr.doob 已提交
2143

2144 2145 2146 2147 2148 2149
		if ( material.normalMap ) {

			uniforms.normalMap.value = material.normalMap;
			uniforms.normalScale.value.copy( material.normalScale );

		}
M
Mr.doob 已提交
2150

2151 2152 2153 2154 2155
		if ( material.displacementMap ) {

			uniforms.displacementMap.value = material.displacementMap;
			uniforms.displacementScale.value = material.displacementScale;
			uniforms.displacementBias.value = material.displacementBias;
2156

2157
		}
2158

T
Takahiro 已提交
2159 2160 2161 2162 2163 2164
	}

	function refreshUniformsToon( uniforms, material ) {

		refreshUniformsPhong( uniforms, material );

T
Takahiro 已提交
2165
		if ( material.gradientMap ) {
T
Takahiro 已提交
2166

T
Takahiro 已提交
2167
			uniforms.gradientMap.value = material.gradientMap;
T
Takahiro 已提交
2168 2169 2170

		}

2171 2172
	}

M
Mr.doob 已提交
2173
	function refreshUniformsStandard( uniforms, material ) {
W
WestLangley 已提交
2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226

		uniforms.roughness.value = material.roughness;
		uniforms.metalness.value = material.metalness;

		if ( material.roughnessMap ) {

			uniforms.roughnessMap.value = material.roughnessMap;

		}

		if ( material.metalnessMap ) {

			uniforms.metalnessMap.value = material.metalnessMap;

		}

		if ( material.emissiveMap ) {

			uniforms.emissiveMap.value = material.emissiveMap;

		}

		if ( material.bumpMap ) {

			uniforms.bumpMap.value = material.bumpMap;
			uniforms.bumpScale.value = material.bumpScale;

		}

		if ( material.normalMap ) {

			uniforms.normalMap.value = material.normalMap;
			uniforms.normalScale.value.copy( material.normalScale );

		}

		if ( material.displacementMap ) {

			uniforms.displacementMap.value = material.displacementMap;
			uniforms.displacementScale.value = material.displacementScale;
			uniforms.displacementBias.value = material.displacementBias;

		}

		if ( material.envMap ) {

			//uniforms.envMap.value = material.envMap; // part of uniforms common
			uniforms.envMapIntensity.value = material.envMapIntensity;

		}

	}

M
Mr.doob 已提交
2227
	function refreshUniformsPhysical( uniforms, material ) {
W
WestLangley 已提交
2228

2229 2230 2231
		uniforms.clearCoat.value = material.clearCoat;
		uniforms.clearCoatRoughness.value = material.clearCoatRoughness;

W
WestLangley 已提交
2232 2233 2234 2235
		refreshUniformsStandard( uniforms, material );

	}

W
WestLangley 已提交
2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263
	function refreshUniformsDepth( uniforms, material ) {

		if ( material.displacementMap ) {

			uniforms.displacementMap.value = material.displacementMap;
			uniforms.displacementScale.value = material.displacementScale;
			uniforms.displacementBias.value = material.displacementBias;

		}

	}

	function refreshUniformsDistance( uniforms, material ) {

		if ( material.displacementMap ) {

			uniforms.displacementMap.value = material.displacementMap;
			uniforms.displacementScale.value = material.displacementScale;
			uniforms.displacementBias.value = material.displacementBias;

		}

		uniforms.referencePosition.value.copy( material.referencePosition );
		uniforms.nearDistance.value = material.nearDistance;
		uniforms.farDistance.value = material.farDistance;

	}

2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289
	function refreshUniformsNormal( uniforms, material ) {

		if ( material.bumpMap ) {

			uniforms.bumpMap.value = material.bumpMap;
			uniforms.bumpScale.value = material.bumpScale;

		}

		if ( material.normalMap ) {

			uniforms.normalMap.value = material.normalMap;
			uniforms.normalScale.value.copy( material.normalScale );

		}

		if ( material.displacementMap ) {

			uniforms.displacementMap.value = material.displacementMap;
			uniforms.displacementScale.value = material.displacementScale;
			uniforms.displacementBias.value = material.displacementBias;

		}

	}

2290 2291
	// If uniforms are marked as clean, they don't need to be loaded to the GPU.

M
Mr.doob 已提交
2292
	function markUniformsLightsNeedsUpdate( uniforms, value ) {
2293

M
Mr.doob 已提交
2294
		uniforms.ambientLightColor.needsUpdate = value;
2295

B
Ben Houston 已提交
2296 2297 2298
		uniforms.directionalLights.needsUpdate = value;
		uniforms.pointLights.needsUpdate = value;
		uniforms.spotLights.needsUpdate = value;
2299
		uniforms.rectAreaLights.needsUpdate = value;
B
Ben Houston 已提交
2300
		uniforms.hemisphereLights.needsUpdate = value;
2301

M
Mr.doob 已提交
2302
	}
2303

M
Mr.doob 已提交
2304 2305 2306 2307
	// GL state setting

	this.setFaceCulling = function ( cullFace, frontFaceDirection ) {

T
tschw 已提交
2308
		state.setCullFace( cullFace );
R
Rich Harris 已提交
2309
		state.setFlipSided( frontFaceDirection === FrontFaceDirectionCW );
M
Mr.doob 已提交
2310 2311 2312 2313 2314

	};

	// Textures

T
tschw 已提交
2315 2316 2317 2318 2319 2320
	function allocTextureUnit() {

		var textureUnit = _usedTextureUnits;

		if ( textureUnit >= capabilities.maxTextures ) {

M
Mugen87 已提交
2321
			console.warn( 'THREE.WebGLRenderer: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );
T
tschw 已提交
2322 2323 2324 2325 2326 2327 2328 2329 2330

		}

		_usedTextureUnits += 1;

		return textureUnit;

	}

2331
	this.allocTextureUnit = allocTextureUnit;
T
tschw 已提交
2332

2333
	// this.setTexture2D = setTexture2D;
M
Mr.doob 已提交
2334
	this.setTexture2D = ( function () {
T
tschw 已提交
2335

2336
		var warned = false;
T
tschw 已提交
2337

2338
		// backwards compatibility: peel texture.texture
W
WestLangley 已提交
2339
		return function setTexture2D( texture, slot ) {
T
tschw 已提交
2340

T
Takahiro 已提交
2341
			if ( texture && texture.isWebGLRenderTarget ) {
T
tschw 已提交
2342

2343
				if ( ! warned ) {
T
tschw 已提交
2344

2345 2346
					console.warn( "THREE.WebGLRenderer.setTexture2D: don't use render targets as textures. Use their .texture property instead." );
					warned = true;
T
tschw 已提交
2347

2348
				}
T
tschw 已提交
2349

2350
				texture = texture.texture;
T
tschw 已提交
2351

2352
			}
T
tschw 已提交
2353

2354
			textures.setTexture2D( texture, slot );
T
tschw 已提交
2355

2356
		};
T
tschw 已提交
2357

2358
	}() );
T
tschw 已提交
2359

M
Mr.doob 已提交
2360
	this.setTexture = ( function () {
2361 2362 2363

		var warned = false;

W
WestLangley 已提交
2364
		return function setTexture( texture, slot ) {
2365 2366 2367 2368 2369 2370 2371 2372

			if ( ! warned ) {

				console.warn( "THREE.WebGLRenderer: .setTexture is deprecated, use setTexture2D instead." );
				warned = true;

			}

2373
			textures.setTexture2D( texture, slot );
2374 2375 2376 2377 2378

		};

	}() );

M
Mr.doob 已提交
2379
	this.setTextureCube = ( function () {
2380 2381 2382

		var warned = false;

W
WestLangley 已提交
2383
		return function setTextureCube( texture, slot ) {
2384 2385

			// backwards compatibility: peel texture.texture
T
Takahiro 已提交
2386
			if ( texture && texture.isWebGLRenderTargetCube ) {
2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400

				if ( ! warned ) {

					console.warn( "THREE.WebGLRenderer.setTextureCube: don't use cube render targets as textures. Use their .texture property instead." );
					warned = true;

				}

				texture = texture.texture;

			}

			// currently relying on the fact that WebGLRenderTargetCube.texture is a Texture and NOT a CubeTexture
			// TODO: unify these code paths
T
Takahiro 已提交
2401
			if ( ( texture && texture.isCubeTexture ) ||
2402
				( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {
2403 2404 2405 2406

				// CompressedTexture can have Array in image :/

				// this function alone should take care of cube textures
2407
				textures.setTextureCube( texture, slot );
2408 2409 2410 2411 2412

			} else {

				// assumed: texture property of THREE.WebGLRenderTargetCube

2413
				textures.setTextureCubeDynamic( texture, slot );
2414 2415 2416 2417 2418 2419

			}

		};

	}() );
T
tschw 已提交
2420

2421
	this.getRenderTarget = function () {
2422 2423 2424

		return _currentRenderTarget;

M
Michael Herzog 已提交
2425
	};
2426

2427
	this.setRenderTarget = function ( renderTarget ) {
M
Mr.doob 已提交
2428

2429 2430
		_currentRenderTarget = renderTarget;

2431
		if ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) {
M
Mr.doob 已提交
2432

2433
			textures.setupRenderTarget( renderTarget );
M
Mr.doob 已提交
2434 2435 2436

		}

M
Mr.doob 已提交
2437
		var framebuffer = null;
M
Mr.doob 已提交
2438
		var isCube = false;
M
Mr.doob 已提交
2439 2440 2441

		if ( renderTarget ) {

M
Mr.doob 已提交
2442
			var __webglFramebuffer = properties.get( renderTarget ).__webglFramebuffer;
F
Fordy 已提交
2443

M
Mr.doob 已提交
2444
			if ( renderTarget.isWebGLRenderTargetCube ) {
M
Mr.doob 已提交
2445

M
Mr.doob 已提交
2446
				framebuffer = __webglFramebuffer[ renderTarget.activeCubeFace ];
M
Mr.doob 已提交
2447
				isCube = true;
M
Mr.doob 已提交
2448 2449 2450

			} else {

M
Mr.doob 已提交
2451
				framebuffer = __webglFramebuffer;
M
Mr.doob 已提交
2452 2453 2454

			}

M
Mr.doob 已提交
2455
			_currentViewport.copy( renderTarget.viewport );
2456 2457
			_currentScissor.copy( renderTarget.scissor );
			_currentScissorTest = renderTarget.scissorTest;
2458

M
Mr.doob 已提交
2459 2460
		} else {

M
Mr.doob 已提交
2461
			_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );
2462
			_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );
2463
			_currentScissorTest = _scissorTest;
2464

M
Mr.doob 已提交
2465 2466
		}

M
Mr.doob 已提交
2467
		if ( _currentFramebuffer !== framebuffer ) {
M
Mr.doob 已提交
2468 2469 2470 2471 2472 2473

			_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
			_currentFramebuffer = framebuffer;

		}

M
Mr.doob 已提交
2474
		state.viewport( _currentViewport );
2475 2476
		state.scissor( _currentScissor );
		state.setScissorTest( _currentScissorTest );
2477

M
Mr.doob 已提交
2478 2479 2480
		if ( isCube ) {

			var textureProperties = properties.get( renderTarget.texture );
2481
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );
M
Mr.doob 已提交
2482 2483 2484

		}

M
Mr.doob 已提交
2485 2486
	};

M
Mr.doob 已提交
2487
	this.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer ) {
2488

0
06wj 已提交
2489
		if ( ! ( renderTarget && renderTarget.isWebGLRenderTarget ) ) {
2490

2491
			console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
G
gero3 已提交
2492
			return;
2493

G
gero3 已提交
2494
		}
2495

M
Mr.doob 已提交
2496
		var framebuffer = properties.get( renderTarget ).__webglFramebuffer;
2497

M
Mr.doob 已提交
2498
		if ( framebuffer ) {
2499

G
gero3 已提交
2500
			var restore = false;
2501

M
Mr.doob 已提交
2502
			if ( framebuffer !== _currentFramebuffer ) {
2503

M
Mr.doob 已提交
2504
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
2505

G
gero3 已提交
2506
				restore = true;
2507

G
gero3 已提交
2508
			}
2509

M
Mr.doob 已提交
2510
			try {
2511

M
Mr.doob 已提交
2512
				var texture = renderTarget.texture;
M
Mr.doob 已提交
2513 2514
				var textureFormat = texture.format;
				var textureType = texture.type;
2515

2516
				if ( textureFormat !== RGBAFormat && utils.convert( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {
2517

M
Mr.doob 已提交
2518 2519
					console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.' );
					return;
2520

M
Mr.doob 已提交
2521
				}
2522

2523
				if ( textureType !== UnsignedByteType && utils.convert( textureType ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE ) && // IE11, Edge and Chrome Mac < 52 (#9513)
2524 2525
					! ( textureType === FloatType && ( extensions.get( 'OES_texture_float' ) || extensions.get( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox
					! ( textureType === HalfFloatType && extensions.get( 'EXT_color_buffer_half_float' ) ) ) {
2526

M
Mr.doob 已提交
2527 2528
					console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' );
					return;
2529

M
Mr.doob 已提交
2530
				}
2531

M
Mr.doob 已提交
2532
				if ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) {
2533

2534 2535
					// the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604)

2536
					if ( ( x >= 0 && x <= ( renderTarget.width - width ) ) && ( y >= 0 && y <= ( renderTarget.height - height ) ) ) {
2537

2538
						_gl.readPixels( x, y, width, height, utils.convert( textureFormat ), utils.convert( textureType ), buffer );
2539 2540

					}
2541

M
Mr.doob 已提交
2542
				} else {
M
Mr.doob 已提交
2543

M
Mr.doob 已提交
2544 2545 2546
					console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' );

				}
M
Mr.doob 已提交
2547

M
Mr.doob 已提交
2548
			} finally {
M
Mr.doob 已提交
2549

M
Mr.doob 已提交
2550 2551 2552
				if ( restore ) {

					_gl.bindFramebuffer( _gl.FRAMEBUFFER, _currentFramebuffer );
M
Mr.doob 已提交
2553

M
Mr.doob 已提交
2554 2555 2556
				}

			}
M
Mr.doob 已提交
2557 2558 2559

		}

M
Mr.doob 已提交
2560 2561
	};

M
Mr.doob 已提交
2562
}
R
Rich Harris 已提交
2563

T
Tristan VALCKE 已提交
2564

2565
export { WebGLRenderer };