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

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

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

	parameters = parameters || {};

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

62 63
		_multiview = parameters.multiview !== undefined ? parameters.multiview : false,

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

73
	var currentRenderList = null;
74
	var currentRenderState = null;
M
Mr.doob 已提交
75

M
Mr.doob 已提交
76 77 78 79
	// public properties

	this.domElement = _canvas;

80 81 82 83 84 85 86
	// Debug configuration container
	this.debug = {

		/**
		 * Enables error checking and reporting when shader programs are being compiled
		 * @type {boolean}
		 */
87
		checkShaderErrors: true
88
	};
89

M
Mr.doob 已提交
90 91 92 93 94 95 96 97 98 99 100
	// clearing

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

	// scene graph

	this.sortObjects = true;

T
tschw 已提交
101 102 103 104 105
	// user-defined clipping

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

M
Mr.doob 已提交
106 107
	// physically based shading

108
	this.gammaFactor = 2.0;	// for backwards compatibility
M
Mr.doob 已提交
109 110 111
	this.gammaInput = false;
	this.gammaOutput = false;

112 113
	// physical lights

114
	this.physicallyCorrectLights = false;
115

B
Ben Houston 已提交
116 117
	// tone mapping

R
Rich Harris 已提交
118
	this.toneMapping = LinearToneMapping;
B
Ben Houston 已提交
119 120 121
	this.toneMappingExposure = 1.0;
	this.toneMappingWhitePoint = 1.0;

M
Mr.doob 已提交
122 123 124 125 126 127 128 129 130
	// morphs

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

	// internal properties

	var _this = this,

131 132
		_isContextLost = false,

133
		// internal state cache
M
Mr.doob 已提交
134

135 136
		_framebuffer = null,

137 138
		_currentActiveCubeFace = 0,
		_currentActiveMipmapLevel = 0,
139 140 141
		_currentRenderTarget = null,
		_currentFramebuffer = null,
		_currentMaterialId = - 1,
142 143 144 145

		// geometry and program caching

		_currentGeometryProgram = {
M
Mr.doob 已提交
146 147
			geometry: null,
			program: null,
148 149
			wireframe: false
		},
150

151
		_currentCamera = null,
152
		_currentArrayCamera = null,
M
Mr.doob 已提交
153

M
Mr.doob 已提交
154
		_currentViewport = new Vector4(),
155 156
		_currentScissor = new Vector4(),
		_currentScissorTest = null,
157

158
		//
159

160 161
		_width = _canvas.width,
		_height = _canvas.height,
M
Mr.doob 已提交
162

163
		_pixelRatio = 1,
M
Mr.doob 已提交
164

M
Mr.doob 已提交
165
		_viewport = new Vector4( 0, 0, _width, _height ),
166 167
		_scissor = new Vector4( 0, 0, _width, _height ),
		_scissorTest = false,
168

169
		// frustum
M
Mr.doob 已提交
170

171
		_frustum = new Frustum(),
M
Mr.doob 已提交
172

173
		// clipping
T
tschw 已提交
174

175 176 177
		_clipping = new WebGLClipping(),
		_clippingEnabled = false,
		_localClippingEnabled = false,
T
tschw 已提交
178

179
		// camera matrices cache
M
Mr.doob 已提交
180

181
		_projScreenMatrix = new Matrix4(),
M
Mr.doob 已提交
182

M
Mugen87 已提交
183
		_vector3 = new Vector3();
A
Atrahasis 已提交
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,
204
			powerPreference: _powerPreference,
M
Mr.doob 已提交
205
			failIfMajorPerformanceCaveat: _failIfMajorPerformanceCaveat,
206
			xrCompatible: true
M
Mr.doob 已提交
207 208
		};

209 210
		// event listeners must be registered before WebGL context is created, see #12753

211
		_canvas.addEventListener( 'webglcontextlost', onContextLost, false );
212
		_canvas.addEventListener( 'webglcontextrestored', onContextRestore, false );
213

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

		if ( _gl === null ) {

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

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

			} else {

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

			}
M
Mr.doob 已提交
227 228 229

		}

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

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

	}

M
Mugen87 已提交
249
	var extensions, capabilities, state, info;
250
	var properties, textures, attributes, geometries, objects;
251
	var programCache, renderLists, renderStates;
252

253
	var background, morphtargets, bufferRenderer, indexedBufferRenderer;
254

255
	var utils;
256

257
	function initGLContext() {
258

259
		extensions = new WebGLExtensions( _gl );
260

T
Takahiro 已提交
261 262 263
		capabilities = new WebGLCapabilities( _gl, extensions, parameters );

		if ( ! capabilities.isWebGL2 ) {
264 265 266 267 268 269 270 271 272 273 274

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

		}

275
		extensions.get( 'OES_texture_float_linear' );
276

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

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

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

294
		background = new WebGLBackground( _this, state, objects, _premultipliedAlpha );
295

T
Takahiro 已提交
296 297
		bufferRenderer = new WebGLBufferRenderer( _gl, extensions, info, capabilities );
		indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, info, capabilities );
298

M
Mugen87 已提交
299
		info.programs = programCache.programs;
300

301 302 303 304 305
		_this.capabilities = capabilities;
		_this.extensions = extensions;
		_this.properties = properties;
		_this.renderLists = renderLists;
		_this.state = state;
M
Mugen87 已提交
306
		_this.info = info;
M
Mr.doob 已提交
307

308
	}
M
Mr.doob 已提交
309

310
	initGLContext();
M
Mr.doob 已提交
311

312
	// vr
M
Mr.doob 已提交
313

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

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

318 319
	var multiviewObject = new WebGLMultiview(_multiview, _gl, _canvas, extensions, capabilities );
	var multiviewEnabled = this.multiviewEnabled = multiviewObject.isEnabled();
320

M
Mr.doob 已提交
321
	// shadow map
M
Mr.doob 已提交
322

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

325
	this.shadowMap = shadowMap;
M
Mr.doob 已提交
326

M
Mr.doob 已提交
327 328 329 330 331 332 333 334
	// API

	this.getContext = function () {

		return _gl;

	};

335 336 337 338 339 340
	this.getContextAttributes = function () {

		return _gl.getContextAttributes();

	};

341 342
	this.forceContextLoss = function () {

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

	};

348
	this.forceContextRestore = function () {
M
Mr.doob 已提交
349

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

	};

355 356
	this.getPixelRatio = function () {

357
		return _pixelRatio;
358 359 360 361 362

	};

	this.setPixelRatio = function ( value ) {

363 364 365 366
		if ( value === undefined ) return;

		_pixelRatio = value;

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

	};

371
	this.getSize = function ( target ) {
372

373 374 375 376 377 378 379 380 381
		if ( target === undefined ) {

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

			target = new Vector2();

		}

		return target.set( _width, _height );
382 383 384

	};

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

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

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

		}

394 395 396
		_width = width;
		_height = height;

397 398
		_canvas.width = Math.floor( width * _pixelRatio );
		_canvas.height = Math.floor( height * _pixelRatio );
399

400
		if ( updateStyle !== false ) {
401

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

G
gero3 已提交
405
		}
M
Mr.doob 已提交
406

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

	};

411
	this.getDrawingBufferSize = function ( target ) {
M
Mr.doob 已提交
412

413 414 415 416 417 418 419 420
		if ( target === undefined ) {

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

			target = new Vector2();

		}

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

	};

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

		_width = width;
		_height = height;

		_pixelRatio = pixelRatio;

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

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

	};

439
	this.getCurrentViewport = function ( target ) {
M
Mugen87 已提交
440

441 442 443 444 445 446 447 448 449
		if ( target === undefined ) {

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

			target = new Vector4();

		}

		return target.copy( _currentViewport );
M
Mugen87 已提交
450 451 452

	};

453 454 455
	this.getViewport = function ( target ) {

		return target.copy( _viewport );
M
Mugen87 已提交
456 457 458

	};

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

461 462 463 464 465 466 467 468 469 470
		if ( x.isVector4 ) {

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

		} else {

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

		}

471
		state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ).floor() );
472

M
Mr.doob 已提交
473 474
	};

475 476 477 478 479 480
	this.getScissor = function ( target ) {

		return target.copy( _scissor );

	};

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

483 484 485 486 487 488 489 490 491 492
		if ( x.isVector4 ) {

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

		} else {

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

		}

493
		state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ).floor() );
494

M
Mr.doob 已提交
495 496
	};

497 498 499 500 501 502
	this.getScissorTest = function () {

		return _scissorTest;

	};

503 504
	this.setScissorTest = function ( boolean ) {

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

	};

	// Clearing

M
Mr.doob 已提交
511
	this.getClearColor = function () {
M
Mr.doob 已提交
512

513
		return background.getClearColor();
M
Mr.doob 已提交
514 515 516

	};

517
	this.setClearColor = function () {
518

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

	};

M
Mr.doob 已提交
523
	this.getClearAlpha = function () {
M
Mr.doob 已提交
524

525
		return background.getClearAlpha();
M
Mr.doob 已提交
526 527 528

	};

M
Mugen87 已提交
529
	this.setClearAlpha = function () {
M
Mr.doob 已提交
530

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

	};

	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 );
544 545 546 547 548

	};

	this.clearColor = function () {

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

	};

	this.clearDepth = function () {

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

	};

	this.clearStencil = function () {

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

	};

M
Mr.doob 已提交
565
	//
M
Mr.doob 已提交
566

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

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

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

577
		vr.dispose();
578

579
		animation.stop();
B
brunnerh 已提交
580

D
dubejf 已提交
581 582
	};

M
Mr.doob 已提交
583
	// Events
M
Mr.doob 已提交
584

D
dubejf 已提交
585 586 587 588
	function onContextLost( event ) {

		event.preventDefault();

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

591 592 593 594
		_isContextLost = true;

	}

M
Mugen87 已提交
595
	function onContextRestore( /* event */ ) {
D
dubejf 已提交
596

597
		console.log( 'THREE.WebGLRenderer: Context Restored.' );
598 599

		_isContextLost = false;
D
dubejf 已提交
600

601
		initGLContext();
D
dubejf 已提交
602

M
Mr.doob 已提交
603
	}
D
dubejf 已提交
604

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

		var material = event.target;

		material.removeEventListener( 'dispose', onMaterialDispose );

		deallocateMaterial( material );

613
	}
M
Mr.doob 已提交
614 615 616

	// Buffer deallocation

617
	function deallocateMaterial( material ) {
M
Mr.doob 已提交
618

619 620
		releaseMaterialProgramReference( material );

621
		properties.remove( material );
622

623
	}
624 625


626
	function releaseMaterialProgramReference( material ) {
627

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

		material.program = undefined;

632
		if ( programInfo !== undefined ) {
M
Mr.doob 已提交
633

634
			programCache.releaseProgram( programInfo );
M
Mr.doob 已提交
635

M
Mr.doob 已提交
636 637
		}

638
	}
M
Mr.doob 已提交
639 640 641

	// Buffer rendering

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

		object.render( function ( object ) {

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

		} );

	}

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

654
		state.initAttributes();
655

656
		var buffers = properties.get( object );
657

658 659 660 661
		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 已提交
662

663
		var programAttributes = program.getAttributes();
664

M
Mr.doob 已提交
665 666
		if ( object.hasPositions ) {

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

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

		}

		if ( object.hasNormals ) {

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

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

		}

685
		if ( object.hasUvs ) {
M
Mr.doob 已提交
686

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

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

		}

695
		if ( object.hasColors ) {
M
Mr.doob 已提交
696

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

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

		}

705
		state.disableUnusedAttributes();
706

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

		object.count = 0;

	};

713
	this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {
714

715
		var frontFaceCW = ( object.isMesh && object.matrixWorld.determinant() < 0 );
716 717

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

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

M
Mr.doob 已提交
721
		var updateBuffers = false;
M
Mr.doob 已提交
722

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

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

		}

734
		if ( object.morphTargetInfluences ) {
735

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

			updateBuffers = true;

		}

742 743
		//

744
		var index = geometry.index;
745
		var position = geometry.attributes.position;
746
		var rangeFactor = 1;
747

748 749
		if ( material.wireframe === true ) {

750
			index = geometries.getWireframeAttribute( geometry );
751
			rangeFactor = 2;
752 753 754

		}

M
Mr.doob 已提交
755
		var attribute;
M
Mr.doob 已提交
756
		var renderer = bufferRenderer;
757

758
		if ( index !== null ) {
759

M
Mr.doob 已提交
760
			attribute = attributes.get( index );
761

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

765
		}
M
Mr.doob 已提交
766

767
		if ( updateBuffers ) {
M
Mr.doob 已提交
768

769
			setupVertexAttributes( material, program, geometry );
M
Mr.doob 已提交
770

771
			if ( index !== null ) {
772

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

			}

777
		}
778

779 780
		//

781
		var dataCount = Infinity;
782

M
Mr.doob 已提交
783
		if ( index !== null ) {
784

M
Mr.doob 已提交
785
			dataCount = index.count;
786

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

M
Mr.doob 已提交
789
			dataCount = position.count;
790

M
Mr.doob 已提交
791
		}
792

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

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

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

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

804 805
		if ( drawCount === 0 ) return;

M
Mr.doob 已提交
806
		//
807

808
		if ( object.isMesh ) {
809

810
			if ( material.wireframe === true ) {
811

812
				state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );
813
				renderer.setMode( _gl.LINES );
814

815
			} else {
M
Mr.doob 已提交
816 817

				switch ( object.drawMode ) {
818

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

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

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

				}
832

833
			}
834

835

836
		} else if ( object.isLine ) {
837

838
			var lineWidth = material.linewidth;
839

840
			if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material
841

842
			state.setLineWidth( lineWidth * getTargetPixelRatio() );
843

844
			if ( object.isLineSegments ) {
845

846
				renderer.setMode( _gl.LINES );
847

848 849 850 851
			} else if ( object.isLineLoop ) {

				renderer.setMode( _gl.LINE_LOOP );

852
			} else {
853

854
				renderer.setMode( _gl.LINE_STRIP );
855 856

			}
M
Mr.doob 已提交
857

858
		} else if ( object.isPoints ) {
859 860

			renderer.setMode( _gl.POINTS );
861

862 863 864 865
		} else if ( object.isSprite ) {

			renderer.setMode( _gl.TRIANGLES );

866
		}
867

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

			if ( geometry.maxInstancedCount > 0 ) {

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

J
jfranc 已提交
874
			}
875 876 877

		} else {

M
Mr.doob 已提交
878
			renderer.render( drawStart, drawCount );
879

M
Mr.doob 已提交
880 881 882 883
		}

	};

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

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

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

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

M
Mr.doob 已提交
893 894 895
			}

		}
B
Ben Adams 已提交
896

897 898
		state.initAttributes();

899
		var geometryAttributes = geometry.attributes;
900

901
		var programAttributes = program.getAttributes();
902

903
		var materialDefaultAttributeValues = material.defaultAttributeValues;
904

905
		for ( var name in programAttributes ) {
906

907
			var programAttribute = programAttributes[ name ];
M
Mr.doob 已提交
908

M
Mr.doob 已提交
909
			if ( programAttribute >= 0 ) {
M
Mr.doob 已提交
910

911
				var geometryAttribute = geometryAttributes[ name ];
912

M
Mr.doob 已提交
913
				if ( geometryAttribute !== undefined ) {
M
Mr.doob 已提交
914

915
					var normalized = geometryAttribute.normalized;
916
					var size = geometryAttribute.itemSize;
917

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

920 921 922 923
					// TODO Attribute may not be available on context restore

					if ( attribute === undefined ) continue;

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

A
aardgoose 已提交
928
					if ( geometryAttribute.isInterleavedBufferAttribute ) {
929

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

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

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

M
Mr.doob 已提交
938
							if ( geometry.maxInstancedCount === undefined ) {
939

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

M
Mr.doob 已提交
942
							}
B
Ben Adams 已提交
943

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

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

M
Mr.doob 已提交
948
						}
B
Ben Adams 已提交
949

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

M
Mr.doob 已提交
953
					} else {
B
Ben Adams 已提交
954

A
aardgoose 已提交
955
						if ( geometryAttribute.isInstancedBufferAttribute ) {
B
Ben Adams 已提交
956

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

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

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

M
Mr.doob 已提交
963
							}
B
Ben Adams 已提交
964

M
Mr.doob 已提交
965 966 967 968
						} else {

							state.enableAttribute( programAttribute );

M
Mr.doob 已提交
969
						}
B
Ben Adams 已提交
970

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

B
Ben Adams 已提交
974
					}
M
Mr.doob 已提交
975

976 977
				} else if ( materialDefaultAttributeValues !== undefined ) {

T
tschw 已提交
978
					var value = materialDefaultAttributeValues[ name ];
979

980
					if ( value !== undefined ) {
M
Mr.doob 已提交
981

982
						switch ( value.length ) {
M
Mr.doob 已提交
983

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

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

992 993 994
							case 4:
								_gl.vertexAttrib4fv( programAttribute, value );
								break;
995

996 997
							default:
								_gl.vertexAttrib1fv( programAttribute, value );
998 999

						}
M
Mr.doob 已提交
1000 1001 1002 1003 1004 1005 1006 1007

					}

				}

			}

		}
1008

1009
		state.disableUnusedAttributes();
1010

M
Mr.doob 已提交
1011 1012
	}

M
Mr.doob 已提交
1013
	// Compile
M
Mr.doob 已提交
1014

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

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

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

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

1024
				currentRenderState.pushLight( object );
1025 1026 1027

				if ( object.castShadow ) {

1028
					currentRenderState.pushShadow( object );
1029 1030

				}
M
Mr.doob 已提交
1031

G
gero3 已提交
1032
			}
M
Mr.doob 已提交
1033 1034 1035

		} );

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

		scene.traverse( function ( object ) {

			if ( object.material ) {

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

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

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

G
gero3 已提交
1048
					}
M
Mr.doob 已提交
1049

G
gero3 已提交
1050
				} else {
M
Mr.doob 已提交
1051 1052 1053

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

G
gero3 已提交
1054
				}
M
Mr.doob 已提交
1055

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

		} );
G
gero3 已提交
1059 1060

	};
1061

1062
	// Animation Loop
M
Mr.doob 已提交
1063

M
Mr.doob 已提交
1064
	var onAnimationFrameCallback = null;
1065

1066
	function onAnimationFrame( time ) {
1067

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

1071
	}
1072

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

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

1078
	this.setAnimationLoop = function ( callback ) {
1079

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

1083 1084
		animation.start();

1085 1086
	};

M
Mr.doob 已提交
1087 1088
	// Rendering

1089 1090
	this.render = function ( scene, camera ) {

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

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

		}
1106

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

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

		}

1114 1115
		if ( _isContextLost ) return;

M
Mr.doob 已提交
1116 1117
		// reset caching for this frame

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

		// update scene graph

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

		// update camera matrices and frustum

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

1132 1133 1134 1135 1136 1137
		if ( vr.enabled ) {

			camera = vr.getCamera( camera );

		}

1138 1139
		//

1140 1141
		currentRenderState = renderStates.get( scene, camera );
		currentRenderState.init();
1142

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

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

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

1151 1152 1153
		currentRenderList = renderLists.get( scene, camera );
		currentRenderList.init();

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

M
Mr.doob 已提交
1156
		if ( _this.sortObjects === true ) {
1157

1158
			currentRenderList.sort();
M
Mr.doob 已提交
1159

1160 1161
		}

M
Mr.doob 已提交
1162
		//
M
Mr.doob 已提交
1163

T
tschw 已提交
1164
		if ( _clippingEnabled ) _clipping.beginShadows();
T
tschw 已提交
1165

1166
		var shadowsArray = currentRenderState.state.shadowsArray;
1167

1168
		shadowMap.render( shadowsArray, scene, camera );
1169

1170
		currentRenderState.setupLights( camera );
1171

T
tschw 已提交
1172
		if ( _clippingEnabled ) _clipping.endShadows();
T
tschw 已提交
1173

M
Mr.doob 已提交
1174 1175
		//

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

1178
		if ( renderTarget !== undefined ) {
1179

1180
			this.setRenderTarget( renderTarget );
1181 1182 1183

		}

M
Mr.doob 已提交
1184 1185
		//

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

1188
		// render scene
M
Mr.doob 已提交
1189

1190 1191 1192
		var opaqueObjects = currentRenderList.opaque;
		var transparentObjects = currentRenderList.transparent;

M
Mr.doob 已提交
1193 1194
		if ( scene.overrideMaterial ) {

1195
			var overrideMaterial = scene.overrideMaterial;
M
Mr.doob 已提交
1196

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

M
Mr.doob 已提交
1200 1201
		} else {

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

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

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

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

1210
		}
M
Mr.doob 已提交
1211

1212
		//
M
Mr.doob 已提交
1213

1214 1215 1216 1217
		scene.onAfterRender( _this, scene, camera );

		//

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

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

1222
			textures.updateRenderTargetMipmap( _currentRenderTarget );
M
Mr.doob 已提交
1223

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

1226
			textures.updateMultisampleRenderTarget( _currentRenderTarget );
1227

M
Mr.doob 已提交
1228 1229
		}

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

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

1236
		state.setPolygonOffset( false );
1237

M
Mr.doob 已提交
1238
		if ( vr.enabled ) {
1239

1240
			vr.submitFrame();
1241

M
Mr.doob 已提交
1242
		}
M
Mr.doob 已提交
1243

M
Mr.doob 已提交
1244 1245
		// _gl.finish();

1246
		currentRenderList = null;
1247
		currentRenderState = null;
1248

M
Mr.doob 已提交
1249
	};
M
Mr.doob 已提交
1250

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

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

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

1257
		if ( visible ) {
1258

1259 1260 1261 1262
			if ( object.isGroup ) {

				groupOrder = object.renderOrder;

T
Takahiro 已提交
1263 1264
			} else if ( object.isLOD ) {

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

1267
			} else if ( object.isLight ) {
M
Mr.doob 已提交
1268

1269
				currentRenderState.pushLight( object );
1270 1271 1272

				if ( object.castShadow ) {

1273
					currentRenderState.pushShadow( object );
1274 1275

				}
M
Mr.doob 已提交
1276

1277
			} else if ( object.isSprite ) {
M
Mr.doob 已提交
1278

1279
				if ( ! object.frustumCulled || _frustum.intersectsSprite( object ) ) {
1280

1281 1282 1283 1284 1285 1286 1287 1288 1289 1290
					if ( sortObjects ) {

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

					}

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

1291 1292 1293 1294 1295
					if ( material.visible ) {

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

					}
M
Mr.doob 已提交
1296

1297
				}
M
Mr.doob 已提交
1298

1299
			} else if ( object.isImmediateRenderObject ) {
M
Mr.doob 已提交
1300

1301
				if ( sortObjects ) {
M
Mr.doob 已提交
1302

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

1306
				}
M
Mr.doob 已提交
1307

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

1310
			} else if ( object.isMesh || object.isLine || object.isPoints ) {
1311

1312
				if ( object.isSkinnedMesh ) {
1313

1314
					object.skeleton.update();
1315

1316
				}
1317

1318
				if ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) {
1319

1320 1321 1322 1323 1324 1325
					if ( sortObjects ) {

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

					}
1326

1327 1328
					var geometry = objects.update( object );
					var material = object.material;
1329

1330
					if ( Array.isArray( material ) ) {
1331

1332
						var groups = geometry.groups;
1333

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

1336 1337
							var group = groups[ i ];
							var groupMaterial = material[ group.materialIndex ];
1338

1339
							if ( groupMaterial && groupMaterial.visible ) {
1340

1341
								currentRenderList.push( object, geometry, groupMaterial, groupOrder, _vector3.z, group );
1342 1343

							}
M
Mr.doob 已提交
1344

M
Mr.doob 已提交
1345
						}
M
Mr.doob 已提交
1346

1347
					} else if ( material.visible ) {
1348

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

1351
					}
M
Mr.doob 已提交
1352

1353
				}
M
Mr.doob 已提交
1354

1355
			}
M
Mr.doob 已提交
1356

M
Mr.doob 已提交
1357
		}
M
Mr.doob 已提交
1358

M
Mr.doob 已提交
1359
		var children = object.children;
M
Mr.doob 已提交
1360

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

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

1365
		}
1366

1367
	}
M
Mr.doob 已提交
1368

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

1371 1372 1373
		if ( multiviewEnabled ) {

			multiviewObject.bindMultiviewFrameBuffer( camera );
1374 1375 1376

			_gl.disable( _gl.SCISSOR_TEST );

1377 1378 1379 1380
			if ( camera.isArrayCamera ) {

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

1382 1383 1384 1385
			} else {

				var width = _canvas.width;
				var height = _canvas.height;
1386

1387 1388 1389
			}
			_gl.viewport( 0, 0, width, height );
			renderer.setViewport( 0, 0, width, height );
1390 1391 1392 1393

			_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 已提交
1394

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

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

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

1404 1405
			}

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

		} 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 ) {
1420

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

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

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

1427
						var camera2 = cameras[ j ];
1428

1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446
						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 ) );

							}
1447

1448
							currentRenderState.setupLights( camera2 );
1449

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

						}
1453 1454

					}
M
Mr.doob 已提交
1455

1456
				} else {
1457

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

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

1462
				}
M
Mr.doob 已提交
1463

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

1466
		}
M
Mr.doob 已提交
1467

1468
	}
G
gero3 已提交
1469

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

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

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

		if ( object.isImmediateRenderObject ) {

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

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

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

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

		} else {

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

		}

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

M
Mr.doob 已提交
1499 1500
	}

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

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

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

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

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

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

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

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

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

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

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

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

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

			programChange = false;

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

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

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

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

		}

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

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

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

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

1559
			} else {
B
Ben Adams 已提交
1560

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

1568
			}
G
gero3 已提交
1569

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

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

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

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

		}

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

		if ( material.morphTargets ) {

			material.numSupportedMorphTargets = 0;

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

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

					material.numSupportedMorphTargets ++;

				}

			}

		}

		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

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

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

					material.numSupportedMorphNormals ++;

				}

			}

		}

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

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

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

		}

1628
		materialProperties.fog = fog;
1629

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

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

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

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

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

1654 1655
		}

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

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

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

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

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

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

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

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

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

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

			}

		}

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

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

1694
				material.needsUpdate = true;
1695

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

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

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

1702
				material.needsUpdate = true;
1703

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

				material.needsUpdate = true;

1710
			}
1711 1712 1713 1714

		}

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

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

		}

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

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

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

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

		}

		if ( material.id !== _currentMaterialId ) {

			_currentMaterialId = material.id;
1740

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

		}

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

1747
			if ( multiviewEnabled ) {
1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764

				if ( false && vr.isPresenting() ) {

					// @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 ] );

			}

			} else {

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

			}
M
Mr.doob 已提交
1765

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

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

			}

1773
			if ( _currentCamera !== camera ) {
1774

1775
				_currentCamera = camera;
1776 1777 1778 1779 1780 1781

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

			}
M
Mr.doob 已提交
1785

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

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

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

				if ( uCamPos !== undefined ) {
1797

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

				}

			}

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

1812
				if ( multiviewEnabled ) {
1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832

					if ( vr.isPresenting() ) {

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

					} else {

						var newMat = camera.matrixWorldInverse.clone();
						var newMat = new Matrix4();

						p_uniforms.setValue( _gl, 'viewMatrices', [camera.matrixWorldInverse, newMat] );

					}

				} else {

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

				}
1833 1834 1835

			}

M
Mr.doob 已提交
1836 1837 1838 1839 1840 1841
		}

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

1842
		if ( material.skinning ) {
M
Mr.doob 已提交
1843

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

T
tschw 已提交
1847
			var skeleton = object.skeleton;
1848

T
tschw 已提交
1849
			if ( skeleton ) {
1850

1851 1852
				var bones = skeleton.bones;

1853
				if ( capabilities.floatVertexTextures ) {
M
Mr.doob 已提交
1854

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

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

					}

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

T
tschw 已提交
1884
				} else {
M
Mr.doob 已提交
1885

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

				}

			}

		}

		if ( refreshMaterial ) {

1896 1897 1898
			p_uniforms.setValue( _gl, 'toneMappingExposure', _this.toneMappingExposure );
			p_uniforms.setValue( _gl, 'toneMappingWhitePoint', _this.toneMappingWhitePoint );

M
Mr.doob 已提交
1899
			if ( material.lights ) {
M
Mr.doob 已提交
1900

1901
				// the current material requires lighting info
M
Mr.doob 已提交
1902

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

T
tschw 已提交
1910
				markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
G
gero3 已提交
1911

T
tschw 已提交
1912
			}
G
gero3 已提交
1913

T
tschw 已提交
1914
			// refresh uniforms common to several materials
G
gero3 已提交
1915

T
tschw 已提交
1916
			if ( fog && material.fog ) {
G
gero3 已提交
1917

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

			}

1922
			if ( material.isMeshBasicMaterial ) {
M
Mr.doob 已提交
1923 1924 1925

				refreshUniformsCommon( m_uniforms, material );

1926
			} else if ( material.isMeshLambertMaterial ) {
M
Mr.doob 已提交
1927

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

1931
			} else if ( material.isMeshPhongMaterial ) {
M
Mr.doob 已提交
1932

1933
				refreshUniformsCommon( m_uniforms, material );
M
Mr.doob 已提交
1934

1935
				if ( material.isMeshToonMaterial ) {
M
Mr.doob 已提交
1936

1937
					refreshUniformsToon( m_uniforms, material );
M
Mr.doob 已提交
1938

1939
				} else {
1940

1941
					refreshUniformsPhong( m_uniforms, material );
1942

1943
				}
T
Takahiro 已提交
1944

1945
			} else if ( material.isMeshStandardMaterial ) {
T
Takahiro 已提交
1946

1947
				refreshUniformsCommon( m_uniforms, material );
1948

1949
				if ( material.isMeshPhysicalMaterial ) {
1950

1951
					refreshUniformsPhysical( m_uniforms, material );
W
WestLangley 已提交
1952

1953
				} else {
W
WestLangley 已提交
1954

1955
					refreshUniformsStandard( m_uniforms, material );
W
WestLangley 已提交
1956

1957
				}
W
WestLangley 已提交
1958

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

				refreshUniformsCommon( m_uniforms, material );

				refreshUniformsMatcap( m_uniforms, material );

1965
			} else if ( material.isMeshDepthMaterial ) {
M
Mr.doob 已提交
1966

1967
				refreshUniformsCommon( m_uniforms, material );
W
WestLangley 已提交
1968
				refreshUniformsDepth( m_uniforms, material );
1969

W
WestLangley 已提交
1970
			} else if ( material.isMeshDistanceMaterial ) {
1971

1972
				refreshUniformsCommon( m_uniforms, material );
W
WestLangley 已提交
1973
				refreshUniformsDistance( m_uniforms, material );
1974

1975
			} else if ( material.isMeshNormalMaterial ) {
M
Mr.doob 已提交
1976

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

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

				refreshUniformsLine( m_uniforms, material );

				if ( material.isLineDashedMaterial ) {

					refreshUniformsDash( m_uniforms, material );

				}

			} else if ( material.isPointsMaterial ) {

				refreshUniformsPoints( m_uniforms, material );

1994 1995 1996 1997
			} else if ( material.isSpriteMaterial ) {

				refreshUniformsSprites( m_uniforms, material );

1998 1999
			} else if ( material.isShadowMaterial ) {

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

M
Mr.doob 已提交
2003 2004
			}

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

2008 2009
			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 已提交
2010

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

		}

2015 2016
		if ( material.isShaderMaterial && material.uniformsNeedUpdate === true ) {

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

		}
M
Mr.doob 已提交
2021

2022 2023 2024 2025 2026 2027
		if ( material.isSpriteMaterial ) {

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

		}

T
tschw 已提交
2028
		// common matrices
M
Mr.doob 已提交
2029

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

T
tschw 已提交
2034
		return program;
A
arose 已提交
2035 2036 2037

	}

M
Mr.doob 已提交
2038 2039
	// Uniforms (refresh uniforms objects)

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

		uniforms.opacity.value = material.opacity;

2044 2045
		if ( material.color ) {

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

		}
M
Mr.doob 已提交
2049

2050
		if ( material.emissive ) {
M
Mr.doob 已提交
2051

2052
			uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );
M
Mr.doob 已提交
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 2080 2081
		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 已提交
2082
			uniforms.flipEnvMap.value = material.envMap.isCubeTexture ? - 1 : 1;
2083 2084 2085 2086

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

2087
			uniforms.maxMipLevel.value = properties.get( material.envMap ).__maxMipLevel;
2088

2089
		}
M
Mr.doob 已提交
2090

2091 2092 2093 2094 2095 2096 2097
		if ( material.lightMap ) {

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

		}

2098
		if ( material.aoMap ) {
2099

2100 2101
			uniforms.aoMap.value = material.aoMap;
			uniforms.aoMapIntensity.value = material.aoMapIntensity;
2102 2103 2104

		}

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

		var uvScaleMap;

		if ( material.map ) {

			uvScaleMap = material.map;

		} else if ( material.specularMap ) {

			uvScaleMap = material.specularMap;

2123 2124 2125 2126
		} else if ( material.displacementMap ) {

			uvScaleMap = material.displacementMap;

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

			uvScaleMap = material.normalMap;

		} else if ( material.bumpMap ) {

			uvScaleMap = material.bumpMap;

2135 2136 2137 2138 2139 2140 2141 2142
		} else if ( material.roughnessMap ) {

			uvScaleMap = material.roughnessMap;

		} else if ( material.metalnessMap ) {

			uvScaleMap = material.metalnessMap;

2143 2144 2145 2146
		} else if ( material.alphaMap ) {

			uvScaleMap = material.alphaMap;

2147 2148 2149 2150
		} else if ( material.emissiveMap ) {

			uvScaleMap = material.emissiveMap;

M
Mr.doob 已提交
2151 2152 2153 2154
		}

		if ( uvScaleMap !== undefined ) {

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

				uvScaleMap = uvScaleMap.texture;

			}

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

W
WestLangley 已提交
2164
				uvScaleMap.updateMatrix();
M
Mr.doob 已提交
2165

W
WestLangley 已提交
2166
			}
2167

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

		}

M
Mr.doob 已提交
2172
	}
M
Mr.doob 已提交
2173

M
Mr.doob 已提交
2174
	function refreshUniformsLine( uniforms, material ) {
M
Mr.doob 已提交
2175

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

M
Mr.doob 已提交
2179
	}
M
Mr.doob 已提交
2180

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

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

M
Mr.doob 已提交
2187
	}
M
Mr.doob 已提交
2188

M
Mr.doob 已提交
2189
	function refreshUniformsPoints( uniforms, material ) {
M
Mr.doob 已提交
2190

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

		uniforms.map.value = material.map;

2198 2199
		if ( material.map !== null ) {

W
WestLangley 已提交
2200
			if ( material.map.matrixAutoUpdate === true ) {
2201

W
WestLangley 已提交
2202
				material.map.updateMatrix();
W
WestLangley 已提交
2203 2204

			}
2205

2206
			uniforms.uvTransform.value.copy( material.map.matrix );
2207 2208 2209

		}

2210 2211 2212 2213
	}

	function refreshUniformsSprites( uniforms, material ) {

T
Takahiro 已提交
2214
		uniforms.diffuse.value.copy( material.color );
2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230
		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 已提交
2231
	}
M
Mr.doob 已提交
2232

M
Mr.doob 已提交
2233
	function refreshUniformsFog( uniforms, fog ) {
M
Mr.doob 已提交
2234

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

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

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

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

			uniforms.fogDensity.value = fog.density;

		}

M
Mr.doob 已提交
2248
	}
M
Mr.doob 已提交
2249

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

		if ( material.emissiveMap ) {

			uniforms.emissiveMap.value = material.emissiveMap;

		}

	}

M
Mr.doob 已提交
2260
	function refreshUniformsPhong( uniforms, material ) {
M
Mr.doob 已提交
2261

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

2265
		if ( material.emissiveMap ) {
2266

2267
			uniforms.emissiveMap.value = material.emissiveMap;
2268

2269
		}
M
Mr.doob 已提交
2270

2271 2272 2273 2274
		if ( material.bumpMap ) {

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

2277
		}
M
Mr.doob 已提交
2278

2279 2280 2281 2282
		if ( material.normalMap ) {

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

		}
M
Mr.doob 已提交
2286

2287 2288 2289 2290 2291
		if ( material.displacementMap ) {

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

2293
		}
2294

T
Takahiro 已提交
2295 2296 2297 2298 2299 2300
	}

	function refreshUniformsToon( uniforms, material ) {

		refreshUniformsPhong( uniforms, material );

T
Takahiro 已提交
2301
		if ( material.gradientMap ) {
T
Takahiro 已提交
2302

T
Takahiro 已提交
2303
			uniforms.gradientMap.value = material.gradientMap;
T
Takahiro 已提交
2304 2305 2306

		}

2307 2308
	}

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

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

		}

		if ( material.normalMap ) {

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

		}

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

2367 2368 2369 2370
		refreshUniformsStandard( uniforms, material );

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

2371 2372
		uniforms.clearcoat.value = material.clearcoat;
		uniforms.clearcoatRoughness.value = material.clearcoatRoughness;
2373
		if ( material.sheen ) uniforms.sheen.value.copy( material.sheen );
2374

2375
		if ( material.clearcoatNormalMap ) {
2376

2377 2378
			uniforms.clearcoatNormalScale.value.copy( material.clearcoatNormalScale );
			uniforms.clearcoatNormalMap.value = material.clearcoatNormalMap;
2379

A
Linting  
arobertson0 已提交
2380 2381
			if ( material.side === BackSide ) {

2382
				uniforms.clearcoatNormalScale.value.negate();
A
Linting  
arobertson0 已提交
2383

A
arobertson0 已提交
2384
			}
A
arobertson0 已提交
2385 2386

		}
2387

2388 2389
		uniforms.transparency.value = material.transparency;

W
WestLangley 已提交
2390 2391
	}

W
WestLangley 已提交
2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425
	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 已提交
2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453
	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;

	}

2454 2455 2456 2457 2458 2459
	function refreshUniformsNormal( uniforms, material ) {

		if ( material.bumpMap ) {

			uniforms.bumpMap.value = material.bumpMap;
			uniforms.bumpScale.value = material.bumpScale;
2460
			if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1;
2461 2462 2463 2464 2465 2466 2467

		}

		if ( material.normalMap ) {

			uniforms.normalMap.value = material.normalMap;
			uniforms.normalScale.value.copy( material.normalScale );
2468
			if ( material.side === BackSide ) uniforms.normalScale.value.negate();
2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481

		}

		if ( material.displacementMap ) {

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

		}

	}

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

M
Mr.doob 已提交
2484
	function markUniformsLightsNeedsUpdate( uniforms, value ) {
2485

M
Mr.doob 已提交
2486
		uniforms.ambientLightColor.needsUpdate = value;
W
WestLangley 已提交
2487
		uniforms.lightProbe.needsUpdate = value;
2488

B
Ben Houston 已提交
2489 2490 2491
		uniforms.directionalLights.needsUpdate = value;
		uniforms.pointLights.needsUpdate = value;
		uniforms.spotLights.needsUpdate = value;
2492
		uniforms.rectAreaLights.needsUpdate = value;
B
Ben Houston 已提交
2493
		uniforms.hemisphereLights.needsUpdate = value;
2494

M
Mr.doob 已提交
2495
	}
2496

2497 2498 2499
	//
	this.setFramebuffer = function ( value ) {

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

2502 2503 2504 2505
		_framebuffer = value;

	};

2506 2507 2508 2509 2510 2511
	this.getActiveCubeFace = function () {

		return _currentActiveCubeFace;

	};

2512
	this.getActiveMipmapLevel = function () {
2513 2514 2515 2516 2517

		return _currentActiveMipmapLevel;

	};

2518
	this.getRenderTarget = function () {
2519 2520 2521

		return _currentRenderTarget;

M
Michael Herzog 已提交
2522
	};
2523

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

2526
		_currentRenderTarget = renderTarget;
2527
		_currentActiveCubeFace = activeCubeFace;
2528
		_currentActiveMipmapLevel = activeMipmapLevel;
2529

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

2532
			textures.setupRenderTarget( renderTarget );
M
Mr.doob 已提交
2533 2534 2535

		}

2536
		var framebuffer = _framebuffer;
M
Mr.doob 已提交
2537
		var isCube = false;
M
Mr.doob 已提交
2538 2539 2540

		if ( renderTarget ) {

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

M
Mr.doob 已提交
2543
			if ( renderTarget.isWebGLRenderTargetCube ) {
M
Mr.doob 已提交
2544

2545
				framebuffer = __webglFramebuffer[ activeCubeFace || 0 ];
M
Mr.doob 已提交
2546
				isCube = true;
M
Mr.doob 已提交
2547

2548 2549 2550 2551
			} else if ( renderTarget.isWebGLMultisampleRenderTarget ) {

				framebuffer = properties.get( renderTarget ).__webglMultisampledFramebuffer;

M
Mr.doob 已提交
2552 2553
			} else {

M
Mr.doob 已提交
2554
				framebuffer = __webglFramebuffer;
M
Mr.doob 已提交
2555 2556 2557

			}

M
Mr.doob 已提交
2558
			_currentViewport.copy( renderTarget.viewport );
2559 2560
			_currentScissor.copy( renderTarget.scissor );
			_currentScissorTest = renderTarget.scissorTest;
2561

M
Mr.doob 已提交
2562 2563
		} else {

2564 2565
			_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ).floor();
			_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ).floor();
2566
			_currentScissorTest = _scissorTest;
2567

M
Mr.doob 已提交
2568 2569
		}

M
Mr.doob 已提交
2570
		if ( _currentFramebuffer !== framebuffer ) {
M
Mr.doob 已提交
2571 2572 2573 2574 2575 2576

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

		}

M
Mr.doob 已提交
2577
		state.viewport( _currentViewport );
2578 2579
		state.scissor( _currentScissor );
		state.setScissorTest( _currentScissorTest );
2580

M
Mr.doob 已提交
2581 2582 2583
		if ( isCube ) {

			var textureProperties = properties.get( renderTarget.texture );
2584
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + ( activeCubeFace || 0 ), textureProperties.__webglTexture, activeMipmapLevel || 0 );
M
Mr.doob 已提交
2585 2586 2587

		}

M
Mr.doob 已提交
2588 2589
	};

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

0
06wj 已提交
2592
		if ( ! ( renderTarget && renderTarget.isWebGLRenderTarget ) ) {
2593

2594
			console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
G
gero3 已提交
2595
			return;
2596

G
gero3 已提交
2597
		}
2598

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

2601
		if ( renderTarget.isWebGLRenderTargetCube && activeCubeFaceIndex !== undefined ) {
2602 2603 2604 2605 2606

			framebuffer = framebuffer[ activeCubeFaceIndex ];

		}

M
Mr.doob 已提交
2607
		if ( framebuffer ) {
2608

G
gero3 已提交
2609
			var restore = false;
2610

M
Mr.doob 已提交
2611
			if ( framebuffer !== _currentFramebuffer ) {
2612

M
Mr.doob 已提交
2613
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
2614

G
gero3 已提交
2615
				restore = true;
2616

G
gero3 已提交
2617
			}
2618

M
Mr.doob 已提交
2619
			try {
2620

M
Mr.doob 已提交
2621
				var texture = renderTarget.texture;
M
Mr.doob 已提交
2622 2623
				var textureFormat = texture.format;
				var textureType = texture.type;
2624

2625
				if ( textureFormat !== RGBAFormat && utils.convert( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {
2626

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

M
Mr.doob 已提交
2630
				}
2631

2632
				if ( textureType !== UnsignedByteType && utils.convert( textureType ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE ) && // IE11, Edge and Chrome Mac < 52 (#9513)
T
Takahiro 已提交
2633 2634
					! ( 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' ) ) ) ) {
2635

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

M
Mr.doob 已提交
2639
				}
2640

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

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

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

2647
						_gl.readPixels( x, y, width, height, utils.convert( textureFormat ), utils.convert( textureType ), buffer );
2648 2649

					}
2650

M
Mr.doob 已提交
2651
				} else {
M
Mr.doob 已提交
2652

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

				}
M
Mr.doob 已提交
2656

M
Mr.doob 已提交
2657
			} finally {
M
Mr.doob 已提交
2658

M
Mr.doob 已提交
2659 2660 2661
				if ( restore ) {

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

M
Mr.doob 已提交
2663 2664 2665
				}

			}
M
Mr.doob 已提交
2666 2667 2668

		}

M
Mr.doob 已提交
2669 2670
	};

2671
	this.copyFramebufferToTexture = function ( position, texture, level ) {
2672 2673 2674

		var width = texture.image.width;
		var height = texture.image.height;
2675
		var glFormat = utils.convert( texture.format );
2676

2677
		textures.setTexture2D( texture, 0 );
2678

2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689
		_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 );

2690
		textures.setTexture2D( dstTexture, 0 );
2691

2692 2693 2694 2695 2696 2697 2698 2699 2700
		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 );

		}
2701 2702 2703

	};

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

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

2708
	}
R
Rich Harris 已提交
2709

M
Mr.doob 已提交
2710
}
T
Tristan VALCKE 已提交
2711

2712
export { WebGLRenderer };