WebGLRenderer.js 62.3 KB
Newer Older
M
Mr.doob 已提交
1 2 3 4 5 6 7 8 9
import {
	REVISION,
	RGBAFormat,
	HalfFloatType,
	FloatType,
	UnsignedByteType,
	TriangleFanDrawMode,
	TriangleStripDrawMode,
	TrianglesDrawMode,
10 11
	LinearToneMapping,
	BackSide
M
Mr.doob 已提交
12
} from '../constants.js';
B
bentok 已提交
13 14
import { _Math } from '../math/Math.js';
import { DataTexture } from '../textures/DataTexture.js';
M
Mr.doob 已提交
15 16 17
import { Frustum } from '../math/Frustum.js';
import { Matrix4 } from '../math/Matrix4.js';
import { ShaderLib } from './shaders/ShaderLib.js';
B
bentok 已提交
18
import { UniformsLib } from './shaders/UniformsLib.js';
M
Mr.doob 已提交
19
import { cloneUniforms } from './shaders/UniformsUtils.js';
20
import { Vector2 } from '../math/Vector2.js';
M
Mr.doob 已提交
21 22
import { Vector3 } from '../math/Vector3.js';
import { Vector4 } from '../math/Vector4.js';
M
Mr.doob 已提交
23
import { WebGLAnimation } from './webgl/WebGLAnimation.js';
B
bentok 已提交
24 25 26
import { WebGLAttributes } from './webgl/WebGLAttributes.js';
import { WebGLBackground } from './webgl/WebGLBackground.js';
import { WebGLBufferRenderer } from './webgl/WebGLBufferRenderer.js';
M
Mr.doob 已提交
27 28 29
import { WebGLCapabilities } from './webgl/WebGLCapabilities.js';
import { WebGLClipping } from './webgl/WebGLClipping.js';
import { WebGLExtensions } from './webgl/WebGLExtensions.js';
B
bentok 已提交
30
import { WebGLGeometries } from './webgl/WebGLGeometries.js';
M
Mr.doob 已提交
31 32 33
import { WebGLIndexedBufferRenderer } from './webgl/WebGLIndexedBufferRenderer.js';
import { WebGLInfo } from './webgl/WebGLInfo.js';
import { WebGLMorphtargets } from './webgl/WebGLMorphtargets.js';
B
bentok 已提交
34 35 36
import { WebGLObjects } from './webgl/WebGLObjects.js';
import { WebGLPrograms } from './webgl/WebGLPrograms.js';
import { WebGLProperties } from './webgl/WebGLProperties.js';
M
Mr.doob 已提交
37 38 39
import { WebGLRenderLists } from './webgl/WebGLRenderLists.js';
import { WebGLRenderStates } from './webgl/WebGLRenderStates.js';
import { WebGLShadowMap } from './webgl/WebGLShadowMap.js';
B
bentok 已提交
40
import { WebGLState } from './webgl/WebGLState.js';
M
Mr.doob 已提交
41 42
import { WebGLTextures } from './webgl/WebGLTextures.js';
import { WebGLUniforms } from './webgl/WebGLUniforms.js';
B
bentok 已提交
43
import { WebGLUtils } from './webgl/WebGLUtils.js';
44
import { WebGLMultiview } from './webgl/WebGLMultiview.js';
M
Mr.doob 已提交
45
import { WebVRManager } from './webvr/WebVRManager.js';
M
Mr.doob 已提交
46
import { WebXRManager } from './webvr/WebXRManager.js';
R
Rich Harris 已提交
47

M
Mr.doob 已提交
48 49 50 51 52
/**
 * @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 已提交
53
 * @author tschw
M
Mr.doob 已提交
54 55
 */

M
Mr.doob 已提交
56
function WebGLRenderer( parameters ) {
M
Mr.doob 已提交
57

M
Mr.doob 已提交
58
	console.log( 'THREE.WebGLRenderer', REVISION );
M
Mr.doob 已提交
59 60 61

	parameters = parameters || {};

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

65
		_multiviewRequested = parameters.multiview !== undefined ? parameters.multiview : false,
66

67 68 69 70 71
		_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,
72
		_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false,
73 74
		_powerPreference = parameters.powerPreference !== undefined ? parameters.powerPreference : 'default',
		_failIfMajorPerformanceCaveat = parameters.failIfMajorPerformanceCaveat !== undefined ? parameters.failIfMajorPerformanceCaveat : false;
M
Mr.doob 已提交
75

76
	var currentRenderList = null;
77
	var currentRenderState = null;
M
Mr.doob 已提交
78

M
Mr.doob 已提交
79 80 81 82
	// public properties

	this.domElement = _canvas;

83 84 85 86 87 88 89
	// Debug configuration container
	this.debug = {

		/**
		 * Enables error checking and reporting when shader programs are being compiled
		 * @type {boolean}
		 */
90
		checkShaderErrors: false
91
	};
92

M
Mr.doob 已提交
93 94 95 96 97 98 99 100 101 102 103
	// clearing

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

	// scene graph

	this.sortObjects = true;

T
tschw 已提交
104 105 106 107 108
	// user-defined clipping

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

M
Mr.doob 已提交
109 110
	// physically based shading

111
	this.gammaFactor = 2.0;	// for backwards compatibility
M
Mr.doob 已提交
112 113 114
	this.gammaInput = false;
	this.gammaOutput = false;

115 116
	// physical lights

117
	this.physicallyCorrectLights = false;
118

B
Ben Houston 已提交
119 120
	// tone mapping

R
Rich Harris 已提交
121
	this.toneMapping = LinearToneMapping;
B
Ben Houston 已提交
122 123 124
	this.toneMappingExposure = 1.0;
	this.toneMappingWhitePoint = 1.0;

M
Mr.doob 已提交
125 126 127 128 129 130 131 132 133
	// morphs

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

	// internal properties

	var _this = this,

134 135
		_isContextLost = false,

136
		// internal state cache
M
Mr.doob 已提交
137

138 139
		_framebuffer = null,

140 141
		_currentActiveCubeFace = 0,
		_currentActiveMipmapLevel = 0,
142 143 144
		_currentRenderTarget = null,
		_currentFramebuffer = null,
		_currentMaterialId = - 1,
145 146 147 148

		// geometry and program caching

		_currentGeometryProgram = {
M
Mr.doob 已提交
149 150
			geometry: null,
			program: null,
151 152
			wireframe: false
		},
153

154
		_currentCamera = null,
155
		_currentArrayCamera = null,
M
Mr.doob 已提交
156

M
Mr.doob 已提交
157
		_currentViewport = new Vector4(),
158 159
		_currentScissor = new Vector4(),
		_currentScissorTest = null,
160

161
		//
162

163 164
		_width = _canvas.width,
		_height = _canvas.height,
M
Mr.doob 已提交
165

166
		_pixelRatio = 1,
M
Mr.doob 已提交
167

M
Mr.doob 已提交
168
		_viewport = new Vector4( 0, 0, _width, _height ),
169 170
		_scissor = new Vector4( 0, 0, _width, _height ),
		_scissorTest = false,
171

172
		// frustum
M
Mr.doob 已提交
173

174
		_frustum = new Frustum(),
M
Mr.doob 已提交
175

176
		// clipping
T
tschw 已提交
177

178 179 180
		_clipping = new WebGLClipping(),
		_clippingEnabled = false,
		_localClippingEnabled = false,
T
tschw 已提交
181

182
		// camera matrices cache
M
Mr.doob 已提交
183

184
		_projScreenMatrix = new Matrix4(),
M
Mr.doob 已提交
185

M
Mugen87 已提交
186
		_vector3 = new Vector3();
A
Atrahasis 已提交
187

188 189 190 191 192
	function getTargetPixelRatio() {

		return _currentRenderTarget === null ? _pixelRatio : 1;

	}
193

M
Mr.doob 已提交
194 195 196 197
	// initialize

	var _gl;

M
Mr.doob 已提交
198 199
	try {

200
		var contextAttributes = {
M
Mr.doob 已提交
201 202 203 204 205
			alpha: _alpha,
			depth: _depth,
			stencil: _stencil,
			antialias: _antialias,
			premultipliedAlpha: _premultipliedAlpha,
206
			preserveDrawingBuffer: _preserveDrawingBuffer,
207
			powerPreference: _powerPreference,
M
Mr.doob 已提交
208
			failIfMajorPerformanceCaveat: _failIfMajorPerformanceCaveat,
209
			xrCompatible: true
M
Mr.doob 已提交
210 211
		};

212 213
		// event listeners must be registered before WebGL context is created, see #12753

214
		_canvas.addEventListener( 'webglcontextlost', onContextLost, false );
215
		_canvas.addEventListener( 'webglcontextrestored', onContextRestore, false );
216

217
		_gl = _context || _canvas.getContext( 'webgl', contextAttributes ) || _canvas.getContext( 'experimental-webgl', contextAttributes );
M
Mr.doob 已提交
218 219 220

		if ( _gl === null ) {

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

D
Daniel Hritzkiv 已提交
223
				throw new Error( 'Error creating WebGL context with your selected attributes.' );
224 225 226

			} else {

D
Daniel Hritzkiv 已提交
227
				throw new Error( 'Error creating WebGL context.' );
228 229

			}
M
Mr.doob 已提交
230 231 232

		}

233 234 235 236 237 238 239 240 241 242 243 244
		// 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 已提交
245 246
	} catch ( error ) {

D
Daniel Hritzkiv 已提交
247
		console.error( 'THREE.WebGLRenderer: ' + error.message );
248
		throw error;
M
Mr.doob 已提交
249 250 251

	}

M
Mugen87 已提交
252
	var extensions, capabilities, state, info;
253
	var properties, textures, attributes, geometries, objects;
254
	var programCache, renderLists, renderStates;
255

256
	var background, morphtargets, bufferRenderer, indexedBufferRenderer;
257

258
	var utils;
259

260
	function initGLContext() {
261

262
		extensions = new WebGLExtensions( _gl );
263

T
Takahiro 已提交
264 265 266
		capabilities = new WebGLCapabilities( _gl, extensions, parameters );

		if ( ! capabilities.isWebGL2 ) {
267 268 269 270 271 272 273 274 275 276 277

			extensions.get( 'WEBGL_depth_texture' );
			extensions.get( 'OES_texture_float' );
			extensions.get( 'OES_texture_half_float' );
			extensions.get( 'OES_texture_half_float_linear' );
			extensions.get( 'OES_standard_derivatives' );
			extensions.get( 'OES_element_index_uint' );
			extensions.get( 'ANGLE_instanced_arrays' );

		}

278
		extensions.get( 'OES_texture_float_linear' );
279

T
Takahiro 已提交
280
		utils = new WebGLUtils( _gl, extensions, capabilities );
M
Mr.doob 已提交
281

T
Takahiro 已提交
282
		state = new WebGLState( _gl, extensions, utils, capabilities );
283 284
		state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ).floor() );
		state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ).floor() );
M
Mr.doob 已提交
285

M
Mugen87 已提交
286
		info = new WebGLInfo( _gl );
287
		properties = new WebGLProperties();
M
Mugen87 已提交
288
		textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info );
289
		attributes = new WebGLAttributes( _gl );
M
Mugen87 已提交
290 291
		geometries = new WebGLGeometries( _gl, attributes, info );
		objects = new WebGLObjects( geometries, info );
292
		morphtargets = new WebGLMorphtargets( _gl );
293
		programCache = new WebGLPrograms( _this, extensions, capabilities );
294
		renderLists = new WebGLRenderLists();
295
		renderStates = new WebGLRenderStates();
M
Mr.doob 已提交
296

297
		background = new WebGLBackground( _this, state, objects, _premultipliedAlpha );
298

T
Takahiro 已提交
299 300
		bufferRenderer = new WebGLBufferRenderer( _gl, extensions, info, capabilities );
		indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, info, capabilities );
301

M
Mugen87 已提交
302
		info.programs = programCache.programs;
303

304 305 306 307 308
		_this.capabilities = capabilities;
		_this.extensions = extensions;
		_this.properties = properties;
		_this.renderLists = renderLists;
		_this.state = state;
M
Mugen87 已提交
309
		_this.info = info;
M
Mr.doob 已提交
310

311
	}
M
Mr.doob 已提交
312

313
	initGLContext();
M
Mr.doob 已提交
314

315
	// vr
M
Mr.doob 已提交
316

317
	var vr = ( typeof navigator !== 'undefined' && 'xr' in navigator && 'supportsSession' in navigator.xr ) ? new WebXRManager( _this, _gl ) : new WebVRManager( _this );
M
Mr.doob 已提交
318

319
	this.vr = vr;
M
Mr.doob 已提交
320

321
	var multiview = this.multiview = new WebGLMultiview( _multiviewRequested, _gl, _canvas, extensions, capabilities );
322

M
Mr.doob 已提交
323
	// shadow map
M
Mr.doob 已提交
324

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

327
	this.shadowMap = shadowMap;
M
Mr.doob 已提交
328

M
Mr.doob 已提交
329 330 331 332 333 334 335 336
	// API

	this.getContext = function () {

		return _gl;

	};

337 338 339 340 341 342
	this.getContextAttributes = function () {

		return _gl.getContextAttributes();

	};

343 344
	this.forceContextLoss = function () {

M
Michael Bond 已提交
345 346
		var extension = extensions.get( 'WEBGL_lose_context' );
		if ( extension ) extension.loseContext();
347 348 349

	};

350
	this.forceContextRestore = function () {
M
Mr.doob 已提交
351

352 353
		var extension = extensions.get( 'WEBGL_lose_context' );
		if ( extension ) extension.restoreContext();
M
Mr.doob 已提交
354 355 356

	};

357 358
	this.getPixelRatio = function () {

359
		return _pixelRatio;
360 361 362 363 364

	};

	this.setPixelRatio = function ( value ) {

365 366 367 368
		if ( value === undefined ) return;

		_pixelRatio = value;

M
Mr.doob 已提交
369
		this.setSize( _width, _height, false );
370 371 372

	};

373
	this.getSize = function ( target ) {
374

375 376 377 378 379 380 381 382 383
		if ( target === undefined ) {

			console.warn( 'WebGLRenderer: .getsize() now requires a Vector2 as an argument' );

			target = new Vector2();

		}

		return target.set( _width, _height );
384 385 386

	};

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

M
Mr.doob 已提交
389
		if ( vr.isPresenting() ) {
390 391 392 393 394 395

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

		}

396 397 398
		_width = width;
		_height = height;

399 400
		_canvas.width = Math.floor( width * _pixelRatio );
		_canvas.height = Math.floor( height * _pixelRatio );
401

402
		if ( updateStyle !== false ) {
403

G
gero3 已提交
404 405
			_canvas.style.width = width + 'px';
			_canvas.style.height = height + 'px';
406

G
gero3 已提交
407
		}
M
Mr.doob 已提交
408

409
		this.setViewport( 0, 0, width, height );
M
Mr.doob 已提交
410 411 412

	};

413
	this.getDrawingBufferSize = function ( target ) {
M
Mr.doob 已提交
414

415 416 417 418 419 420 421 422
		if ( target === undefined ) {

			console.warn( 'WebGLRenderer: .getdrawingBufferSize() now requires a Vector2 as an argument' );

			target = new Vector2();

		}

423
		return target.set( _width * _pixelRatio, _height * _pixelRatio ).floor();
M
Mr.doob 已提交
424 425 426

	};

427 428 429 430 431 432 433
	this.setDrawingBufferSize = function ( width, height, pixelRatio ) {

		_width = width;
		_height = height;

		_pixelRatio = pixelRatio;

434 435
		_canvas.width = Math.floor( width * pixelRatio );
		_canvas.height = Math.floor( height * pixelRatio );
436 437 438 439 440

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

	};

441
	this.getCurrentViewport = function ( target ) {
M
Mugen87 已提交
442

443 444 445 446 447 448 449 450 451
		if ( target === undefined ) {

			console.warn( 'WebGLRenderer: .getCurrentViewport() now requires a Vector4 as an argument' );

			target = new Vector4();

		}

		return target.copy( _currentViewport );
M
Mugen87 已提交
452 453 454

	};

455 456 457
	this.getViewport = function ( target ) {

		return target.copy( _viewport );
M
Mugen87 已提交
458 459 460

	};

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

463 464 465 466 467 468 469 470 471 472
		if ( x.isVector4 ) {

			_viewport.set( x.x, x.y, x.z, x.w );

		} else {

			_viewport.set( x, y, width, height );

		}

473
		state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ).floor() );
474

M
Mr.doob 已提交
475 476
	};

477 478 479 480 481 482
	this.getScissor = function ( target ) {

		return target.copy( _scissor );

	};

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

485 486 487 488 489 490 491 492 493 494
		if ( x.isVector4 ) {

			_scissor.set( x.x, x.y, x.z, x.w );

		} else {

			_scissor.set( x, y, width, height );

		}

495
		state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ).floor() );
496

M
Mr.doob 已提交
497 498
	};

499 500 501 502 503 504
	this.getScissorTest = function () {

		return _scissorTest;

	};

505 506
	this.setScissorTest = function ( boolean ) {

507
		state.setScissorTest( _scissorTest = boolean );
M
Mr.doob 已提交
508 509 510 511 512

	};

	// Clearing

M
Mr.doob 已提交
513
	this.getClearColor = function () {
M
Mr.doob 已提交
514

515
		return background.getClearColor();
M
Mr.doob 已提交
516 517 518

	};

519
	this.setClearColor = function () {
520

521
		background.setClearColor.apply( background, arguments );
M
Mr.doob 已提交
522 523 524

	};

M
Mr.doob 已提交
525
	this.getClearAlpha = function () {
M
Mr.doob 已提交
526

527
		return background.getClearAlpha();
M
Mr.doob 已提交
528 529 530

	};

M
Mugen87 已提交
531
	this.setClearAlpha = function () {
M
Mr.doob 已提交
532

533
		background.setClearAlpha.apply( background, arguments );
M
Mr.doob 已提交
534 535 536 537 538 539 540 541 542 543 544 545

	};

	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 );
546 547 548 549 550

	};

	this.clearColor = function () {

M
Mr.doob 已提交
551
		this.clear( true, false, false );
552 553 554 555 556

	};

	this.clearDepth = function () {

M
Mr.doob 已提交
557
		this.clear( false, true, false );
558 559 560 561 562

	};

	this.clearStencil = function () {

M
Mr.doob 已提交
563
		this.clear( false, false, true );
M
Mr.doob 已提交
564 565 566

	};

M
Mr.doob 已提交
567
	//
M
Mr.doob 已提交
568

M
Mr.doob 已提交
569
	this.dispose = function () {
D
dubejf 已提交
570 571

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

574
		renderLists.dispose();
575
		renderStates.dispose();
M
Mugen87 已提交
576 577
		properties.dispose();
		objects.dispose();
578

579
		vr.dispose();
580

581
		animation.stop();
B
brunnerh 已提交
582

D
dubejf 已提交
583 584
	};

M
Mr.doob 已提交
585
	// Events
M
Mr.doob 已提交
586

D
dubejf 已提交
587 588 589 590
	function onContextLost( event ) {

		event.preventDefault();

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

593 594 595 596
		_isContextLost = true;

	}

M
Mugen87 已提交
597
	function onContextRestore( /* event */ ) {
D
dubejf 已提交
598

599
		console.log( 'THREE.WebGLRenderer: Context Restored.' );
600 601

		_isContextLost = false;
D
dubejf 已提交
602

603
		initGLContext();
D
dubejf 已提交
604

M
Mr.doob 已提交
605
	}
D
dubejf 已提交
606

607
	function onMaterialDispose( event ) {
M
Mr.doob 已提交
608 609 610 611 612 613 614

		var material = event.target;

		material.removeEventListener( 'dispose', onMaterialDispose );

		deallocateMaterial( material );

615
	}
M
Mr.doob 已提交
616 617 618

	// Buffer deallocation

619
	function deallocateMaterial( material ) {
M
Mr.doob 已提交
620

621 622
		releaseMaterialProgramReference( material );

623
		properties.remove( material );
624

625
	}
626 627


628
	function releaseMaterialProgramReference( material ) {
629

630
		var programInfo = properties.get( material ).program;
M
Mr.doob 已提交
631 632 633

		material.program = undefined;

634
		if ( programInfo !== undefined ) {
M
Mr.doob 已提交
635

636
			programCache.releaseProgram( programInfo );
M
Mr.doob 已提交
637

M
Mr.doob 已提交
638 639
		}

640
	}
M
Mr.doob 已提交
641 642 643

	// Buffer rendering

M
Mr.doob 已提交
644
	function renderObjectImmediate( object, program ) {
M
Mr.doob 已提交
645 646 647

		object.render( function ( object ) {

M
Mr.doob 已提交
648
			_this.renderBufferImmediate( object, program );
M
Mr.doob 已提交
649 650 651 652 653

		} );

	}

M
Mugen87 已提交
654
	this.renderBufferImmediate = function ( object, program ) {
M
Mr.doob 已提交
655

656
		state.initAttributes();
657

658
		var buffers = properties.get( object );
659

660 661 662 663
		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 已提交
664

665
		var programAttributes = program.getAttributes();
666

M
Mr.doob 已提交
667 668
		if ( object.hasPositions ) {

669
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );
M
Mr.doob 已提交
670
			_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );
671

672 673
			state.enableAttribute( programAttributes.position );
			_gl.vertexAttribPointer( programAttributes.position, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
674 675 676 677 678

		}

		if ( object.hasNormals ) {

679
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.normal );
M
Mr.doob 已提交
680
			_gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );
681

682 683
			state.enableAttribute( programAttributes.normal );
			_gl.vertexAttribPointer( programAttributes.normal, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
684 685 686

		}

687
		if ( object.hasUvs ) {
M
Mr.doob 已提交
688

689
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );
M
Mr.doob 已提交
690
			_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );
691

692
			state.enableAttribute( programAttributes.uv );
693
			_gl.vertexAttribPointer( programAttributes.uv, 2, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
694 695 696

		}

697
		if ( object.hasColors ) {
M
Mr.doob 已提交
698

699
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );
M
Mr.doob 已提交
700
			_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );
701

702 703
			state.enableAttribute( programAttributes.color );
			_gl.vertexAttribPointer( programAttributes.color, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
704 705 706

		}

707
		state.disableUnusedAttributes();
708

M
Mr.doob 已提交
709 710 711 712 713 714
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );

		object.count = 0;

	};

715
	this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {
716

717
		var frontFaceCW = ( object.isMesh && object.matrixWorld.determinant() < 0 );
718 719

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

M
Mr.doob 已提交
721
		var program = setProgram( camera, fog, material, object );
M
Mr.doob 已提交
722

M
Mr.doob 已提交
723
		var updateBuffers = false;
M
Mr.doob 已提交
724

725 726 727
		if ( _currentGeometryProgram.geometry !== geometry.id ||
			_currentGeometryProgram.program !== program.id ||
			_currentGeometryProgram.wireframe !== ( material.wireframe === true ) ) {
M
Mr.doob 已提交
728

M
Mr.doob 已提交
729 730
			_currentGeometryProgram.geometry = geometry.id;
			_currentGeometryProgram.program = program.id;
731
			_currentGeometryProgram.wireframe = material.wireframe === true;
M
Mr.doob 已提交
732 733 734 735
			updateBuffers = true;

		}

736
		if ( object.morphTargetInfluences ) {
737

738
			morphtargets.update( object, geometry, material, program );
M
Mr.doob 已提交
739 740 741 742 743

			updateBuffers = true;

		}

744 745
		//

746
		var index = geometry.index;
747
		var position = geometry.attributes.position;
748
		var rangeFactor = 1;
749

750 751
		if ( material.wireframe === true ) {

752
			index = geometries.getWireframeAttribute( geometry );
753
			rangeFactor = 2;
754 755 756

		}

M
Mr.doob 已提交
757
		var attribute;
M
Mr.doob 已提交
758
		var renderer = bufferRenderer;
759

760
		if ( index !== null ) {
761

M
Mr.doob 已提交
762
			attribute = attributes.get( index );
763

764
			renderer = indexedBufferRenderer;
M
Mr.doob 已提交
765
			renderer.setIndex( attribute );
766

767
		}
M
Mr.doob 已提交
768

769
		if ( updateBuffers ) {
M
Mr.doob 已提交
770

771
			setupVertexAttributes( material, program, geometry );
M
Mr.doob 已提交
772

773
			if ( index !== null ) {
774

M
Mr.doob 已提交
775
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, attribute.buffer );
776 777 778

			}

779
		}
780

781 782
		//

783
		var dataCount = Infinity;
784

M
Mr.doob 已提交
785
		if ( index !== null ) {
786

M
Mr.doob 已提交
787
			dataCount = index.count;
788

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

M
Mr.doob 已提交
791
			dataCount = position.count;
792

M
Mr.doob 已提交
793
		}
794

M
Mr.doob 已提交
795 796
		var rangeStart = geometry.drawRange.start * rangeFactor;
		var rangeCount = geometry.drawRange.count * rangeFactor;
797

M
Mr.doob 已提交
798 799
		var groupStart = group !== null ? group.start * rangeFactor : 0;
		var groupCount = group !== null ? group.count * rangeFactor : Infinity;
800

M
Mr.doob 已提交
801
		var drawStart = Math.max( rangeStart, groupStart );
802
		var drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1;
M
Mr.doob 已提交
803 804 805

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

806 807
		if ( drawCount === 0 ) return;

M
Mr.doob 已提交
808
		//
809

810
		if ( object.isMesh ) {
811

812
			if ( material.wireframe === true ) {
813

814
				state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );
815
				renderer.setMode( _gl.LINES );
816

817
			} else {
M
Mr.doob 已提交
818 819

				switch ( object.drawMode ) {
820

R
Rich Harris 已提交
821
					case TrianglesDrawMode:
B
Ben Adams 已提交
822 823 824
						renderer.setMode( _gl.TRIANGLES );
						break;

R
Rich Harris 已提交
825
					case TriangleStripDrawMode:
B
Ben Adams 已提交
826 827 828
						renderer.setMode( _gl.TRIANGLE_STRIP );
						break;

R
Rich Harris 已提交
829
					case TriangleFanDrawMode:
B
Ben Adams 已提交
830 831 832 833
						renderer.setMode( _gl.TRIANGLE_FAN );
						break;

				}
834

835
			}
836

837

838
		} else if ( object.isLine ) {
839

840
			var lineWidth = material.linewidth;
841

842
			if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material
843

844
			state.setLineWidth( lineWidth * getTargetPixelRatio() );
845

846
			if ( object.isLineSegments ) {
847

848
				renderer.setMode( _gl.LINES );
849

850 851 852 853
			} else if ( object.isLineLoop ) {

				renderer.setMode( _gl.LINE_LOOP );

854
			} else {
855

856
				renderer.setMode( _gl.LINE_STRIP );
857 858

			}
M
Mr.doob 已提交
859

860
		} else if ( object.isPoints ) {
861 862

			renderer.setMode( _gl.POINTS );
863

864 865 866 867
		} else if ( object.isSprite ) {

			renderer.setMode( _gl.TRIANGLES );

868
		}
869

T
Takahiro 已提交
870
		if ( geometry && geometry.isInstancedBufferGeometry ) {
M
Mr.doob 已提交
871 872 873

			if ( geometry.maxInstancedCount > 0 ) {

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

J
jfranc 已提交
876
			}
877 878 879

		} else {

M
Mr.doob 已提交
880
			renderer.render( drawStart, drawCount );
881

M
Mr.doob 已提交
882 883 884 885
		}

	};

886
	function setupVertexAttributes( material, program, geometry ) {
M
Mr.doob 已提交
887

A
Alex Goldring 已提交
888
		if ( geometry && geometry.isInstancedBufferGeometry && ! capabilities.isWebGL2 ) {
B
Ben Adams 已提交
889

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

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

M
Mr.doob 已提交
895 896 897
			}

		}
B
Ben Adams 已提交
898

899 900
		state.initAttributes();

901
		var geometryAttributes = geometry.attributes;
902

903
		var programAttributes = program.getAttributes();
904

905
		var materialDefaultAttributeValues = material.defaultAttributeValues;
906

907
		for ( var name in programAttributes ) {
908

909
			var programAttribute = programAttributes[ name ];
M
Mr.doob 已提交
910

M
Mr.doob 已提交
911
			if ( programAttribute >= 0 ) {
M
Mr.doob 已提交
912

913
				var geometryAttribute = geometryAttributes[ name ];
914

M
Mr.doob 已提交
915
				if ( geometryAttribute !== undefined ) {
M
Mr.doob 已提交
916

917
					var normalized = geometryAttribute.normalized;
918
					var size = geometryAttribute.itemSize;
919

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

922 923 924 925
					// TODO Attribute may not be available on context restore

					if ( attribute === undefined ) continue;

M
Mr.doob 已提交
926 927 928
					var buffer = attribute.buffer;
					var type = attribute.type;
					var bytesPerElement = attribute.bytesPerElement;
929

A
aardgoose 已提交
930
					if ( geometryAttribute.isInterleavedBufferAttribute ) {
931

M
Mr.doob 已提交
932 933 934 935
						var data = geometryAttribute.data;
						var stride = data.stride;
						var offset = geometryAttribute.offset;

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

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

M
Mr.doob 已提交
940
							if ( geometry.maxInstancedCount === undefined ) {
941

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

M
Mr.doob 已提交
944
							}
B
Ben Adams 已提交
945

M
Mr.doob 已提交
946
						} else {
B
Ben Adams 已提交
947

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

M
Mr.doob 已提交
950
						}
B
Ben Adams 已提交
951

M
Mr.doob 已提交
952
						_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
953
						_gl.vertexAttribPointer( programAttribute, size, type, normalized, stride * bytesPerElement, offset * bytesPerElement );
B
Ben Adams 已提交
954

M
Mr.doob 已提交
955
					} else {
B
Ben Adams 已提交
956

A
aardgoose 已提交
957
						if ( geometryAttribute.isInstancedBufferAttribute ) {
B
Ben Adams 已提交
958

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

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

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

M
Mr.doob 已提交
965
							}
B
Ben Adams 已提交
966

M
Mr.doob 已提交
967 968 969 970
						} else {

							state.enableAttribute( programAttribute );

M
Mr.doob 已提交
971
						}
B
Ben Adams 已提交
972

M
Mr.doob 已提交
973
						_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
974
						_gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, 0 );
M
Mr.doob 已提交
975

B
Ben Adams 已提交
976
					}
M
Mr.doob 已提交
977

978 979
				} else if ( materialDefaultAttributeValues !== undefined ) {

T
tschw 已提交
980
					var value = materialDefaultAttributeValues[ name ];
981

982
					if ( value !== undefined ) {
M
Mr.doob 已提交
983

984
						switch ( value.length ) {
M
Mr.doob 已提交
985

986 987 988
							case 2:
								_gl.vertexAttrib2fv( programAttribute, value );
								break;
M
Mr.doob 已提交
989

990 991 992
							case 3:
								_gl.vertexAttrib3fv( programAttribute, value );
								break;
M
Mr.doob 已提交
993

994 995 996
							case 4:
								_gl.vertexAttrib4fv( programAttribute, value );
								break;
997

998 999
							default:
								_gl.vertexAttrib1fv( programAttribute, value );
1000 1001

						}
M
Mr.doob 已提交
1002 1003 1004 1005 1006 1007 1008 1009

					}

				}

			}

		}
1010

1011
		state.disableUnusedAttributes();
1012

M
Mr.doob 已提交
1013 1014
	}

M
Mr.doob 已提交
1015
	// Compile
M
Mr.doob 已提交
1016

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

M
Mr.doob 已提交
1019
		currentRenderState = renderStates.get( scene, camera );
1020
		currentRenderState.init();
1021

M
Mr.doob 已提交
1022
		scene.traverse( function ( object ) {
G
gero3 已提交
1023 1024

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

1026
				currentRenderState.pushLight( object );
1027 1028 1029

				if ( object.castShadow ) {

1030
					currentRenderState.pushShadow( object );
1031 1032

				}
M
Mr.doob 已提交
1033

G
gero3 已提交
1034
			}
M
Mr.doob 已提交
1035 1036 1037

		} );

1038
		currentRenderState.setupLights( camera );
M
Mr.doob 已提交
1039 1040 1041 1042 1043

		scene.traverse( function ( object ) {

			if ( object.material ) {

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

G
gero3 已提交
1046
					for ( var i = 0; i < object.material.length; i ++ ) {
M
Mr.doob 已提交
1047 1048 1049

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

G
gero3 已提交
1050
					}
M
Mr.doob 已提交
1051

G
gero3 已提交
1052
				} else {
M
Mr.doob 已提交
1053 1054 1055

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

G
gero3 已提交
1056
				}
M
Mr.doob 已提交
1057

G
gero3 已提交
1058
			}
M
Mr.doob 已提交
1059 1060

		} );
G
gero3 已提交
1061 1062

	};
1063

1064
	// Animation Loop
M
Mr.doob 已提交
1065

M
Mr.doob 已提交
1066
	var onAnimationFrameCallback = null;
1067

1068
	function onAnimationFrame( time ) {
1069

M
Mr.doob 已提交
1070
		if ( vr.isPresenting() ) return;
1071
		if ( onAnimationFrameCallback ) onAnimationFrameCallback( time );
1072

1073
	}
1074

M
Mr.doob 已提交
1075 1076
	var animation = new WebGLAnimation();
	animation.setAnimationLoop( onAnimationFrame );
1077 1078

	if ( typeof window !== 'undefined' ) animation.setContext( window );
1079

1080
	this.setAnimationLoop = function ( callback ) {
1081

M
Mr.doob 已提交
1082 1083
		onAnimationFrameCallback = callback;
		vr.setAnimationLoop( callback );
1084

1085 1086
		animation.start();

1087 1088
	};

M
Mr.doob 已提交
1089 1090
	// Rendering

1091 1092
	this.render = function ( scene, camera ) {

M
Mr.doob 已提交
1093
		var renderTarget, forceClear;
1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107

		if ( arguments[ 2 ] !== undefined ) {

			console.warn( 'THREE.WebGLRenderer.render(): the renderTarget argument has been removed. Use .setRenderTarget() instead.' );
			renderTarget = arguments[ 2 ];

		}

		if ( arguments[ 3 ] !== undefined ) {

			console.warn( 'THREE.WebGLRenderer.render(): the forceClear argument has been removed. Use .clear() instead.' );
			forceClear = arguments[ 3 ];

		}
1108

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

1111
			console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );
M
Mr.doob 已提交
1112 1113 1114 1115
			return;

		}

1116 1117
		if ( _isContextLost ) return;

M
Mr.doob 已提交
1118 1119
		// reset caching for this frame

M
Mr.doob 已提交
1120 1121
		_currentGeometryProgram.geometry = null;
		_currentGeometryProgram.program = null;
1122
		_currentGeometryProgram.wireframe = false;
1123
		_currentMaterialId = - 1;
1124
		_currentCamera = null;
M
Mr.doob 已提交
1125 1126 1127

		// update scene graph

1128
		if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
M
Mr.doob 已提交
1129 1130 1131

		// update camera matrices and frustum

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

1134 1135 1136 1137 1138 1139
		if ( vr.enabled ) {

			camera = vr.getCamera( camera );

		}

1140 1141
		//

1142 1143
		currentRenderState = renderStates.get( scene, camera );
		currentRenderState.init();
1144

M
Marc-Sefan Cassola 已提交
1145
		scene.onBeforeRender( _this, scene, camera, renderTarget || _currentRenderTarget );
1146

M
Mr.doob 已提交
1147 1148 1149
		_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
		_frustum.setFromMatrix( _projScreenMatrix );

T
tschw 已提交
1150
		_localClippingEnabled = this.localClippingEnabled;
M
Mr.doob 已提交
1151
		_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );
T
tschw 已提交
1152

1153 1154 1155
		currentRenderList = renderLists.get( scene, camera );
		currentRenderList.init();

1156
		projectObject( scene, camera, 0, _this.sortObjects );
M
Mr.doob 已提交
1157

M
Mr.doob 已提交
1158
		if ( _this.sortObjects === true ) {
1159

1160
			currentRenderList.sort();
M
Mr.doob 已提交
1161

1162 1163
		}

M
Mr.doob 已提交
1164
		//
M
Mr.doob 已提交
1165

T
tschw 已提交
1166
		if ( _clippingEnabled ) _clipping.beginShadows();
T
tschw 已提交
1167

1168
		var shadowsArray = currentRenderState.state.shadowsArray;
1169

1170
		shadowMap.render( shadowsArray, scene, camera );
1171

1172
		currentRenderState.setupLights( camera );
1173

T
tschw 已提交
1174
		if ( _clippingEnabled ) _clipping.endShadows();
T
tschw 已提交
1175

M
Mr.doob 已提交
1176 1177
		//

A
Atrahasis 已提交
1178
		if ( this.info.autoReset ) this.info.reset();
M
Mr.doob 已提交
1179

1180
		if ( renderTarget !== undefined ) {
1181

1182
			this.setRenderTarget( renderTarget );
1183 1184 1185

		}

M
Mr.doob 已提交
1186 1187
		//

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

1190
		// render scene
M
Mr.doob 已提交
1191

1192 1193 1194
		var opaqueObjects = currentRenderList.opaque;
		var transparentObjects = currentRenderList.transparent;

M
Mr.doob 已提交
1195 1196
		if ( scene.overrideMaterial ) {

1197
			var overrideMaterial = scene.overrideMaterial;
M
Mr.doob 已提交
1198

M
Mr.doob 已提交
1199 1200
			if ( opaqueObjects.length ) renderObjects( opaqueObjects, scene, camera, overrideMaterial );
			if ( transparentObjects.length ) renderObjects( transparentObjects, scene, camera, overrideMaterial );
1201

M
Mr.doob 已提交
1202 1203
		} else {

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

M
Mr.doob 已提交
1206
			if ( opaqueObjects.length ) renderObjects( opaqueObjects, scene, camera );
1207 1208 1209

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

M
Mr.doob 已提交
1210
			if ( transparentObjects.length ) renderObjects( transparentObjects, scene, camera );
M
Mr.doob 已提交
1211

1212
		}
M
Mr.doob 已提交
1213

1214
		//
M
Mr.doob 已提交
1215

1216 1217 1218 1219
		scene.onAfterRender( _this, scene, camera );

		//

M
Marc-Sefan Cassola 已提交
1220
		if ( _currentRenderTarget !== null ) {
M
Mr.doob 已提交
1221

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

1224
			textures.updateRenderTargetMipmap( _currentRenderTarget );
M
Mr.doob 已提交
1225

M
Mugen87 已提交
1226
			// resolve multisample renderbuffers to a single-sample texture if necessary
1227

1228
			textures.updateMultisampleRenderTarget( _currentRenderTarget );
1229

M
Mr.doob 已提交
1230 1231
		}

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

1234 1235 1236
		state.buffers.depth.setTest( true );
		state.buffers.depth.setMask( true );
		state.buffers.color.setMask( true );
M
Mr.doob 已提交
1237

1238
		state.setPolygonOffset( false );
1239

M
Mr.doob 已提交
1240
		if ( vr.enabled ) {
1241

1242
			vr.submitFrame();
1243

M
Mr.doob 已提交
1244
		}
M
Mr.doob 已提交
1245

M
Mr.doob 已提交
1246 1247
		// _gl.finish();

1248
		currentRenderList = null;
1249
		currentRenderState = null;
1250

M
Mr.doob 已提交
1251
	};
M
Mr.doob 已提交
1252

1253
	function projectObject( object, camera, groupOrder, sortObjects ) {
M
Mr.doob 已提交
1254

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

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

1259
		if ( visible ) {
1260

1261 1262 1263 1264
			if ( object.isGroup ) {

				groupOrder = object.renderOrder;

T
Takahiro 已提交
1265 1266
			} else if ( object.isLOD ) {

1267
				if ( object.autoUpdate === true ) object.update( camera );
T
Takahiro 已提交
1268

1269
			} else if ( object.isLight ) {
M
Mr.doob 已提交
1270

1271
				currentRenderState.pushLight( object );
1272 1273 1274

				if ( object.castShadow ) {

1275
					currentRenderState.pushShadow( object );
1276 1277

				}
M
Mr.doob 已提交
1278

1279
			} else if ( object.isSprite ) {
M
Mr.doob 已提交
1280

1281
				if ( ! object.frustumCulled || _frustum.intersectsSprite( object ) ) {
1282

1283 1284 1285 1286 1287 1288 1289 1290 1291 1292
					if ( sortObjects ) {

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

					}

					var geometry = objects.update( object );
					var material = object.material;

1293 1294 1295 1296 1297
					if ( material.visible ) {

						currentRenderList.push( object, geometry, material, groupOrder, _vector3.z, null );

					}
M
Mr.doob 已提交
1298

1299
				}
M
Mr.doob 已提交
1300

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

1303
				if ( sortObjects ) {
M
Mr.doob 已提交
1304

1305 1306
					_vector3.setFromMatrixPosition( object.matrixWorld )
						.applyMatrix4( _projScreenMatrix );
M
Mr.doob 已提交
1307

1308
				}
M
Mr.doob 已提交
1309

1310
				currentRenderList.push( object, null, object.material, groupOrder, _vector3.z, null );
1311

1312
			} else if ( object.isMesh || object.isLine || object.isPoints ) {
1313

1314
				if ( object.isSkinnedMesh ) {
1315

1316
					object.skeleton.update();
1317

1318
				}
1319

1320
				if ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) {
1321

1322 1323 1324 1325 1326 1327
					if ( sortObjects ) {

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

					}
1328

1329 1330
					var geometry = objects.update( object );
					var material = object.material;
1331

1332
					if ( Array.isArray( material ) ) {
1333

1334
						var groups = geometry.groups;
1335

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

1338 1339
							var group = groups[ i ];
							var groupMaterial = material[ group.materialIndex ];
1340

1341
							if ( groupMaterial && groupMaterial.visible ) {
1342

1343
								currentRenderList.push( object, geometry, groupMaterial, groupOrder, _vector3.z, group );
1344 1345

							}
M
Mr.doob 已提交
1346

M
Mr.doob 已提交
1347
						}
M
Mr.doob 已提交
1348

1349
					} else if ( material.visible ) {
1350

1351
						currentRenderList.push( object, geometry, material, groupOrder, _vector3.z, null );
O
OpenShift guest 已提交
1352

1353
					}
M
Mr.doob 已提交
1354

1355
				}
M
Mr.doob 已提交
1356

1357
			}
M
Mr.doob 已提交
1358

M
Mr.doob 已提交
1359
		}
M
Mr.doob 已提交
1360

M
Mr.doob 已提交
1361
		var children = object.children;
M
Mr.doob 已提交
1362

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

1365
			projectObject( children[ i ], camera, groupOrder, sortObjects );
M
Mr.doob 已提交
1366

1367
		}
1368

1369
	}
M
Mr.doob 已提交
1370

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

1373
		if ( multiview.isEnabled() ) {
1374

1375
			multiview.bindMultiviewFrameBuffer( camera );
1376 1377 1378

			_gl.disable( _gl.SCISSOR_TEST );

1379 1380 1381 1382
			if ( camera.isArrayCamera ) {

				var height = _canvas.height;
				var width = Math.floor( _canvas.width * 0.5 );
1383

1384 1385 1386 1387
			} else {

				var width = _canvas.width;
				var height = _canvas.height;
1388

1389 1390
			}
			_gl.viewport( 0, 0, width, height );
1391 1392 1393 1394

			_gl.clear( _gl.COLOR_BUFFER_BIT | _gl.DEPTH_BUFFER_BIT | _gl.STENCIL_BUFFER_BIT );

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

1396
				var renderItem = renderList[ i ];
M
Mr.doob 已提交
1397

1398 1399 1400 1401
				var object = renderItem.object;
				var geometry = renderItem.geometry;
				var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;
				var group = renderItem.group;
M
Mr.doob 已提交
1402

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

1405 1406
			}

1407
			multiview.unbindMultiviewFrameBuffer( camera );
1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420

		} else {

			for ( var i = 0, l = renderList.length; i < l; i ++ ) {

				var renderItem = renderList[ i ];

				var object = renderItem.object;
				var geometry = renderItem.geometry;
				var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;
				var group = renderItem.group;

				if ( camera.isArrayCamera ) {
1421

1422
					_currentArrayCamera = camera;
M
Mr.doob 已提交
1423

1424
					var cameras = camera.cameras;
M
Mr.doob 已提交
1425

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

1428
						var camera2 = cameras[ j ];
1429

1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447
						if ( object.layers.test( camera2.layers ) ) {

							if ( 'viewport' in camera2 ) { // XR

								state.viewport( _currentViewport.copy( camera2.viewport ) );

							} else {

								var bounds = camera2.bounds;

								var x = bounds.x * _width;
								var y = bounds.y * _height;
								var width = bounds.z * _width;
								var height = bounds.w * _height;

								state.viewport( _currentViewport.set( x, y, width, height ).multiplyScalar( _pixelRatio ) );

							}
1448

1449
							currentRenderState.setupLights( camera2 );
1450

1451 1452 1453
							renderObject( object, scene, camera2, geometry, material, group );

						}
1454 1455

					}
M
Mr.doob 已提交
1456

1457
				} else {
1458

1459
					_currentArrayCamera = null;
M
Mr.doob 已提交
1460

1461
					renderObject( object, scene, camera, geometry, material, group );
1462

1463
				}
M
Mr.doob 已提交
1464

M
Mr.doob 已提交
1465
			}
M
Mr.doob 已提交
1466

1467
		}
M
Mr.doob 已提交
1468

1469
	}
G
gero3 已提交
1470

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

M
Mugen87 已提交
1473
		object.onBeforeRender( _this, scene, camera, geometry, material, group );
1474
		currentRenderState = renderStates.get( scene, _currentArrayCamera || camera );
1475

M
Mr.doob 已提交
1476 1477 1478 1479 1480
		object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
		object.normalMatrix.getNormalMatrix( object.modelViewMatrix );

		if ( object.isImmediateRenderObject ) {

1481
			state.setMaterial( material );
M
Mr.doob 已提交
1482 1483 1484

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

M
Mr.doob 已提交
1485 1486
			_currentGeometryProgram.geometry = null;
			_currentGeometryProgram.program = null;
1487
			_currentGeometryProgram.wireframe = false;
M
Mr.doob 已提交
1488

M
Mr.doob 已提交
1489
			renderObjectImmediate( object, program );
M
Mr.doob 已提交
1490 1491 1492

		} else {

M
Mugen87 已提交
1493
			_this.renderBufferDirect( camera, scene.fog, geometry, material, object, group );
M
Mr.doob 已提交
1494 1495 1496

		}

M
Mr.doob 已提交
1497
		object.onAfterRender( _this, scene, camera, geometry, material, group );
1498
		currentRenderState = renderStates.get( scene, _currentArrayCamera || camera );
M
Mr.doob 已提交
1499

M
Mr.doob 已提交
1500 1501
	}

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

1504
		var materialProperties = properties.get( material );
G
gero3 已提交
1505

1506 1507
		var lights = currentRenderState.state.lights;
		var shadowsArray = currentRenderState.state.shadowsArray;
1508

A
aardgoose 已提交
1509
		var lightsStateVersion = lights.state.version;
M
Mr.doob 已提交
1510

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

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

1516
		var program = materialProperties.program;
T
tschw 已提交
1517
		var programChange = true;
1518

1519
		if ( program === undefined ) {
B
Ben Adams 已提交
1520

M
Mr.doob 已提交
1521 1522
			// new material
			material.addEventListener( 'dispose', onMaterialDispose );
B
Ben Adams 已提交
1523

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

M
Mr.doob 已提交
1526
			// changed glsl or parameters
1527
			releaseMaterialProgramReference( material );
B
Ben Adams 已提交
1528

A
aardgoose 已提交
1529
		} else if ( materialProperties.lightsStateVersion !== lightsStateVersion ) {
M
Mr.doob 已提交
1530

A
aardgoose 已提交
1531
			materialProperties.lightsStateVersion = lightsStateVersion;
1532 1533 1534

			programChange = false;

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

T
tschw 已提交
1537
			// same glsl and uniform list
T
tschw 已提交
1538 1539
			return;

T
tschw 已提交
1540
		} else {
B
Ben Adams 已提交
1541

T
tschw 已提交
1542 1543
			// only rebuild uniform list
			programChange = false;
B
Ben Adams 已提交
1544 1545 1546

		}

1547
		if ( programChange ) {
B
Ben Adams 已提交
1548

1549
			if ( parameters.shaderID ) {
B
Ben Adams 已提交
1550

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

1553
				materialProperties.shader = {
1554
					name: material.type,
M
Mr.doob 已提交
1555
					uniforms: cloneUniforms( shader.uniforms ),
1556
					vertexShader: shader.vertexShader,
1557
					fragmentShader: shader.fragmentShader
1558
				};
B
Ben Adams 已提交
1559

1560
			} else {
B
Ben Adams 已提交
1561

1562
				materialProperties.shader = {
1563 1564 1565
					name: material.type,
					uniforms: material.uniforms,
					vertexShader: material.vertexShader,
1566
					fragmentShader: material.fragmentShader
1567
				};
G
gero3 已提交
1568

1569
			}
G
gero3 已提交
1570

1571
			material.onBeforeCompile( materialProperties.shader, _this );
G
gero3 已提交
1572

1573
			// Computing code again as onBeforeCompile may have changed the shaders
1574 1575
			code = programCache.getProgramCode( material, parameters );

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

1578 1579
			materialProperties.program = program;
			material.program = program;
1580 1581 1582

		}

1583
		var programAttributes = program.getAttributes();
M
Mr.doob 已提交
1584 1585 1586 1587 1588

		if ( material.morphTargets ) {

			material.numSupportedMorphTargets = 0;

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

1591
				if ( programAttributes[ 'morphTarget' + i ] >= 0 ) {
M
Mr.doob 已提交
1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604

					material.numSupportedMorphTargets ++;

				}

			}

		}

		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

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

1607
				if ( programAttributes[ 'morphNormal' + i ] >= 0 ) {
M
Mr.doob 已提交
1608 1609 1610 1611 1612 1613 1614 1615 1616

					material.numSupportedMorphNormals ++;

				}

			}

		}

1617
		var uniforms = materialProperties.shader.uniforms;
T
tschw 已提交
1618

1619
		if ( ! material.isShaderMaterial &&
1620 1621
			! material.isRawShaderMaterial ||
			material.clipping === true ) {
T
tschw 已提交
1622

T
tschw 已提交
1623
			materialProperties.numClippingPlanes = _clipping.numPlanes;
1624
			materialProperties.numIntersection = _clipping.numIntersection;
T
tschw 已提交
1625
			uniforms.clippingPlanes = _clipping.uniform;
T
tschw 已提交
1626 1627 1628

		}

1629
		materialProperties.fog = fog;
1630

1631
		// store the light setup it was created for
1632

A
aardgoose 已提交
1633
		materialProperties.lightsStateVersion = lightsStateVersion;
1634

M
Mr.doob 已提交
1635
		if ( material.lights ) {
1636 1637 1638

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

1639
			uniforms.ambientLightColor.value = lights.state.ambient;
W
WestLangley 已提交
1640
			uniforms.lightProbe.value = lights.state.probe;
1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652
			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;
1653
			// TODO (abelnation): add area lights shadow info to uniforms
1654

1655 1656
		}

T
tschw 已提交
1657 1658
		var progUniforms = materialProperties.program.getUniforms(),
			uniformsList =
1659
				WebGLUniforms.seqWithValue( progUniforms.seq, uniforms );
A
arose 已提交
1660

T
tschw 已提交
1661
		materialProperties.uniformsList = uniformsList;
A
arose 已提交
1662

M
Mr.doob 已提交
1663
	}
M
Mr.doob 已提交
1664

1665
	function setProgram( camera, fog, material, object ) {
M
Mr.doob 已提交
1666

1667
		textures.resetTextureUnits();
M
Mr.doob 已提交
1668

1669
		var materialProperties = properties.get( material );
1670
		var lights = currentRenderState.state.lights;
1671

T
tschw 已提交
1672 1673 1674 1675 1676
		if ( _clippingEnabled ) {

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

				var useCache =
1677 1678
					camera === _currentCamera &&
					material.id === _currentMaterialId;
T
tschw 已提交
1679 1680 1681 1682

				// we might want to call this function with some ClippingGroup
				// object instead of the material, once it becomes feasible
				// (#8465, #8379)
T
tschw 已提交
1683
				_clipping.setState(
1684 1685
					material.clippingPlanes, material.clipIntersection, material.clipShadows,
					camera, materialProperties, useCache );
T
tschw 已提交
1686 1687 1688 1689 1690

			}

		}

1691
		if ( material.needsUpdate === false ) {
1692

1693
			if ( materialProperties.program === undefined ) {
1694

1695
				material.needsUpdate = true;
1696

1697
			} else if ( material.fog && materialProperties.fog !== fog ) {
1698

M
Mr.doob 已提交
1699
				material.needsUpdate = true;
1700

A
aardgoose 已提交
1701
			} else if ( material.lights && materialProperties.lightsStateVersion !== lights.state.version ) {
1702

1703
				material.needsUpdate = true;
1704

1705
			} else if ( materialProperties.numClippingPlanes !== undefined &&
1706
				( materialProperties.numClippingPlanes !== _clipping.numPlanes ||
M
Mr.doob 已提交
1707
				materialProperties.numIntersection !== _clipping.numIntersection ) ) {
1708 1709 1710

				material.needsUpdate = true;

1711
			}
1712 1713 1714 1715

		}

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

1717
			initMaterial( material, fog, object );
M
Mr.doob 已提交
1718 1719 1720 1721
			material.needsUpdate = false;

		}

1722
		var refreshProgram = false;
M
Mr.doob 已提交
1723
		var refreshMaterial = false;
1724
		var refreshLights = false;
M
Mr.doob 已提交
1725

1726
		var program = materialProperties.program,
1727
			p_uniforms = program.getUniforms(),
1728
			m_uniforms = materialProperties.shader.uniforms;
M
Mr.doob 已提交
1729

1730
		if ( state.useProgram( program.program ) ) {
M
Mr.doob 已提交
1731

1732
			refreshProgram = true;
M
Mr.doob 已提交
1733
			refreshMaterial = true;
1734
			refreshLights = true;
M
Mr.doob 已提交
1735 1736 1737 1738 1739 1740

		}

		if ( material.id !== _currentMaterialId ) {

			_currentMaterialId = material.id;
1741

M
Mr.doob 已提交
1742 1743 1744 1745
			refreshMaterial = true;

		}

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

1748
			if ( multiview.isEnabled() ) {
1749

1750
				if ( camera.isArrayCamera ) {
1751 1752 1753 1754 1755 1756 1757 1758

					// @todo Obviously remove the map :)
					p_uniforms.setValue( _gl, 'projectionMatrices', camera.cameras.map( c => c.projectionMatrix ) );

				} else {

					p_uniforms.setValue( _gl, 'projectionMatrices', [ camera.projectionMatrix, camera.projectionMatrix ] );

1759
				}
1760 1761 1762 1763 1764 1765

			} else {

				p_uniforms.setValue( _gl, 'projectionMatrix', camera.projectionMatrix );

			}
M
Mr.doob 已提交
1766

G
gero3 已提交
1767
			if ( capabilities.logarithmicDepthBuffer ) {
1768

T
tschw 已提交
1769
				p_uniforms.setValue( _gl, 'logDepthBufFC',
1770
					2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
1771 1772 1773

			}

1774
			if ( _currentCamera !== camera ) {
1775

1776
				_currentCamera = camera;
1777 1778 1779 1780 1781 1782

				// 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 已提交
1783
				refreshLights = true;		// remains set until update done
1784 1785

			}
M
Mr.doob 已提交
1786

1787 1788 1789
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)

1790
			if ( material.isShaderMaterial ||
1791 1792 1793
				material.isMeshPhongMaterial ||
				material.isMeshStandardMaterial ||
				material.envMap ) {
1794

T
tschw 已提交
1795 1796 1797
				var uCamPos = p_uniforms.map.cameraPosition;

				if ( uCamPos !== undefined ) {
1798

T
tschw 已提交
1799
					uCamPos.setValue( _gl,
1800
						_vector3.setFromMatrixPosition( camera.matrixWorld ) );
1801 1802 1803 1804 1805

				}

			}

1806
			if ( material.isMeshPhongMaterial ||
1807 1808 1809 1810
				material.isMeshLambertMaterial ||
				material.isMeshBasicMaterial ||
				material.isMeshStandardMaterial ||
				material.isShaderMaterial ||
1811
				material.skinning ) {
1812

1813
				if ( multiview.isEnabled() ) {
1814

1815
					if ( camera.isArrayCamera ) {
1816 1817 1818 1819 1820 1821

						// @todo Obviously remove the map :)
						p_uniforms.setValue( _gl, 'viewMatrix', camera.cameras.map( c => c.matrixWorldInverse ) );

					} else {

1822
						p_uniforms.setValue( _gl, 'viewMatrices', [ camera.matrixWorldInverse, camera.matrixWorldInverse ] );
1823 1824 1825 1826 1827 1828 1829 1830

					}

				} else {

					p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );

				}
1831 1832 1833

			}

M
Mr.doob 已提交
1834 1835 1836 1837 1838 1839
		}

		// 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

1840
		if ( material.skinning ) {
M
Mr.doob 已提交
1841

T
tschw 已提交
1842 1843
			p_uniforms.setOptional( _gl, object, 'bindMatrix' );
			p_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );
1844

T
tschw 已提交
1845
			var skeleton = object.skeleton;
1846

T
tschw 已提交
1847
			if ( skeleton ) {
1848

1849 1850
				var bones = skeleton.bones;

1851
				if ( capabilities.floatVertexTextures ) {
M
Mr.doob 已提交
1852

1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863
					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
1864
						size = _Math.ceilPowerOfTwo( size );
1865 1866 1867 1868 1869 1870
						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 );
1871
						boneTexture.needsUpdate = true;
1872 1873 1874 1875 1876 1877 1878

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

					}

1879
					p_uniforms.setValue( _gl, 'boneTexture', skeleton.boneTexture, textures );
M
Mr.doob 已提交
1880
					p_uniforms.setValue( _gl, 'boneTextureSize', skeleton.boneTextureSize );
M
Mr.doob 已提交
1881

T
tschw 已提交
1882
				} else {
M
Mr.doob 已提交
1883

T
tschw 已提交
1884
					p_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );
M
Mr.doob 已提交
1885 1886 1887 1888 1889 1890 1891 1892 1893

				}

			}

		}

		if ( refreshMaterial ) {

1894 1895 1896
			p_uniforms.setValue( _gl, 'toneMappingExposure', _this.toneMappingExposure );
			p_uniforms.setValue( _gl, 'toneMappingWhitePoint', _this.toneMappingWhitePoint );

M
Mr.doob 已提交
1897
			if ( material.lights ) {
M
Mr.doob 已提交
1898

1899
				// the current material requires lighting info
M
Mr.doob 已提交
1900

T
tschw 已提交
1901 1902 1903 1904 1905 1906
				// 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 已提交
1907

T
tschw 已提交
1908
				markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
G
gero3 已提交
1909

T
tschw 已提交
1910
			}
G
gero3 已提交
1911

T
tschw 已提交
1912
			// refresh uniforms common to several materials
G
gero3 已提交
1913

T
tschw 已提交
1914
			if ( fog && material.fog ) {
G
gero3 已提交
1915

T
tschw 已提交
1916
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
1917 1918 1919

			}

1920
			if ( material.isMeshBasicMaterial ) {
M
Mr.doob 已提交
1921 1922 1923

				refreshUniformsCommon( m_uniforms, material );

1924
			} else if ( material.isMeshLambertMaterial ) {
M
Mr.doob 已提交
1925

1926 1927
				refreshUniformsCommon( m_uniforms, material );
				refreshUniformsLambert( m_uniforms, material );
M
Mr.doob 已提交
1928

1929
			} else if ( material.isMeshPhongMaterial ) {
M
Mr.doob 已提交
1930

1931
				refreshUniformsCommon( m_uniforms, material );
M
Mr.doob 已提交
1932

1933
				if ( material.isMeshToonMaterial ) {
M
Mr.doob 已提交
1934

1935
					refreshUniformsToon( m_uniforms, material );
M
Mr.doob 已提交
1936

1937
				} else {
1938

1939
					refreshUniformsPhong( m_uniforms, material );
1940

1941
				}
T
Takahiro 已提交
1942

1943
			} else if ( material.isMeshStandardMaterial ) {
T
Takahiro 已提交
1944

1945
				refreshUniformsCommon( m_uniforms, material );
1946

1947
				if ( material.isMeshPhysicalMaterial ) {
1948

1949
					refreshUniformsPhysical( m_uniforms, material );
W
WestLangley 已提交
1950

1951
				} else {
W
WestLangley 已提交
1952

1953
					refreshUniformsStandard( m_uniforms, material );
W
WestLangley 已提交
1954

1955
				}
W
WestLangley 已提交
1956

W
WestLangley 已提交
1957 1958 1959 1960 1961 1962
			} else if ( material.isMeshMatcapMaterial ) {

				refreshUniformsCommon( m_uniforms, material );

				refreshUniformsMatcap( m_uniforms, material );

1963
			} else if ( material.isMeshDepthMaterial ) {
M
Mr.doob 已提交
1964

1965
				refreshUniformsCommon( m_uniforms, material );
W
WestLangley 已提交
1966
				refreshUniformsDepth( m_uniforms, material );
1967

W
WestLangley 已提交
1968
			} else if ( material.isMeshDistanceMaterial ) {
1969

1970
				refreshUniformsCommon( m_uniforms, material );
W
WestLangley 已提交
1971
				refreshUniformsDistance( m_uniforms, material );
1972

1973
			} else if ( material.isMeshNormalMaterial ) {
M
Mr.doob 已提交
1974

1975
				refreshUniformsCommon( m_uniforms, material );
1976
				refreshUniformsNormal( m_uniforms, material );
M
Mr.doob 已提交
1977

1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991
			} else if ( material.isLineBasicMaterial ) {

				refreshUniformsLine( m_uniforms, material );

				if ( material.isLineDashedMaterial ) {

					refreshUniformsDash( m_uniforms, material );

				}

			} else if ( material.isPointsMaterial ) {

				refreshUniformsPoints( m_uniforms, material );

1992 1993 1994 1995
			} else if ( material.isSpriteMaterial ) {

				refreshUniformsSprites( m_uniforms, material );

1996 1997
			} else if ( material.isShadowMaterial ) {

T
Takahiro 已提交
1998
				m_uniforms.color.value.copy( material.color );
1999 2000
				m_uniforms.opacity.value = material.opacity;

M
Mr.doob 已提交
2001 2002
			}

M
Mr.doob 已提交
2003 2004 2005
			// RectAreaLight Texture
			// TODO (mrdoob): Find a nicer implementation

2006 2007
			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 已提交
2008

2009
			WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, textures );
A
arose 已提交
2010 2011 2012

		}

2013 2014
		if ( material.isShaderMaterial && material.uniformsNeedUpdate === true ) {

2015
			WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, textures );
2016 2017 2018
			material.uniformsNeedUpdate = false;

		}
M
Mr.doob 已提交
2019

2020 2021 2022 2023 2024 2025
		if ( material.isSpriteMaterial ) {

			p_uniforms.setValue( _gl, 'center', object.center );

		}

T
tschw 已提交
2026
		// common matrices
M
Mr.doob 已提交
2027

M
Mr.doob 已提交
2028 2029
		p_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix );
		p_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix );
T
tschw 已提交
2030
		p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );
A
arose 已提交
2031

T
tschw 已提交
2032
		return program;
A
arose 已提交
2033 2034 2035

	}

M
Mr.doob 已提交
2036 2037
	// Uniforms (refresh uniforms objects)

M
Mr.doob 已提交
2038
	function refreshUniformsCommon( uniforms, material ) {
M
Mr.doob 已提交
2039 2040 2041

		uniforms.opacity.value = material.opacity;

2042 2043
		if ( material.color ) {

T
Takahiro 已提交
2044
			uniforms.diffuse.value.copy( material.color );
2045 2046

		}
M
Mr.doob 已提交
2047

2048
		if ( material.emissive ) {
M
Mr.doob 已提交
2049

2050
			uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );
M
Mr.doob 已提交
2051 2052 2053

		}

2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079
		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
0
06wj 已提交
2080
			uniforms.flipEnvMap.value = material.envMap.isCubeTexture ? - 1 : 1;
2081 2082 2083 2084

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

2085
			uniforms.maxMipLevel.value = properties.get( material.envMap ).__maxMipLevel;
2086

2087
		}
M
Mr.doob 已提交
2088

2089 2090 2091 2092 2093 2094 2095
		if ( material.lightMap ) {

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

		}

2096
		if ( material.aoMap ) {
2097

2098 2099
			uniforms.aoMap.value = material.aoMap;
			uniforms.aoMapIntensity.value = material.aoMapIntensity;
2100 2101 2102

		}

M
Mr.doob 已提交
2103
		// uv repeat and offset setting priorities
M
Mr.doob 已提交
2104 2105 2106 2107 2108
		// 1. color map
		// 2. specular map
		// 3. normal map
		// 4. bump map
		// 5. alpha map
2109
		// 6. emissive map
M
Mr.doob 已提交
2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120

		var uvScaleMap;

		if ( material.map ) {

			uvScaleMap = material.map;

		} else if ( material.specularMap ) {

			uvScaleMap = material.specularMap;

2121 2122 2123 2124
		} else if ( material.displacementMap ) {

			uvScaleMap = material.displacementMap;

M
Mr.doob 已提交
2125 2126 2127 2128 2129 2130 2131 2132
		} else if ( material.normalMap ) {

			uvScaleMap = material.normalMap;

		} else if ( material.bumpMap ) {

			uvScaleMap = material.bumpMap;

2133 2134 2135 2136 2137 2138 2139 2140
		} else if ( material.roughnessMap ) {

			uvScaleMap = material.roughnessMap;

		} else if ( material.metalnessMap ) {

			uvScaleMap = material.metalnessMap;

2141 2142 2143 2144
		} else if ( material.alphaMap ) {

			uvScaleMap = material.alphaMap;

2145 2146 2147 2148
		} else if ( material.emissiveMap ) {

			uvScaleMap = material.emissiveMap;

M
Mr.doob 已提交
2149 2150 2151 2152
		}

		if ( uvScaleMap !== undefined ) {

2153
			// backwards compatibility
2154
			if ( uvScaleMap.isWebGLRenderTarget ) {
M
Mr.doob 已提交
2155 2156 2157 2158 2159

				uvScaleMap = uvScaleMap.texture;

			}

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

W
WestLangley 已提交
2162
				uvScaleMap.updateMatrix();
M
Mr.doob 已提交
2163

W
WestLangley 已提交
2164
			}
2165

2166
			uniforms.uvTransform.value.copy( uvScaleMap.matrix );
M
Mr.doob 已提交
2167 2168 2169

		}

M
Mr.doob 已提交
2170
	}
M
Mr.doob 已提交
2171

M
Mr.doob 已提交
2172
	function refreshUniformsLine( uniforms, material ) {
M
Mr.doob 已提交
2173

T
Takahiro 已提交
2174
		uniforms.diffuse.value.copy( material.color );
M
Mr.doob 已提交
2175 2176
		uniforms.opacity.value = material.opacity;

M
Mr.doob 已提交
2177
	}
M
Mr.doob 已提交
2178

M
Mr.doob 已提交
2179
	function refreshUniformsDash( uniforms, material ) {
M
Mr.doob 已提交
2180 2181 2182 2183 2184

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

M
Mr.doob 已提交
2185
	}
M
Mr.doob 已提交
2186

M
Mr.doob 已提交
2187
	function refreshUniformsPoints( uniforms, material ) {
M
Mr.doob 已提交
2188

T
Takahiro 已提交
2189
		uniforms.diffuse.value.copy( material.color );
M
Mr.doob 已提交
2190
		uniforms.opacity.value = material.opacity;
2191
		uniforms.size.value = material.size * _pixelRatio;
2192
		uniforms.scale.value = _height * 0.5;
M
Mr.doob 已提交
2193 2194 2195

		uniforms.map.value = material.map;

2196 2197
		if ( material.map !== null ) {

W
WestLangley 已提交
2198
			if ( material.map.matrixAutoUpdate === true ) {
2199

W
WestLangley 已提交
2200
				material.map.updateMatrix();
W
WestLangley 已提交
2201 2202

			}
2203

2204
			uniforms.uvTransform.value.copy( material.map.matrix );
2205 2206 2207

		}

2208 2209 2210 2211
	}

	function refreshUniformsSprites( uniforms, material ) {

T
Takahiro 已提交
2212
		uniforms.diffuse.value.copy( material.color );
2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228
		uniforms.opacity.value = material.opacity;
		uniforms.rotation.value = material.rotation;
		uniforms.map.value = material.map;

		if ( material.map !== null ) {

			if ( material.map.matrixAutoUpdate === true ) {

				material.map.updateMatrix();

			}

			uniforms.uvTransform.value.copy( material.map.matrix );

		}

M
Mr.doob 已提交
2229
	}
M
Mr.doob 已提交
2230

M
Mr.doob 已提交
2231
	function refreshUniformsFog( uniforms, fog ) {
M
Mr.doob 已提交
2232

T
Takahiro 已提交
2233
		uniforms.fogColor.value.copy( fog.color );
M
Mr.doob 已提交
2234

2235
		if ( fog.isFog ) {
M
Mr.doob 已提交
2236 2237 2238 2239

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

2240
		} else if ( fog.isFogExp2 ) {
M
Mr.doob 已提交
2241 2242 2243 2244 2245

			uniforms.fogDensity.value = fog.density;

		}

M
Mr.doob 已提交
2246
	}
M
Mr.doob 已提交
2247

M
Mr.doob 已提交
2248
	function refreshUniformsLambert( uniforms, material ) {
2249 2250 2251 2252 2253 2254 2255 2256 2257

		if ( material.emissiveMap ) {

			uniforms.emissiveMap.value = material.emissiveMap;

		}

	}

M
Mr.doob 已提交
2258
	function refreshUniformsPhong( uniforms, material ) {
M
Mr.doob 已提交
2259

T
Takahiro 已提交
2260
		uniforms.specular.value.copy( material.specular );
M
Mr.doob 已提交
2261
		uniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 )
M
Mr.doob 已提交
2262

2263
		if ( material.emissiveMap ) {
2264

2265
			uniforms.emissiveMap.value = material.emissiveMap;
2266

2267
		}
M
Mr.doob 已提交
2268

2269 2270 2271 2272
		if ( material.bumpMap ) {

			uniforms.bumpMap.value = material.bumpMap;
			uniforms.bumpScale.value = material.bumpScale;
2273
			if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1;
M
Mr.doob 已提交
2274

2275
		}
M
Mr.doob 已提交
2276

2277 2278 2279 2280
		if ( material.normalMap ) {

			uniforms.normalMap.value = material.normalMap;
			uniforms.normalScale.value.copy( material.normalScale );
2281
			if ( material.side === BackSide ) uniforms.normalScale.value.negate();
2282 2283

		}
M
Mr.doob 已提交
2284

2285 2286 2287 2288 2289
		if ( material.displacementMap ) {

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

2291
		}
2292

T
Takahiro 已提交
2293 2294 2295 2296 2297 2298
	}

	function refreshUniformsToon( uniforms, material ) {

		refreshUniformsPhong( uniforms, material );

T
Takahiro 已提交
2299
		if ( material.gradientMap ) {
T
Takahiro 已提交
2300

T
Takahiro 已提交
2301
			uniforms.gradientMap.value = material.gradientMap;
T
Takahiro 已提交
2302 2303 2304

		}

2305 2306
	}

M
Mr.doob 已提交
2307
	function refreshUniformsStandard( uniforms, material ) {
W
WestLangley 已提交
2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333

		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;
2334
			if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1;
W
WestLangley 已提交
2335 2336 2337 2338 2339 2340 2341

		}

		if ( material.normalMap ) {

			uniforms.normalMap.value = material.normalMap;
			uniforms.normalScale.value.copy( material.normalScale );
2342
			if ( material.side === BackSide ) uniforms.normalScale.value.negate();
W
WestLangley 已提交
2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362

		}

		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 已提交
2363
	function refreshUniformsPhysical( uniforms, material ) {
W
WestLangley 已提交
2364

2365 2366 2367 2368
		refreshUniformsStandard( uniforms, material );

		uniforms.reflectivity.value = material.reflectivity; // also part of uniforms common

2369 2370 2371
		uniforms.clearCoat.value = material.clearCoat;
		uniforms.clearCoatRoughness.value = material.clearCoatRoughness;

W
WestLangley 已提交
2372 2373
	}

W
WestLangley 已提交
2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407
	function refreshUniformsMatcap( uniforms, material ) {

		if ( material.matcap ) {

			uniforms.matcap.value = material.matcap;

		}

		if ( material.bumpMap ) {

			uniforms.bumpMap.value = material.bumpMap;
			uniforms.bumpScale.value = material.bumpScale;
			if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1;

		}

		if ( material.normalMap ) {

			uniforms.normalMap.value = material.normalMap;
			uniforms.normalScale.value.copy( material.normalScale );
			if ( material.side === BackSide ) uniforms.normalScale.value.negate();

		}

		if ( material.displacementMap ) {

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

		}

	}

W
WestLangley 已提交
2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435
	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;

	}

2436 2437 2438 2439 2440 2441
	function refreshUniformsNormal( uniforms, material ) {

		if ( material.bumpMap ) {

			uniforms.bumpMap.value = material.bumpMap;
			uniforms.bumpScale.value = material.bumpScale;
2442
			if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1;
2443 2444 2445 2446 2447 2448 2449

		}

		if ( material.normalMap ) {

			uniforms.normalMap.value = material.normalMap;
			uniforms.normalScale.value.copy( material.normalScale );
2450
			if ( material.side === BackSide ) uniforms.normalScale.value.negate();
2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463

		}

		if ( material.displacementMap ) {

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

		}

	}

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

M
Mr.doob 已提交
2466
	function markUniformsLightsNeedsUpdate( uniforms, value ) {
2467

M
Mr.doob 已提交
2468
		uniforms.ambientLightColor.needsUpdate = value;
W
WestLangley 已提交
2469
		uniforms.lightProbe.needsUpdate = value;
2470

B
Ben Houston 已提交
2471 2472 2473
		uniforms.directionalLights.needsUpdate = value;
		uniforms.pointLights.needsUpdate = value;
		uniforms.spotLights.needsUpdate = value;
2474
		uniforms.rectAreaLights.needsUpdate = value;
B
Ben Houston 已提交
2475
		uniforms.hemisphereLights.needsUpdate = value;
2476

M
Mr.doob 已提交
2477
	}
2478

2479 2480 2481
	//
	this.setFramebuffer = function ( value ) {

M
Mr.doob 已提交
2482
		if ( _framebuffer !== value ) _gl.bindFramebuffer( _gl.FRAMEBUFFER, value );
2483

2484 2485 2486 2487
		_framebuffer = value;

	};

2488 2489 2490 2491 2492 2493
	this.getActiveCubeFace = function () {

		return _currentActiveCubeFace;

	};

2494
	this.getActiveMipmapLevel = function () {
2495 2496 2497 2498 2499

		return _currentActiveMipmapLevel;

	};

2500
	this.getRenderTarget = function () {
2501 2502 2503

		return _currentRenderTarget;

M
Michael Herzog 已提交
2504
	};
2505

2506
	this.setRenderTarget = function ( renderTarget, activeCubeFace, activeMipmapLevel ) {
M
Mr.doob 已提交
2507

2508
		_currentRenderTarget = renderTarget;
2509
		_currentActiveCubeFace = activeCubeFace;
2510
		_currentActiveMipmapLevel = activeMipmapLevel;
2511

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

2514
			textures.setupRenderTarget( renderTarget );
M
Mr.doob 已提交
2515 2516 2517

		}

2518
		var framebuffer = _framebuffer;
M
Mr.doob 已提交
2519
		var isCube = false;
M
Mr.doob 已提交
2520 2521 2522

		if ( renderTarget ) {

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

M
Mr.doob 已提交
2525
			if ( renderTarget.isWebGLRenderTargetCube ) {
M
Mr.doob 已提交
2526

2527
				framebuffer = __webglFramebuffer[ activeCubeFace || 0 ];
M
Mr.doob 已提交
2528
				isCube = true;
M
Mr.doob 已提交
2529

2530 2531 2532 2533
			} else if ( renderTarget.isWebGLMultisampleRenderTarget ) {

				framebuffer = properties.get( renderTarget ).__webglMultisampledFramebuffer;

M
Mr.doob 已提交
2534 2535
			} else {

M
Mr.doob 已提交
2536
				framebuffer = __webglFramebuffer;
M
Mr.doob 已提交
2537 2538 2539

			}

M
Mr.doob 已提交
2540
			_currentViewport.copy( renderTarget.viewport );
2541 2542
			_currentScissor.copy( renderTarget.scissor );
			_currentScissorTest = renderTarget.scissorTest;
2543

M
Mr.doob 已提交
2544 2545
		} else {

2546 2547
			_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ).floor();
			_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ).floor();
2548
			_currentScissorTest = _scissorTest;
2549

M
Mr.doob 已提交
2550 2551
		}

M
Mr.doob 已提交
2552
		if ( _currentFramebuffer !== framebuffer ) {
M
Mr.doob 已提交
2553 2554 2555 2556 2557 2558

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

		}

M
Mr.doob 已提交
2559
		state.viewport( _currentViewport );
2560 2561
		state.scissor( _currentScissor );
		state.setScissorTest( _currentScissorTest );
2562

M
Mr.doob 已提交
2563 2564 2565
		if ( isCube ) {

			var textureProperties = properties.get( renderTarget.texture );
2566
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + ( activeCubeFace || 0 ), textureProperties.__webglTexture, activeMipmapLevel || 0 );
M
Mr.doob 已提交
2567 2568 2569

		}

M
Mr.doob 已提交
2570 2571
	};

2572
	this.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer, activeCubeFaceIndex ) {
2573

0
06wj 已提交
2574
		if ( ! ( renderTarget && renderTarget.isWebGLRenderTarget ) ) {
2575

2576
			console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
G
gero3 已提交
2577
			return;
2578

G
gero3 已提交
2579
		}
2580

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

2583
		if ( renderTarget.isWebGLRenderTargetCube && activeCubeFaceIndex !== undefined ) {
2584 2585 2586 2587 2588

			framebuffer = framebuffer[ activeCubeFaceIndex ];

		}

M
Mr.doob 已提交
2589
		if ( framebuffer ) {
2590

G
gero3 已提交
2591
			var restore = false;
2592

M
Mr.doob 已提交
2593
			if ( framebuffer !== _currentFramebuffer ) {
2594

M
Mr.doob 已提交
2595
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
2596

G
gero3 已提交
2597
				restore = true;
2598

G
gero3 已提交
2599
			}
2600

M
Mr.doob 已提交
2601
			try {
2602

M
Mr.doob 已提交
2603
				var texture = renderTarget.texture;
M
Mr.doob 已提交
2604 2605
				var textureFormat = texture.format;
				var textureType = texture.type;
2606

2607
				if ( textureFormat !== RGBAFormat && utils.convert( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {
2608

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

M
Mr.doob 已提交
2612
				}
2613

2614
				if ( textureType !== UnsignedByteType && utils.convert( textureType ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE ) && // IE11, Edge and Chrome Mac < 52 (#9513)
T
Takahiro 已提交
2615 2616
					! ( textureType === FloatType && ( capabilities.isWebGL2 || extensions.get( 'OES_texture_float' ) || extensions.get( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox
					! ( textureType === HalfFloatType && ( capabilities.isWebGL2 ? extensions.get( 'EXT_color_buffer_float' ) : extensions.get( 'EXT_color_buffer_half_float' ) ) ) ) {
2617

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

M
Mr.doob 已提交
2621
				}
2622

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

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

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

2629
						_gl.readPixels( x, y, width, height, utils.convert( textureFormat ), utils.convert( textureType ), buffer );
2630 2631

					}
2632

M
Mr.doob 已提交
2633
				} else {
M
Mr.doob 已提交
2634

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

				}
M
Mr.doob 已提交
2638

M
Mr.doob 已提交
2639
			} finally {
M
Mr.doob 已提交
2640

M
Mr.doob 已提交
2641 2642 2643
				if ( restore ) {

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

M
Mr.doob 已提交
2645 2646 2647
				}

			}
M
Mr.doob 已提交
2648 2649 2650

		}

M
Mr.doob 已提交
2651 2652
	};

2653
	this.copyFramebufferToTexture = function ( position, texture, level ) {
2654 2655 2656

		var width = texture.image.width;
		var height = texture.image.height;
2657
		var glFormat = utils.convert( texture.format );
2658

2659
		textures.setTexture2D( texture, 0 );
2660

2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671
		_gl.copyTexImage2D( _gl.TEXTURE_2D, level || 0, glFormat, position.x, position.y, width, height, 0 );

	};

	this.copyTextureToTexture = function ( position, srcTexture, dstTexture, level ) {

		var width = srcTexture.image.width;
		var height = srcTexture.image.height;
		var glFormat = utils.convert( dstTexture.format );
		var glType = utils.convert( dstTexture.type );

2672
		textures.setTexture2D( dstTexture, 0 );
2673

2674 2675 2676 2677 2678 2679 2680 2681 2682
		if ( srcTexture.isDataTexture ) {

			_gl.texSubImage2D( _gl.TEXTURE_2D, level || 0, position.x, position.y, width, height, glFormat, glType, srcTexture.image.data );

		} else {

			_gl.texSubImage2D( _gl.TEXTURE_2D, level || 0, position.x, position.y, glFormat, glType, srcTexture.image );

		}
2683 2684 2685

	};

M
Mr.doob 已提交
2686
	if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) {
R
Rich Harris 已提交
2687

M
Mugen87 已提交
2688 2689
		__THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'observe', { detail: this } ) ); // eslint-disable-line no-undef

2690
	}
R
Rich Harris 已提交
2691

M
Mr.doob 已提交
2692
}
T
Tristan VALCKE 已提交
2693

2694
export { WebGLRenderer };