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

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

	parameters = parameters || {};

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

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 70
		_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false,
		_powerPreference = parameters.powerPreference !== undefined ? parameters.powerPreference : 'default';
M
Mr.doob 已提交
71

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

M
Mr.doob 已提交
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
	// public properties

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

	// clearing

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

	// scene graph

	this.sortObjects = true;

T
tschw 已提交
91 92 93 94 95
	// user-defined clipping

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

M
Mr.doob 已提交
96 97
	// physically based shading

98
	this.gammaFactor = 2.0;	// for backwards compatibility
M
Mr.doob 已提交
99 100 101
	this.gammaInput = false;
	this.gammaOutput = false;

102 103
	// physical lights

104
	this.physicallyCorrectLights = false;
105

B
Ben Houston 已提交
106 107
	// tone mapping

R
Rich Harris 已提交
108
	this.toneMapping = LinearToneMapping;
B
Ben Houston 已提交
109 110 111
	this.toneMappingExposure = 1.0;
	this.toneMappingWhitePoint = 1.0;

M
Mr.doob 已提交
112 113 114 115 116 117 118 119 120
	// morphs

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

	// internal properties

	var _this = this,

121 122
		_isContextLost = false,

123
		// internal state cache
M
Mr.doob 已提交
124

125 126
		_framebuffer = null,

127 128 129
		_currentRenderTarget = null,
		_currentFramebuffer = null,
		_currentMaterialId = - 1,
130 131 132 133

		// geometry and program caching

		_currentGeometryProgram = {
M
Mr.doob 已提交
134 135
			geometry: null,
			program: null,
136 137
			wireframe: false
		},
138

139
		_currentCamera = null,
140
		_currentArrayCamera = null,
M
Mr.doob 已提交
141

M
Mr.doob 已提交
142
		_currentViewport = new Vector4(),
143 144
		_currentScissor = new Vector4(),
		_currentScissorTest = null,
145

146
		//
147

148
		_usedTextureUnits = 0,
M
Mr.doob 已提交
149

150
		//
M
Mr.doob 已提交
151

152 153
		_width = _canvas.width,
		_height = _canvas.height,
M
Mr.doob 已提交
154

155
		_pixelRatio = 1,
M
Mr.doob 已提交
156

M
Mr.doob 已提交
157
		_viewport = new Vector4( 0, 0, _width, _height ),
158 159
		_scissor = new Vector4( 0, 0, _width, _height ),
		_scissorTest = false,
160

161
		// frustum
M
Mr.doob 已提交
162

163
		_frustum = new Frustum(),
M
Mr.doob 已提交
164

165
		// clipping
T
tschw 已提交
166

167 168 169
		_clipping = new WebGLClipping(),
		_clippingEnabled = false,
		_localClippingEnabled = false,
T
tschw 已提交
170

171
		// camera matrices cache
M
Mr.doob 已提交
172

173
		_projScreenMatrix = new Matrix4(),
M
Mr.doob 已提交
174

M
Mugen87 已提交
175
		_vector3 = new Vector3();
A
Atrahasis 已提交
176

177 178 179 180 181
	function getTargetPixelRatio() {

		return _currentRenderTarget === null ? _pixelRatio : 1;

	}
182

M
Mr.doob 已提交
183 184 185 186
	// initialize

	var _gl;

M
Mr.doob 已提交
187 188
	try {

189
		var contextAttributes = {
M
Mr.doob 已提交
190 191 192 193 194
			alpha: _alpha,
			depth: _depth,
			stencil: _stencil,
			antialias: _antialias,
			premultipliedAlpha: _premultipliedAlpha,
195
			preserveDrawingBuffer: _preserveDrawingBuffer,
L
Luigi De Rosa 已提交
196
			powerPreference: _powerPreference
M
Mr.doob 已提交
197 198
		};

199 200
		// event listeners must be registered before WebGL context is created, see #12753

201
		_canvas.addEventListener( 'webglcontextlost', onContextLost, false );
202
		_canvas.addEventListener( 'webglcontextrestored', onContextRestore, false );
203

204
		_gl = _context || _canvas.getContext( 'webgl', contextAttributes ) || _canvas.getContext( 'experimental-webgl', contextAttributes );
M
Mr.doob 已提交
205 206 207

		if ( _gl === null ) {

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

D
Daniel Hritzkiv 已提交
210
				throw new Error( 'Error creating WebGL context with your selected attributes.' );
211 212 213

			} else {

D
Daniel Hritzkiv 已提交
214
				throw new Error( 'Error creating WebGL context.' );
215 216

			}
M
Mr.doob 已提交
217 218 219

		}

220 221 222 223 224 225 226 227 228 229 230 231
		// 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 已提交
232 233
	} catch ( error ) {

D
Daniel Hritzkiv 已提交
234
		console.error( 'THREE.WebGLRenderer: ' + error.message );
M
Mr.doob 已提交
235 236 237

	}

M
Mugen87 已提交
238
	var extensions, capabilities, state, info;
239
	var properties, textures, attributes, geometries, objects;
240
	var programCache, renderLists, renderStates;
241

242
	var background, morphtargets, bufferRenderer, indexedBufferRenderer;
243

244
	var utils;
245

246
	function initGLContext() {
247

248
		extensions = new WebGLExtensions( _gl );
249

T
Takahiro 已提交
250 251 252
		capabilities = new WebGLCapabilities( _gl, extensions, parameters );

		if ( ! capabilities.isWebGL2 ) {
253 254 255 256 257 258 259 260 261 262 263

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

		}

264
		extensions.get( 'OES_texture_float_linear' );
265

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

T
Takahiro 已提交
268
		state = new WebGLState( _gl, extensions, utils, capabilities );
269 270
		state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );
		state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );
M
Mr.doob 已提交
271

M
Mugen87 已提交
272
		info = new WebGLInfo( _gl );
273
		properties = new WebGLProperties();
M
Mugen87 已提交
274
		textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info );
275
		attributes = new WebGLAttributes( _gl );
M
Mugen87 已提交
276 277
		geometries = new WebGLGeometries( _gl, attributes, info );
		objects = new WebGLObjects( geometries, info );
278
		morphtargets = new WebGLMorphtargets( _gl );
279
		programCache = new WebGLPrograms( _this, extensions, capabilities );
280
		renderLists = new WebGLRenderLists();
281
		renderStates = new WebGLRenderStates();
M
Mr.doob 已提交
282

283
		background = new WebGLBackground( _this, state, objects, _premultipliedAlpha );
284

T
Takahiro 已提交
285 286
		bufferRenderer = new WebGLBufferRenderer( _gl, extensions, info, capabilities );
		indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, info, capabilities );
287

M
Mugen87 已提交
288
		info.programs = programCache.programs;
289

290 291 292 293 294 295
		_this.context = _gl;
		_this.capabilities = capabilities;
		_this.extensions = extensions;
		_this.properties = properties;
		_this.renderLists = renderLists;
		_this.state = state;
M
Mugen87 已提交
296
		_this.info = info;
M
Mr.doob 已提交
297

298
	}
M
Mr.doob 已提交
299

300
	initGLContext();
M
Mr.doob 已提交
301

302
	// vr
M
Mr.doob 已提交
303

304 305 306 307 308 309 310
	var vr = null;

	if ( typeof navigator !== 'undefined' ) {

		vr = ( 'xr' in navigator ) ? new WebXRManager( _this ) : new WebVRManager( _this );

	}
M
Mr.doob 已提交
311

312
	this.vr = vr;
M
Mr.doob 已提交
313 314

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

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

318
	this.shadowMap = shadowMap;
M
Mr.doob 已提交
319

M
Mr.doob 已提交
320 321 322 323 324 325 326 327
	// API

	this.getContext = function () {

		return _gl;

	};

328 329 330 331 332 333
	this.getContextAttributes = function () {

		return _gl.getContextAttributes();

	};

334 335
	this.forceContextLoss = function () {

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

	};

341
	this.forceContextRestore = function () {
M
Mr.doob 已提交
342

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

	};

348 349
	this.getPixelRatio = function () {

350
		return _pixelRatio;
351 352 353 354 355

	};

	this.setPixelRatio = function ( value ) {

356 357 358 359
		if ( value === undefined ) return;

		_pixelRatio = value;

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

	};

364
	this.getSize = function ( target ) {
365

366 367 368 369 370 371 372 373 374
		if ( target === undefined ) {

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

			target = new Vector2();

		}

		return target.set( _width, _height );
375 376 377

	};

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

M
Mr.doob 已提交
380
		if ( vr.isPresenting() ) {
381 382 383 384 385 386

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

		}

387 388 389
		_width = width;
		_height = height;

390 391
		_canvas.width = width * _pixelRatio;
		_canvas.height = height * _pixelRatio;
392

393
		if ( updateStyle !== false ) {
394

G
gero3 已提交
395 396
			_canvas.style.width = width + 'px';
			_canvas.style.height = height + 'px';
397

G
gero3 已提交
398
		}
M
Mr.doob 已提交
399

400
		this.setViewport( 0, 0, width, height );
M
Mr.doob 已提交
401 402 403

	};

404
	this.getDrawingBufferSize = function ( target ) {
M
Mr.doob 已提交
405

406 407 408 409 410 411 412 413 414
		if ( target === undefined ) {

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

			target = new Vector2();

		}

		return target.set( _width * _pixelRatio, _height * _pixelRatio );
M
Mr.doob 已提交
415 416 417

	};

418 419 420 421 422 423 424 425 426 427 428 429 430 431
	this.setDrawingBufferSize = function ( width, height, pixelRatio ) {

		_width = width;
		_height = height;

		_pixelRatio = pixelRatio;

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

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

	};

432
	this.getCurrentViewport = function () {
M
Mugen87 已提交
433

434
		return _currentViewport;
M
Mugen87 已提交
435 436 437

	};

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

440
		_viewport.set( x, y, width, height );
441
		state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );
442

M
Mr.doob 已提交
443 444
	};

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

447
		_scissor.set( x, y, width, height );
448
		state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );
449

M
Mr.doob 已提交
450 451
	};

452 453
	this.setScissorTest = function ( boolean ) {

454
		state.setScissorTest( _scissorTest = boolean );
M
Mr.doob 已提交
455 456 457 458 459

	};

	// Clearing

M
Mr.doob 已提交
460
	this.getClearColor = function () {
M
Mr.doob 已提交
461

462
		return background.getClearColor();
M
Mr.doob 已提交
463 464 465

	};

466
	this.setClearColor = function () {
467

468
		background.setClearColor.apply( background, arguments );
M
Mr.doob 已提交
469 470 471

	};

M
Mr.doob 已提交
472
	this.getClearAlpha = function () {
M
Mr.doob 已提交
473

474
		return background.getClearAlpha();
M
Mr.doob 已提交
475 476 477

	};

M
Mugen87 已提交
478
	this.setClearAlpha = function () {
M
Mr.doob 已提交
479

480
		background.setClearAlpha.apply( background, arguments );
M
Mr.doob 已提交
481 482 483 484 485 486 487 488 489 490 491 492

	};

	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 );
493 494 495 496 497

	};

	this.clearColor = function () {

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

	};

	this.clearDepth = function () {

M
Mr.doob 已提交
504
		this.clear( false, true, false );
505 506 507 508 509

	};

	this.clearStencil = function () {

M
Mr.doob 已提交
510
		this.clear( false, false, true );
M
Mr.doob 已提交
511 512 513

	};

M
Mr.doob 已提交
514
	//
M
Mr.doob 已提交
515

M
Mr.doob 已提交
516
	this.dispose = function () {
D
dubejf 已提交
517 518

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

521
		renderLists.dispose();
522
		renderStates.dispose();
M
Mugen87 已提交
523 524
		properties.dispose();
		objects.dispose();
525

526
		vr.dispose();
527

528
		animation.stop();
B
brunnerh 已提交
529

D
dubejf 已提交
530 531
	};

M
Mr.doob 已提交
532
	// Events
M
Mr.doob 已提交
533

D
dubejf 已提交
534 535 536 537
	function onContextLost( event ) {

		event.preventDefault();

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

540 541 542 543
		_isContextLost = true;

	}

M
Mugen87 已提交
544
	function onContextRestore( /* event */ ) {
D
dubejf 已提交
545

546
		console.log( 'THREE.WebGLRenderer: Context Restored.' );
547 548

		_isContextLost = false;
D
dubejf 已提交
549

550
		initGLContext();
D
dubejf 已提交
551

M
Mr.doob 已提交
552
	}
D
dubejf 已提交
553

554
	function onMaterialDispose( event ) {
M
Mr.doob 已提交
555 556 557 558 559 560 561

		var material = event.target;

		material.removeEventListener( 'dispose', onMaterialDispose );

		deallocateMaterial( material );

562
	}
M
Mr.doob 已提交
563 564 565

	// Buffer deallocation

566
	function deallocateMaterial( material ) {
M
Mr.doob 已提交
567

568 569
		releaseMaterialProgramReference( material );

570
		properties.remove( material );
571

572
	}
573 574


575
	function releaseMaterialProgramReference( material ) {
576

577
		var programInfo = properties.get( material ).program;
M
Mr.doob 已提交
578 579 580

		material.program = undefined;

581
		if ( programInfo !== undefined ) {
M
Mr.doob 已提交
582

583
			programCache.releaseProgram( programInfo );
M
Mr.doob 已提交
584

M
Mr.doob 已提交
585 586
		}

587
	}
M
Mr.doob 已提交
588 589 590

	// Buffer rendering

M
Mr.doob 已提交
591
	function renderObjectImmediate( object, program ) {
M
Mr.doob 已提交
592 593 594

		object.render( function ( object ) {

M
Mr.doob 已提交
595
			_this.renderBufferImmediate( object, program );
M
Mr.doob 已提交
596 597 598 599 600

		} );

	}

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

603
		state.initAttributes();
604

605
		var buffers = properties.get( object );
606

607 608 609 610
		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 已提交
611

612
		var programAttributes = program.getAttributes();
613

M
Mr.doob 已提交
614 615
		if ( object.hasPositions ) {

616
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );
M
Mr.doob 已提交
617
			_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );
618

619 620
			state.enableAttribute( programAttributes.position );
			_gl.vertexAttribPointer( programAttributes.position, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
621 622 623 624 625

		}

		if ( object.hasNormals ) {

626
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.normal );
M
Mr.doob 已提交
627
			_gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );
628

629 630
			state.enableAttribute( programAttributes.normal );
			_gl.vertexAttribPointer( programAttributes.normal, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
631 632 633

		}

634
		if ( object.hasUvs ) {
M
Mr.doob 已提交
635

636
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );
M
Mr.doob 已提交
637
			_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );
638

639
			state.enableAttribute( programAttributes.uv );
640
			_gl.vertexAttribPointer( programAttributes.uv, 2, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
641 642 643

		}

644
		if ( object.hasColors ) {
M
Mr.doob 已提交
645

646
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );
M
Mr.doob 已提交
647
			_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );
648

649 650
			state.enableAttribute( programAttributes.color );
			_gl.vertexAttribPointer( programAttributes.color, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
651 652 653

		}

654
		state.disableUnusedAttributes();
655

M
Mr.doob 已提交
656 657 658 659 660 661
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );

		object.count = 0;

	};

662
	this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {
663

664
		var frontFaceCW = ( object.isMesh && object.normalMatrix.determinant() < 0 );
665 666

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

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

M
Mr.doob 已提交
670
		var updateBuffers = false;
M
Mr.doob 已提交
671

672 673 674
		if ( _currentGeometryProgram.geometry !== geometry.id ||
			_currentGeometryProgram.program !== program.id ||
			_currentGeometryProgram.wireframe !== ( material.wireframe === true ) ) {
M
Mr.doob 已提交
675

M
Mr.doob 已提交
676 677
			_currentGeometryProgram.geometry = geometry.id;
			_currentGeometryProgram.program = program.id;
678
			_currentGeometryProgram.wireframe = material.wireframe === true;
M
Mr.doob 已提交
679 680 681 682
			updateBuffers = true;

		}

683
		if ( object.morphTargetInfluences ) {
684

685
			morphtargets.update( object, geometry, material, program );
M
Mr.doob 已提交
686 687 688 689 690

			updateBuffers = true;

		}

691 692
		//

693
		var index = geometry.index;
694
		var position = geometry.attributes.position;
695
		var rangeFactor = 1;
696

697 698
		if ( material.wireframe === true ) {

699
			index = geometries.getWireframeAttribute( geometry );
700
			rangeFactor = 2;
701 702 703

		}

M
Mr.doob 已提交
704
		var attribute;
M
Mr.doob 已提交
705
		var renderer = bufferRenderer;
706

707
		if ( index !== null ) {
708

M
Mr.doob 已提交
709
			attribute = attributes.get( index );
710

711
			renderer = indexedBufferRenderer;
M
Mr.doob 已提交
712
			renderer.setIndex( attribute );
713

714
		}
M
Mr.doob 已提交
715

716
		if ( updateBuffers ) {
M
Mr.doob 已提交
717

718
			setupVertexAttributes( material, program, geometry );
M
Mr.doob 已提交
719

720
			if ( index !== null ) {
721

M
Mr.doob 已提交
722
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, attribute.buffer );
723 724 725

			}

726
		}
727

728 729
		//

730
		var dataCount = Infinity;
731

M
Mr.doob 已提交
732
		if ( index !== null ) {
733

M
Mr.doob 已提交
734
			dataCount = index.count;
735

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

M
Mr.doob 已提交
738
			dataCount = position.count;
739

M
Mr.doob 已提交
740
		}
741

M
Mr.doob 已提交
742 743
		var rangeStart = geometry.drawRange.start * rangeFactor;
		var rangeCount = geometry.drawRange.count * rangeFactor;
744

M
Mr.doob 已提交
745 746
		var groupStart = group !== null ? group.start * rangeFactor : 0;
		var groupCount = group !== null ? group.count * rangeFactor : Infinity;
747

M
Mr.doob 已提交
748
		var drawStart = Math.max( rangeStart, groupStart );
749
		var drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1;
M
Mr.doob 已提交
750 751 752

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

753 754
		if ( drawCount === 0 ) return;

M
Mr.doob 已提交
755
		//
756

757
		if ( object.isMesh ) {
758

759
			if ( material.wireframe === true ) {
760

761
				state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );
762
				renderer.setMode( _gl.LINES );
763

764
			} else {
M
Mr.doob 已提交
765 766

				switch ( object.drawMode ) {
767

R
Rich Harris 已提交
768
					case TrianglesDrawMode:
B
Ben Adams 已提交
769 770 771
						renderer.setMode( _gl.TRIANGLES );
						break;

R
Rich Harris 已提交
772
					case TriangleStripDrawMode:
B
Ben Adams 已提交
773 774 775
						renderer.setMode( _gl.TRIANGLE_STRIP );
						break;

R
Rich Harris 已提交
776
					case TriangleFanDrawMode:
B
Ben Adams 已提交
777 778 779 780
						renderer.setMode( _gl.TRIANGLE_FAN );
						break;

				}
781

782
			}
783

784

785
		} else if ( object.isLine ) {
786

787
			var lineWidth = material.linewidth;
788

789
			if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material
790

791
			state.setLineWidth( lineWidth * getTargetPixelRatio() );
792

793
			if ( object.isLineSegments ) {
794

795
				renderer.setMode( _gl.LINES );
796

797 798 799 800
			} else if ( object.isLineLoop ) {

				renderer.setMode( _gl.LINE_LOOP );

801
			} else {
802

803
				renderer.setMode( _gl.LINE_STRIP );
804 805

			}
M
Mr.doob 已提交
806

807
		} else if ( object.isPoints ) {
808 809

			renderer.setMode( _gl.POINTS );
810

811 812 813 814
		} else if ( object.isSprite ) {

			renderer.setMode( _gl.TRIANGLES );

815
		}
816

T
Takahiro 已提交
817
		if ( geometry && geometry.isInstancedBufferGeometry ) {
M
Mr.doob 已提交
818 819 820

			if ( geometry.maxInstancedCount > 0 ) {

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

J
jfranc 已提交
823
			}
824 825 826

		} else {

M
Mr.doob 已提交
827
			renderer.render( drawStart, drawCount );
828

M
Mr.doob 已提交
829 830 831 832
		}

	};

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

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

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

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

M
Mr.doob 已提交
842 843 844
			}

		}
B
Ben Adams 已提交
845

846 847
		state.initAttributes();

848
		var geometryAttributes = geometry.attributes;
849

850
		var programAttributes = program.getAttributes();
851

852
		var materialDefaultAttributeValues = material.defaultAttributeValues;
853

854
		for ( var name in programAttributes ) {
855

856
			var programAttribute = programAttributes[ name ];
M
Mr.doob 已提交
857

M
Mr.doob 已提交
858
			if ( programAttribute >= 0 ) {
M
Mr.doob 已提交
859

860
				var geometryAttribute = geometryAttributes[ name ];
861

M
Mr.doob 已提交
862
				if ( geometryAttribute !== undefined ) {
M
Mr.doob 已提交
863

864
					var normalized = geometryAttribute.normalized;
865
					var size = geometryAttribute.itemSize;
866

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

869 870 871 872
					// TODO Attribute may not be available on context restore

					if ( attribute === undefined ) continue;

M
Mr.doob 已提交
873 874 875
					var buffer = attribute.buffer;
					var type = attribute.type;
					var bytesPerElement = attribute.bytesPerElement;
876

A
aardgoose 已提交
877
					if ( geometryAttribute.isInterleavedBufferAttribute ) {
878

M
Mr.doob 已提交
879 880 881 882
						var data = geometryAttribute.data;
						var stride = data.stride;
						var offset = geometryAttribute.offset;

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

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

M
Mr.doob 已提交
887
							if ( geometry.maxInstancedCount === undefined ) {
888

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

M
Mr.doob 已提交
891
							}
B
Ben Adams 已提交
892

M
Mr.doob 已提交
893
						} else {
B
Ben Adams 已提交
894

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

M
Mr.doob 已提交
897
						}
B
Ben Adams 已提交
898

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

M
Mr.doob 已提交
902
					} else {
B
Ben Adams 已提交
903

A
aardgoose 已提交
904
						if ( geometryAttribute.isInstancedBufferAttribute ) {
B
Ben Adams 已提交
905

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

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

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

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

M
Mr.doob 已提交
914 915 916 917
						} else {

							state.enableAttribute( programAttribute );

M
Mr.doob 已提交
918
						}
B
Ben Adams 已提交
919

M
Mr.doob 已提交
920
						_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
921
						_gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, 0 );
M
Mr.doob 已提交
922

B
Ben Adams 已提交
923
					}
M
Mr.doob 已提交
924

925 926
				} else if ( materialDefaultAttributeValues !== undefined ) {

T
tschw 已提交
927
					var value = materialDefaultAttributeValues[ name ];
928

929
					if ( value !== undefined ) {
M
Mr.doob 已提交
930

931
						switch ( value.length ) {
M
Mr.doob 已提交
932

933 934 935
							case 2:
								_gl.vertexAttrib2fv( programAttribute, value );
								break;
M
Mr.doob 已提交
936

937 938 939
							case 3:
								_gl.vertexAttrib3fv( programAttribute, value );
								break;
M
Mr.doob 已提交
940

941 942 943
							case 4:
								_gl.vertexAttrib4fv( programAttribute, value );
								break;
944

945 946
							default:
								_gl.vertexAttrib1fv( programAttribute, value );
947 948

						}
M
Mr.doob 已提交
949 950 951 952 953 954 955 956

					}

				}

			}

		}
957

958
		state.disableUnusedAttributes();
959

M
Mr.doob 已提交
960 961
	}

M
Mr.doob 已提交
962
	// Compile
M
Mr.doob 已提交
963

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

M
Mr.doob 已提交
966
		currentRenderState = renderStates.get( scene, camera );
967
		currentRenderState.init();
968

M
Mr.doob 已提交
969
		scene.traverse( function ( object ) {
G
gero3 已提交
970 971

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

973
				currentRenderState.pushLight( object );
974 975 976

				if ( object.castShadow ) {

977
					currentRenderState.pushShadow( object );
978 979

				}
M
Mr.doob 已提交
980

G
gero3 已提交
981
			}
M
Mr.doob 已提交
982 983 984

		} );

985
		currentRenderState.setupLights( camera );
M
Mr.doob 已提交
986 987 988 989 990

		scene.traverse( function ( object ) {

			if ( object.material ) {

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

G
gero3 已提交
993
					for ( var i = 0; i < object.material.length; i ++ ) {
M
Mr.doob 已提交
994 995 996

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

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

G
gero3 已提交
999
				} else {
M
Mr.doob 已提交
1000 1001 1002

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

G
gero3 已提交
1003
				}
M
Mr.doob 已提交
1004

G
gero3 已提交
1005
			}
M
Mr.doob 已提交
1006 1007

		} );
G
gero3 已提交
1008 1009

	};
1010

1011
	// Animation Loop
M
Mr.doob 已提交
1012

M
Mr.doob 已提交
1013
	var onAnimationFrameCallback = null;
1014

1015
	function onAnimationFrame( time ) {
1016

M
Mr.doob 已提交
1017
		if ( vr.isPresenting() ) return;
1018
		if ( onAnimationFrameCallback ) onAnimationFrameCallback( time );
1019

1020
	}
1021

M
Mr.doob 已提交
1022 1023
	var animation = new WebGLAnimation();
	animation.setAnimationLoop( onAnimationFrame );
1024 1025

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

1027
	this.setAnimationLoop = function ( callback ) {
1028

M
Mr.doob 已提交
1029 1030
		onAnimationFrameCallback = callback;
		vr.setAnimationLoop( callback );
1031

1032 1033
		animation.start();

1034 1035
	};

M
Mr.doob 已提交
1036 1037
	// Rendering

1038 1039
	this.render = function ( scene, camera ) {

M
Mr.doob 已提交
1040
		var renderTarget, forceClear;
1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054

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

		}
1055

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

1058
			console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );
M
Mr.doob 已提交
1059 1060 1061 1062
			return;

		}

1063 1064
		if ( _isContextLost ) return;

M
Mr.doob 已提交
1065 1066
		// reset caching for this frame

M
Mr.doob 已提交
1067 1068
		_currentGeometryProgram.geometry = null;
		_currentGeometryProgram.program = null;
1069
		_currentGeometryProgram.wireframe = false;
1070
		_currentMaterialId = - 1;
1071
		_currentCamera = null;
M
Mr.doob 已提交
1072 1073 1074

		// update scene graph

1075
		if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
M
Mr.doob 已提交
1076 1077 1078

		// update camera matrices and frustum

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

1081 1082 1083 1084 1085 1086
		if ( vr.enabled ) {

			camera = vr.getCamera( camera );

		}

1087 1088
		//

1089 1090
		currentRenderState = renderStates.get( scene, camera );
		currentRenderState.init();
1091

1092 1093
		scene.onBeforeRender( _this, scene, camera, renderTarget );

M
Mr.doob 已提交
1094 1095 1096
		_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
		_frustum.setFromMatrix( _projScreenMatrix );

T
tschw 已提交
1097
		_localClippingEnabled = this.localClippingEnabled;
M
Mr.doob 已提交
1098
		_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );
T
tschw 已提交
1099

1100 1101 1102
		currentRenderList = renderLists.get( scene, camera );
		currentRenderList.init();

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

M
Mr.doob 已提交
1105
		if ( _this.sortObjects === true ) {
1106

1107
			currentRenderList.sort();
M
Mr.doob 已提交
1108

1109 1110
		}

M
Mr.doob 已提交
1111
		//
M
Mr.doob 已提交
1112

T
tschw 已提交
1113
		if ( _clippingEnabled ) _clipping.beginShadows();
T
tschw 已提交
1114

1115
		var shadowsArray = currentRenderState.state.shadowsArray;
1116

1117
		shadowMap.render( shadowsArray, scene, camera );
1118

1119
		currentRenderState.setupLights( camera );
1120

T
tschw 已提交
1121
		if ( _clippingEnabled ) _clipping.endShadows();
T
tschw 已提交
1122

M
Mr.doob 已提交
1123 1124
		//

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

1127
		if ( renderTarget !== undefined ) {
1128

1129
			this.setRenderTarget( renderTarget );
1130 1131 1132

		}

M
Mr.doob 已提交
1133 1134
		//

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

1137
		// render scene
M
Mr.doob 已提交
1138

1139 1140 1141
		var opaqueObjects = currentRenderList.opaque;
		var transparentObjects = currentRenderList.transparent;

M
Mr.doob 已提交
1142 1143
		if ( scene.overrideMaterial ) {

1144
			var overrideMaterial = scene.overrideMaterial;
M
Mr.doob 已提交
1145

M
Mr.doob 已提交
1146 1147
			if ( opaqueObjects.length ) renderObjects( opaqueObjects, scene, camera, overrideMaterial );
			if ( transparentObjects.length ) renderObjects( transparentObjects, scene, camera, overrideMaterial );
1148

M
Mr.doob 已提交
1149 1150
		} else {

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

M
Mr.doob 已提交
1153
			if ( opaqueObjects.length ) renderObjects( opaqueObjects, scene, camera );
1154 1155 1156

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

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

1159
		}
M
Mr.doob 已提交
1160

1161
		//
M
Mr.doob 已提交
1162

M
Mr.doob 已提交
1163
		if ( renderTarget !== undefined ) {
M
Mr.doob 已提交
1164

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

1167
			textures.updateRenderTargetMipmap( renderTarget );
M
Mr.doob 已提交
1168

M
Mugen87 已提交
1169
			// resolve multisample renderbuffers to a single-sample texture if necessary
1170 1171 1172

			textures.updateMultisampleRenderTarget( renderTarget );

M
Mr.doob 已提交
1173 1174
		}

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

1177 1178 1179
		state.buffers.depth.setTest( true );
		state.buffers.depth.setMask( true );
		state.buffers.color.setMask( true );
M
Mr.doob 已提交
1180

1181
		state.setPolygonOffset( false );
1182

1183
		scene.onAfterRender( _this, scene, camera );
1184

M
Mr.doob 已提交
1185
		if ( vr.enabled ) {
1186

1187
			vr.submitFrame();
1188

M
Mr.doob 已提交
1189
		}
M
Mr.doob 已提交
1190

M
Mr.doob 已提交
1191 1192
		// _gl.finish();

1193
		currentRenderList = null;
1194
		currentRenderState = null;
1195

M
Mr.doob 已提交
1196
	};
M
Mr.doob 已提交
1197

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

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

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

1204
		if ( visible ) {
1205

1206 1207 1208 1209 1210
			if ( object.isGroup ) {

				groupOrder = object.renderOrder;

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

1212
				currentRenderState.pushLight( object );
1213 1214 1215

				if ( object.castShadow ) {

1216
					currentRenderState.pushShadow( object );
1217 1218

				}
M
Mr.doob 已提交
1219

1220
			} else if ( object.isSprite ) {
M
Mr.doob 已提交
1221

1222
				if ( ! object.frustumCulled || _frustum.intersectsSprite( object ) ) {
1223

1224 1225 1226 1227 1228 1229 1230 1231 1232 1233
					if ( sortObjects ) {

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

					}

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

1234
					currentRenderList.push( object, geometry, material, groupOrder, _vector3.z, null );
M
Mr.doob 已提交
1235

1236
				}
M
Mr.doob 已提交
1237

1238
			} else if ( object.isImmediateRenderObject ) {
M
Mr.doob 已提交
1239

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

1242 1243
					_vector3.setFromMatrixPosition( object.matrixWorld )
						.applyMatrix4( _projScreenMatrix );
M
Mr.doob 已提交
1244

1245
				}
M
Mr.doob 已提交
1246

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

1249
			} else if ( object.isMesh || object.isLine || object.isPoints ) {
1250

1251
				if ( object.isSkinnedMesh ) {
1252

1253
					object.skeleton.update();
1254

1255
				}
1256

1257
				if ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) {
1258

1259 1260 1261 1262 1263 1264
					if ( sortObjects ) {

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

					}
1265

1266 1267
					var geometry = objects.update( object );
					var material = object.material;
1268

1269
					if ( Array.isArray( material ) ) {
1270

1271
						var groups = geometry.groups;
1272

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

1275 1276
							var group = groups[ i ];
							var groupMaterial = material[ group.materialIndex ];
1277

1278
							if ( groupMaterial && groupMaterial.visible ) {
1279

1280
								currentRenderList.push( object, geometry, groupMaterial, groupOrder, _vector3.z, group );
1281 1282

							}
M
Mr.doob 已提交
1283

M
Mr.doob 已提交
1284
						}
M
Mr.doob 已提交
1285

1286
					} else if ( material.visible ) {
1287

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

1290
					}
M
Mr.doob 已提交
1291

1292
				}
M
Mr.doob 已提交
1293

1294
			}
M
Mr.doob 已提交
1295

M
Mr.doob 已提交
1296
		}
M
Mr.doob 已提交
1297

M
Mr.doob 已提交
1298
		var children = object.children;
M
Mr.doob 已提交
1299

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

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

1304
		}
1305

1306
	}
M
Mr.doob 已提交
1307

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

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

1312
			var renderItem = renderList[ i ];
M
Mr.doob 已提交
1313

1314
			var object = renderItem.object;
M
Mr.doob 已提交
1315 1316 1317
			var geometry = renderItem.geometry;
			var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;
			var group = renderItem.group;
M
Mr.doob 已提交
1318

M
Mr.doob 已提交
1319
			if ( camera.isArrayCamera ) {
M
Mr.doob 已提交
1320

1321 1322
				_currentArrayCamera = camera;

M
Mr.doob 已提交
1323
				var cameras = camera.cameras;
M
Mr.doob 已提交
1324

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

M
Mr.doob 已提交
1327
					var camera2 = cameras[ j ];
M
Mr.doob 已提交
1328

1329
					if ( object.layers.test( camera2.layers ) ) {
1330

M
Mr.doob 已提交
1331 1332 1333 1334 1335 1336 1337
						if ( 'viewport' in camera2 ) { // XR

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

						} else {

							var bounds = camera2.bounds;
1338

M
Mr.doob 已提交
1339 1340 1341 1342
							var x = bounds.x * _width;
							var y = bounds.y * _height;
							var width = bounds.z * _width;
							var height = bounds.w * _height;
M
Mr.doob 已提交
1343

M
Mr.doob 已提交
1344 1345 1346
							state.viewport( _currentViewport.set( x, y, width, height ).multiplyScalar( _pixelRatio ) );

						}
1347

1348 1349
						currentRenderState.setupLights( camera2 );

1350 1351 1352
						renderObject( object, scene, camera2, geometry, material, group );

					}
M
Mr.doob 已提交
1353

M
Mr.doob 已提交
1354
				}
1355

M
Mr.doob 已提交
1356
			} else {
M
Mr.doob 已提交
1357

1358 1359
				_currentArrayCamera = null;

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

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

1364
		}
M
Mr.doob 已提交
1365

1366
	}
G
gero3 已提交
1367

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

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

M
Mr.doob 已提交
1373 1374 1375 1376 1377
		object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
		object.normalMatrix.getNormalMatrix( object.modelViewMatrix );

		if ( object.isImmediateRenderObject ) {

1378
			state.setMaterial( material );
M
Mr.doob 已提交
1379 1380 1381

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

M
Mr.doob 已提交
1382 1383
			_currentGeometryProgram.geometry = null;
			_currentGeometryProgram.program = null;
1384
			_currentGeometryProgram.wireframe = false;
M
Mr.doob 已提交
1385

M
Mr.doob 已提交
1386
			renderObjectImmediate( object, program );
M
Mr.doob 已提交
1387 1388 1389

		} else {

M
Mugen87 已提交
1390
			_this.renderBufferDirect( camera, scene.fog, geometry, material, object, group );
M
Mr.doob 已提交
1391 1392 1393

		}

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

M
Mr.doob 已提交
1397 1398
	}

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

1401
		var materialProperties = properties.get( material );
G
gero3 已提交
1402

1403 1404
		var lights = currentRenderState.state.lights;
		var shadowsArray = currentRenderState.state.shadowsArray;
1405

M
Mr.doob 已提交
1406 1407 1408
		var lightsHash = materialProperties.lightsHash;
		var lightsStateHash = lights.state.hash;

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

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

1414
		var program = materialProperties.program;
T
tschw 已提交
1415
		var programChange = true;
1416

1417
		if ( program === undefined ) {
B
Ben Adams 已提交
1418

M
Mr.doob 已提交
1419 1420
			// new material
			material.addEventListener( 'dispose', onMaterialDispose );
B
Ben Adams 已提交
1421

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

M
Mr.doob 已提交
1424
			// changed glsl or parameters
1425
			releaseMaterialProgramReference( material );
B
Ben Adams 已提交
1426

M
Mr.doob 已提交
1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441
		} else if ( lightsHash.stateID !== lightsStateHash.stateID ||
			lightsHash.directionalLength !== lightsStateHash.directionalLength ||
			lightsHash.pointLength !== lightsStateHash.pointLength ||
			lightsHash.spotLength !== lightsStateHash.spotLength ||
			lightsHash.rectAreaLength !== lightsStateHash.rectAreaLength ||
			lightsHash.hemiLength !== lightsStateHash.hemiLength ||
			lightsHash.shadowsLength !== lightsStateHash.shadowsLength ) {

			lightsHash.stateID = lightsStateHash.stateID;
			lightsHash.directionalLength = lightsStateHash.directionalLength;
			lightsHash.pointLength = lightsStateHash.pointLength;
			lightsHash.spotLength = lightsStateHash.spotLength;
			lightsHash.rectAreaLength = lightsStateHash.rectAreaLength;
			lightsHash.hemiLength = lightsStateHash.hemiLength;
			lightsHash.shadowsLength = lightsStateHash.shadowsLength;
1442 1443 1444

			programChange = false;

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

T
tschw 已提交
1447
			// same glsl and uniform list
T
tschw 已提交
1448 1449
			return;

T
tschw 已提交
1450
		} else {
B
Ben Adams 已提交
1451

T
tschw 已提交
1452 1453
			// only rebuild uniform list
			programChange = false;
B
Ben Adams 已提交
1454 1455 1456

		}

1457
		if ( programChange ) {
B
Ben Adams 已提交
1458

1459
			if ( parameters.shaderID ) {
B
Ben Adams 已提交
1460

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

1463
				materialProperties.shader = {
1464
					name: material.type,
M
Mr.doob 已提交
1465
					uniforms: cloneUniforms( shader.uniforms ),
1466
					vertexShader: shader.vertexShader,
1467
					fragmentShader: shader.fragmentShader
1468
				};
B
Ben Adams 已提交
1469

1470
			} else {
B
Ben Adams 已提交
1471

1472
				materialProperties.shader = {
1473 1474 1475
					name: material.type,
					uniforms: material.uniforms,
					vertexShader: material.vertexShader,
1476
					fragmentShader: material.fragmentShader
1477
				};
G
gero3 已提交
1478

1479
			}
G
gero3 已提交
1480

1481
			material.onBeforeCompile( materialProperties.shader, _this );
G
gero3 已提交
1482

1483
			// Computing code again as onBeforeCompile may have changed the shaders
1484 1485
			code = programCache.getProgramCode( material, parameters );

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

1488 1489
			materialProperties.program = program;
			material.program = program;
1490 1491 1492

		}

1493
		var programAttributes = program.getAttributes();
M
Mr.doob 已提交
1494 1495 1496 1497 1498

		if ( material.morphTargets ) {

			material.numSupportedMorphTargets = 0;

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

1501
				if ( programAttributes[ 'morphTarget' + i ] >= 0 ) {
M
Mr.doob 已提交
1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514

					material.numSupportedMorphTargets ++;

				}

			}

		}

		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

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

1517
				if ( programAttributes[ 'morphNormal' + i ] >= 0 ) {
M
Mr.doob 已提交
1518 1519 1520 1521 1522 1523 1524 1525 1526

					material.numSupportedMorphNormals ++;

				}

			}

		}

1527
		var uniforms = materialProperties.shader.uniforms;
T
tschw 已提交
1528

1529
		if ( ! material.isShaderMaterial &&
1530 1531
			! material.isRawShaderMaterial ||
			material.clipping === true ) {
T
tschw 已提交
1532

T
tschw 已提交
1533
			materialProperties.numClippingPlanes = _clipping.numPlanes;
1534
			materialProperties.numIntersection = _clipping.numIntersection;
T
tschw 已提交
1535
			uniforms.clippingPlanes = _clipping.uniform;
T
tschw 已提交
1536 1537 1538

		}

1539
		materialProperties.fog = fog;
1540

1541
		// store the light setup it was created for
M
Mr.doob 已提交
1542
		if ( lightsHash === undefined ) {
1543

M
Mr.doob 已提交
1544
			materialProperties.lightsHash = lightsHash = {};
1545 1546 1547

		}

M
Mr.doob 已提交
1548 1549 1550 1551 1552 1553 1554
		lightsHash.stateID = lightsStateHash.stateID;
		lightsHash.directionalLength = lightsStateHash.directionalLength;
		lightsHash.pointLength = lightsStateHash.pointLength;
		lightsHash.spotLength = lightsStateHash.spotLength;
		lightsHash.rectAreaLength = lightsStateHash.rectAreaLength;
		lightsHash.hemiLength = lightsStateHash.hemiLength;
		lightsHash.shadowsLength = lightsStateHash.shadowsLength;
1555

M
Mr.doob 已提交
1556
		if ( material.lights ) {
1557 1558 1559

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

1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572
			uniforms.ambientLightColor.value = lights.state.ambient;
			uniforms.directionalLights.value = lights.state.directional;
			uniforms.spotLights.value = lights.state.spot;
			uniforms.rectAreaLights.value = lights.state.rectArea;
			uniforms.pointLights.value = lights.state.point;
			uniforms.hemisphereLights.value = lights.state.hemi;

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

1575 1576
		}

T
tschw 已提交
1577 1578
		var progUniforms = materialProperties.program.getUniforms(),
			uniformsList =
1579
				WebGLUniforms.seqWithValue( progUniforms.seq, uniforms );
A
arose 已提交
1580

T
tschw 已提交
1581
		materialProperties.uniformsList = uniformsList;
A
arose 已提交
1582

M
Mr.doob 已提交
1583
	}
M
Mr.doob 已提交
1584

1585
	function setProgram( camera, fog, material, object ) {
M
Mr.doob 已提交
1586 1587 1588

		_usedTextureUnits = 0;

1589
		var materialProperties = properties.get( material );
1590
		var lights = currentRenderState.state.lights;
1591

M
Mr.doob 已提交
1592 1593 1594
		var lightsHash = materialProperties.lightsHash;
		var lightsStateHash = lights.state.hash;

T
tschw 已提交
1595 1596 1597 1598 1599
		if ( _clippingEnabled ) {

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

				var useCache =
1600 1601
					camera === _currentCamera &&
					material.id === _currentMaterialId;
T
tschw 已提交
1602 1603 1604 1605

				// we might want to call this function with some ClippingGroup
				// object instead of the material, once it becomes feasible
				// (#8465, #8379)
T
tschw 已提交
1606
				_clipping.setState(
1607 1608
					material.clippingPlanes, material.clipIntersection, material.clipShadows,
					camera, materialProperties, useCache );
T
tschw 已提交
1609 1610 1611 1612 1613

			}

		}

1614
		if ( material.needsUpdate === false ) {
1615

1616
			if ( materialProperties.program === undefined ) {
1617

1618
				material.needsUpdate = true;
1619

1620
			} else if ( material.fog && materialProperties.fog !== fog ) {
1621

M
Mr.doob 已提交
1622
				material.needsUpdate = true;
1623

M
Mr.doob 已提交
1624 1625 1626 1627 1628 1629 1630
			} else if ( material.lights && ( lightsHash.stateID !== lightsStateHash.stateID ||
				lightsHash.directionalLength !== lightsStateHash.directionalLength ||
				lightsHash.pointLength !== lightsStateHash.pointLength ||
				lightsHash.spotLength !== lightsStateHash.spotLength ||
				lightsHash.rectAreaLength !== lightsStateHash.rectAreaLength ||
				lightsHash.hemiLength !== lightsStateHash.hemiLength ||
				lightsHash.shadowsLength !== lightsStateHash.shadowsLength ) ) {
1631

1632
				material.needsUpdate = true;
1633

1634
			} else if ( materialProperties.numClippingPlanes !== undefined &&
1635
				( materialProperties.numClippingPlanes !== _clipping.numPlanes ||
M
Mr.doob 已提交
1636
				materialProperties.numIntersection !== _clipping.numIntersection ) ) {
1637 1638 1639

				material.needsUpdate = true;

1640
			}
1641 1642 1643 1644

		}

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

1646
			initMaterial( material, fog, object );
M
Mr.doob 已提交
1647 1648 1649 1650
			material.needsUpdate = false;

		}

1651
		var refreshProgram = false;
M
Mr.doob 已提交
1652
		var refreshMaterial = false;
1653
		var refreshLights = false;
M
Mr.doob 已提交
1654

1655
		var program = materialProperties.program,
1656
			p_uniforms = program.getUniforms(),
1657
			m_uniforms = materialProperties.shader.uniforms;
M
Mr.doob 已提交
1658

1659
		if ( state.useProgram( program.program ) ) {
M
Mr.doob 已提交
1660

1661
			refreshProgram = true;
M
Mr.doob 已提交
1662
			refreshMaterial = true;
1663
			refreshLights = true;
M
Mr.doob 已提交
1664 1665 1666 1667 1668 1669

		}

		if ( material.id !== _currentMaterialId ) {

			_currentMaterialId = material.id;
1670

M
Mr.doob 已提交
1671 1672 1673 1674
			refreshMaterial = true;

		}

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

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

G
gero3 已提交
1679
			if ( capabilities.logarithmicDepthBuffer ) {
1680

T
tschw 已提交
1681
				p_uniforms.setValue( _gl, 'logDepthBufFC',
1682
					2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
1683 1684 1685

			}

1686
			if ( _currentCamera !== camera ) {
1687

1688
				_currentCamera = camera;
1689 1690 1691 1692 1693 1694

				// 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 已提交
1695
				refreshLights = true;		// remains set until update done
1696 1697

			}
M
Mr.doob 已提交
1698

1699 1700 1701
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)

1702
			if ( material.isShaderMaterial ||
1703 1704 1705
				material.isMeshPhongMaterial ||
				material.isMeshStandardMaterial ||
				material.envMap ) {
1706

T
tschw 已提交
1707 1708 1709
				var uCamPos = p_uniforms.map.cameraPosition;

				if ( uCamPos !== undefined ) {
1710

T
tschw 已提交
1711
					uCamPos.setValue( _gl,
1712
						_vector3.setFromMatrixPosition( camera.matrixWorld ) );
1713 1714 1715 1716 1717

				}

			}

1718
			if ( material.isMeshPhongMaterial ||
1719 1720 1721 1722
				material.isMeshLambertMaterial ||
				material.isMeshBasicMaterial ||
				material.isMeshStandardMaterial ||
				material.isShaderMaterial ||
1723
				material.skinning ) {
1724

T
tschw 已提交
1725
				p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );
1726 1727 1728

			}

M
Mr.doob 已提交
1729 1730 1731 1732 1733 1734
		}

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

1735
		if ( material.skinning ) {
M
Mr.doob 已提交
1736

T
tschw 已提交
1737 1738
			p_uniforms.setOptional( _gl, object, 'bindMatrix' );
			p_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );
1739

T
tschw 已提交
1740
			var skeleton = object.skeleton;
1741

T
tschw 已提交
1742
			if ( skeleton ) {
1743

1744 1745
				var bones = skeleton.bones;

1746
				if ( capabilities.floatVertexTextures ) {
M
Mr.doob 已提交
1747

1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758
					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
1759
						size = _Math.ceilPowerOfTwo( size );
1760 1761 1762 1763 1764 1765
						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 );
1766
						boneTexture.needsUpdate = true;
1767 1768 1769 1770 1771 1772 1773

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

					}

M
Mr.doob 已提交
1774 1775
					p_uniforms.setValue( _gl, 'boneTexture', skeleton.boneTexture );
					p_uniforms.setValue( _gl, 'boneTextureSize', skeleton.boneTextureSize );
M
Mr.doob 已提交
1776

T
tschw 已提交
1777
				} else {
M
Mr.doob 已提交
1778

T
tschw 已提交
1779
					p_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );
M
Mr.doob 已提交
1780 1781 1782 1783 1784 1785 1786 1787 1788

				}

			}

		}

		if ( refreshMaterial ) {

1789 1790 1791
			p_uniforms.setValue( _gl, 'toneMappingExposure', _this.toneMappingExposure );
			p_uniforms.setValue( _gl, 'toneMappingWhitePoint', _this.toneMappingWhitePoint );

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

1794
				// the current material requires lighting info
M
Mr.doob 已提交
1795

T
tschw 已提交
1796 1797 1798 1799 1800 1801
				// 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 已提交
1802

T
tschw 已提交
1803
				markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
G
gero3 已提交
1804

T
tschw 已提交
1805
			}
G
gero3 已提交
1806

T
tschw 已提交
1807
			// refresh uniforms common to several materials
G
gero3 已提交
1808

T
tschw 已提交
1809
			if ( fog && material.fog ) {
G
gero3 已提交
1810

T
tschw 已提交
1811
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
1812 1813 1814

			}

1815
			if ( material.isMeshBasicMaterial ) {
M
Mr.doob 已提交
1816 1817 1818

				refreshUniformsCommon( m_uniforms, material );

1819
			} else if ( material.isMeshLambertMaterial ) {
M
Mr.doob 已提交
1820

1821 1822
				refreshUniformsCommon( m_uniforms, material );
				refreshUniformsLambert( m_uniforms, material );
M
Mr.doob 已提交
1823

1824
			} else if ( material.isMeshPhongMaterial ) {
M
Mr.doob 已提交
1825

1826
				refreshUniformsCommon( m_uniforms, material );
M
Mr.doob 已提交
1827

1828
				if ( material.isMeshToonMaterial ) {
M
Mr.doob 已提交
1829

1830
					refreshUniformsToon( m_uniforms, material );
M
Mr.doob 已提交
1831

1832
				} else {
1833

1834
					refreshUniformsPhong( m_uniforms, material );
1835

1836
				}
T
Takahiro 已提交
1837

1838
			} else if ( material.isMeshStandardMaterial ) {
T
Takahiro 已提交
1839

1840
				refreshUniformsCommon( m_uniforms, material );
1841

1842
				if ( material.isMeshPhysicalMaterial ) {
1843

1844
					refreshUniformsPhysical( m_uniforms, material );
W
WestLangley 已提交
1845

1846
				} else {
W
WestLangley 已提交
1847

1848
					refreshUniformsStandard( m_uniforms, material );
W
WestLangley 已提交
1849

1850
				}
W
WestLangley 已提交
1851

W
WestLangley 已提交
1852 1853 1854 1855 1856 1857
			} else if ( material.isMeshMatcapMaterial ) {

				refreshUniformsCommon( m_uniforms, material );

				refreshUniformsMatcap( m_uniforms, material );

1858
			} else if ( material.isMeshDepthMaterial ) {
M
Mr.doob 已提交
1859

1860
				refreshUniformsCommon( m_uniforms, material );
W
WestLangley 已提交
1861
				refreshUniformsDepth( m_uniforms, material );
1862

W
WestLangley 已提交
1863
			} else if ( material.isMeshDistanceMaterial ) {
1864

1865
				refreshUniformsCommon( m_uniforms, material );
W
WestLangley 已提交
1866
				refreshUniformsDistance( m_uniforms, material );
1867

1868
			} else if ( material.isMeshNormalMaterial ) {
M
Mr.doob 已提交
1869

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

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

				refreshUniformsLine( m_uniforms, material );

				if ( material.isLineDashedMaterial ) {

					refreshUniformsDash( m_uniforms, material );

				}

			} else if ( material.isPointsMaterial ) {

				refreshUniformsPoints( m_uniforms, material );

1887 1888 1889 1890
			} else if ( material.isSpriteMaterial ) {

				refreshUniformsSprites( m_uniforms, material );

1891 1892 1893 1894 1895
			} else if ( material.isShadowMaterial ) {

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

M
Mr.doob 已提交
1896 1897
			}

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

1901 1902
			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 已提交
1903

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

		}

1908 1909 1910 1911 1912 1913
		if ( material.isShaderMaterial && material.uniformsNeedUpdate === true ) {

			WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, _this );
			material.uniformsNeedUpdate = false;

		}
M
Mr.doob 已提交
1914

1915 1916 1917 1918 1919 1920
		if ( material.isSpriteMaterial ) {

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

		}

T
tschw 已提交
1921
		// common matrices
M
Mr.doob 已提交
1922

M
Mr.doob 已提交
1923 1924
		p_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix );
		p_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix );
T
tschw 已提交
1925
		p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );
A
arose 已提交
1926

T
tschw 已提交
1927
		return program;
A
arose 已提交
1928 1929 1930

	}

M
Mr.doob 已提交
1931 1932
	// Uniforms (refresh uniforms objects)

M
Mr.doob 已提交
1933
	function refreshUniformsCommon( uniforms, material ) {
M
Mr.doob 已提交
1934 1935 1936

		uniforms.opacity.value = material.opacity;

1937 1938 1939 1940 1941
		if ( material.color ) {

			uniforms.diffuse.value = material.color;

		}
M
Mr.doob 已提交
1942

1943
		if ( material.emissive ) {
M
Mr.doob 已提交
1944

1945
			uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );
M
Mr.doob 已提交
1946 1947 1948

		}

1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974
		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 已提交
1975
			uniforms.flipEnvMap.value = material.envMap.isCubeTexture ? - 1 : 1;
1976 1977 1978 1979

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

1980
			uniforms.maxMipLevel.value = properties.get( material.envMap ).__maxMipLevel;
1981

1982
		}
M
Mr.doob 已提交
1983

1984 1985 1986 1987 1988 1989 1990
		if ( material.lightMap ) {

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

		}

1991
		if ( material.aoMap ) {
1992

1993 1994
			uniforms.aoMap.value = material.aoMap;
			uniforms.aoMapIntensity.value = material.aoMapIntensity;
1995 1996 1997

		}

M
Mr.doob 已提交
1998
		// uv repeat and offset setting priorities
M
Mr.doob 已提交
1999 2000 2001 2002 2003
		// 1. color map
		// 2. specular map
		// 3. normal map
		// 4. bump map
		// 5. alpha map
2004
		// 6. emissive map
M
Mr.doob 已提交
2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015

		var uvScaleMap;

		if ( material.map ) {

			uvScaleMap = material.map;

		} else if ( material.specularMap ) {

			uvScaleMap = material.specularMap;

2016 2017 2018 2019
		} else if ( material.displacementMap ) {

			uvScaleMap = material.displacementMap;

M
Mr.doob 已提交
2020 2021 2022 2023 2024 2025 2026 2027
		} else if ( material.normalMap ) {

			uvScaleMap = material.normalMap;

		} else if ( material.bumpMap ) {

			uvScaleMap = material.bumpMap;

2028 2029 2030 2031 2032 2033 2034 2035
		} else if ( material.roughnessMap ) {

			uvScaleMap = material.roughnessMap;

		} else if ( material.metalnessMap ) {

			uvScaleMap = material.metalnessMap;

2036 2037 2038 2039
		} else if ( material.alphaMap ) {

			uvScaleMap = material.alphaMap;

2040 2041 2042 2043
		} else if ( material.emissiveMap ) {

			uvScaleMap = material.emissiveMap;

M
Mr.doob 已提交
2044 2045 2046 2047
		}

		if ( uvScaleMap !== undefined ) {

2048
			// backwards compatibility
2049
			if ( uvScaleMap.isWebGLRenderTarget ) {
M
Mr.doob 已提交
2050 2051 2052 2053 2054

				uvScaleMap = uvScaleMap.texture;

			}

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

W
WestLangley 已提交
2057
				uvScaleMap.updateMatrix();
M
Mr.doob 已提交
2058

W
WestLangley 已提交
2059
			}
2060

2061
			uniforms.uvTransform.value.copy( uvScaleMap.matrix );
M
Mr.doob 已提交
2062 2063 2064

		}

M
Mr.doob 已提交
2065
	}
M
Mr.doob 已提交
2066

M
Mr.doob 已提交
2067
	function refreshUniformsLine( uniforms, material ) {
M
Mr.doob 已提交
2068 2069 2070 2071

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

M
Mr.doob 已提交
2072
	}
M
Mr.doob 已提交
2073

M
Mr.doob 已提交
2074
	function refreshUniformsDash( uniforms, material ) {
M
Mr.doob 已提交
2075 2076 2077 2078 2079

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

M
Mr.doob 已提交
2080
	}
M
Mr.doob 已提交
2081

M
Mr.doob 已提交
2082
	function refreshUniformsPoints( uniforms, material ) {
M
Mr.doob 已提交
2083

2084
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
2085
		uniforms.opacity.value = material.opacity;
2086
		uniforms.size.value = material.size * _pixelRatio;
2087
		uniforms.scale.value = _height * 0.5;
M
Mr.doob 已提交
2088 2089 2090

		uniforms.map.value = material.map;

2091 2092
		if ( material.map !== null ) {

W
WestLangley 已提交
2093
			if ( material.map.matrixAutoUpdate === true ) {
2094

W
WestLangley 已提交
2095
				material.map.updateMatrix();
W
WestLangley 已提交
2096 2097

			}
2098

2099
			uniforms.uvTransform.value.copy( material.map.matrix );
2100 2101 2102

		}

2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123
	}

	function refreshUniformsSprites( uniforms, material ) {

		uniforms.diffuse.value = material.color;
		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 已提交
2124
	}
M
Mr.doob 已提交
2125

M
Mr.doob 已提交
2126
	function refreshUniformsFog( uniforms, fog ) {
M
Mr.doob 已提交
2127 2128 2129

		uniforms.fogColor.value = fog.color;

2130
		if ( fog.isFog ) {
M
Mr.doob 已提交
2131 2132 2133 2134

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

2135
		} else if ( fog.isFogExp2 ) {
M
Mr.doob 已提交
2136 2137 2138 2139 2140

			uniforms.fogDensity.value = fog.density;

		}

M
Mr.doob 已提交
2141
	}
M
Mr.doob 已提交
2142

M
Mr.doob 已提交
2143
	function refreshUniformsLambert( uniforms, material ) {
2144 2145 2146 2147 2148 2149 2150 2151 2152

		if ( material.emissiveMap ) {

			uniforms.emissiveMap.value = material.emissiveMap;

		}

	}

M
Mr.doob 已提交
2153
	function refreshUniformsPhong( uniforms, material ) {
M
Mr.doob 已提交
2154

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

2158
		if ( material.emissiveMap ) {
2159

2160
			uniforms.emissiveMap.value = material.emissiveMap;
2161

2162
		}
M
Mr.doob 已提交
2163

2164 2165 2166 2167
		if ( material.bumpMap ) {

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

2170
		}
M
Mr.doob 已提交
2171

2172 2173 2174 2175
		if ( material.normalMap ) {

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

		}
M
Mr.doob 已提交
2179

2180 2181 2182 2183 2184
		if ( material.displacementMap ) {

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

2186
		}
2187

T
Takahiro 已提交
2188 2189 2190 2191 2192 2193
	}

	function refreshUniformsToon( uniforms, material ) {

		refreshUniformsPhong( uniforms, material );

T
Takahiro 已提交
2194
		if ( material.gradientMap ) {
T
Takahiro 已提交
2195

T
Takahiro 已提交
2196
			uniforms.gradientMap.value = material.gradientMap;
T
Takahiro 已提交
2197 2198 2199

		}

2200 2201
	}

M
Mr.doob 已提交
2202
	function refreshUniformsStandard( uniforms, material ) {
W
WestLangley 已提交
2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228

		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;
2229
			if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1;
W
WestLangley 已提交
2230 2231 2232 2233 2234 2235 2236

		}

		if ( material.normalMap ) {

			uniforms.normalMap.value = material.normalMap;
			uniforms.normalScale.value.copy( material.normalScale );
2237
			if ( material.side === BackSide ) uniforms.normalScale.value.negate();
W
WestLangley 已提交
2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257

		}

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

2260 2261 2262 2263
		refreshUniformsStandard( uniforms, material );

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

2264 2265 2266
		uniforms.clearCoat.value = material.clearCoat;
		uniforms.clearCoatRoughness.value = material.clearCoatRoughness;

W
WestLangley 已提交
2267 2268
	}

W
WestLangley 已提交
2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302
	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 已提交
2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330
	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;

	}

2331 2332 2333 2334 2335 2336
	function refreshUniformsNormal( uniforms, material ) {

		if ( material.bumpMap ) {

			uniforms.bumpMap.value = material.bumpMap;
			uniforms.bumpScale.value = material.bumpScale;
2337
			if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1;
2338 2339 2340 2341 2342 2343 2344

		}

		if ( material.normalMap ) {

			uniforms.normalMap.value = material.normalMap;
			uniforms.normalScale.value.copy( material.normalScale );
2345
			if ( material.side === BackSide ) uniforms.normalScale.value.negate();
2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358

		}

		if ( material.displacementMap ) {

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

		}

	}

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

M
Mr.doob 已提交
2361
	function markUniformsLightsNeedsUpdate( uniforms, value ) {
2362

M
Mr.doob 已提交
2363
		uniforms.ambientLightColor.needsUpdate = value;
2364

B
Ben Houston 已提交
2365 2366 2367
		uniforms.directionalLights.needsUpdate = value;
		uniforms.pointLights.needsUpdate = value;
		uniforms.spotLights.needsUpdate = value;
2368
		uniforms.rectAreaLights.needsUpdate = value;
B
Ben Houston 已提交
2369
		uniforms.hemisphereLights.needsUpdate = value;
2370

M
Mr.doob 已提交
2371
	}
2372

M
Mr.doob 已提交
2373 2374
	// Textures

T
tschw 已提交
2375 2376 2377 2378 2379 2380
	function allocTextureUnit() {

		var textureUnit = _usedTextureUnits;

		if ( textureUnit >= capabilities.maxTextures ) {

M
Mugen87 已提交
2381
			console.warn( 'THREE.WebGLRenderer: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );
T
tschw 已提交
2382 2383 2384 2385 2386 2387 2388 2389 2390

		}

		_usedTextureUnits += 1;

		return textureUnit;

	}

2391
	this.allocTextureUnit = allocTextureUnit;
T
tschw 已提交
2392

2393
	// this.setTexture2D = setTexture2D;
M
Mr.doob 已提交
2394
	this.setTexture2D = ( function () {
T
tschw 已提交
2395

2396
		var warned = false;
T
tschw 已提交
2397

2398
		// backwards compatibility: peel texture.texture
W
WestLangley 已提交
2399
		return function setTexture2D( texture, slot ) {
T
tschw 已提交
2400

T
Takahiro 已提交
2401
			if ( texture && texture.isWebGLRenderTarget ) {
T
tschw 已提交
2402

2403
				if ( ! warned ) {
T
tschw 已提交
2404

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

2408
				}
T
tschw 已提交
2409

2410
				texture = texture.texture;
T
tschw 已提交
2411

2412
			}
T
tschw 已提交
2413

2414
			textures.setTexture2D( texture, slot );
T
tschw 已提交
2415

2416
		};
T
tschw 已提交
2417

2418
	}() );
T
tschw 已提交
2419

A
artur.trzesiok 已提交
2420
	this.setTexture3D = ( function () {
A
artur.trzesiok 已提交
2421

A
artur.trzesiok 已提交
2422 2423
		// backwards compatibility: peel texture.texture
		return function setTexture3D( texture, slot ) {
A
artur.trzesiok 已提交
2424

A
artur.trzesiok 已提交
2425 2426 2427 2428 2429
			textures.setTexture3D( texture, slot );

		};

	}() );
A
artur.trzesiok 已提交
2430

M
Mr.doob 已提交
2431
	this.setTexture = ( function () {
2432 2433 2434

		var warned = false;

W
WestLangley 已提交
2435
		return function setTexture( texture, slot ) {
2436 2437 2438 2439 2440 2441 2442 2443

			if ( ! warned ) {

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

			}

2444
			textures.setTexture2D( texture, slot );
2445 2446 2447 2448 2449

		};

	}() );

M
Mr.doob 已提交
2450
	this.setTextureCube = ( function () {
2451 2452 2453

		var warned = false;

W
WestLangley 已提交
2454
		return function setTextureCube( texture, slot ) {
2455 2456

			// backwards compatibility: peel texture.texture
T
Takahiro 已提交
2457
			if ( texture && texture.isWebGLRenderTargetCube ) {
2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471

				if ( ! warned ) {

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

				}

				texture = texture.texture;

			}

			// currently relying on the fact that WebGLRenderTargetCube.texture is a Texture and NOT a CubeTexture
			// TODO: unify these code paths
T
Takahiro 已提交
2472
			if ( ( texture && texture.isCubeTexture ) ||
2473
				( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {
2474 2475 2476 2477

				// CompressedTexture can have Array in image :/

				// this function alone should take care of cube textures
2478
				textures.setTextureCube( texture, slot );
2479 2480 2481 2482 2483

			} else {

				// assumed: texture property of THREE.WebGLRenderTargetCube

2484
				textures.setTextureCubeDynamic( texture, slot );
2485 2486 2487 2488 2489 2490

			}

		};

	}() );
T
tschw 已提交
2491

2492 2493 2494 2495 2496 2497 2498 2499
	//

	this.setFramebuffer = function ( value ) {

		_framebuffer = value;

	};

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

		return _currentRenderTarget;

M
Michael Herzog 已提交
2504
	};
2505

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

2508 2509
		_currentRenderTarget = renderTarget;

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

2512
			textures.setupRenderTarget( renderTarget );
M
Mr.doob 已提交
2513 2514 2515

		}

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

		if ( renderTarget ) {

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

M
Mr.doob 已提交
2523
			if ( renderTarget.isWebGLRenderTargetCube ) {
M
Mr.doob 已提交
2524

M
Mr.doob 已提交
2525
				framebuffer = __webglFramebuffer[ renderTarget.activeCubeFace ];
M
Mr.doob 已提交
2526
				isCube = true;
M
Mr.doob 已提交
2527

2528 2529 2530 2531
			} else if ( renderTarget.isWebGLMultisampleRenderTarget ) {

				framebuffer = properties.get( renderTarget ).__webglMultisampledFramebuffer;

M
Mr.doob 已提交
2532 2533
			} else {

M
Mr.doob 已提交
2534
				framebuffer = __webglFramebuffer;
M
Mr.doob 已提交
2535 2536 2537

			}

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

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

M
Mr.doob 已提交
2544
			_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );
2545
			_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );
2546
			_currentScissorTest = _scissorTest;
2547

M
Mr.doob 已提交
2548 2549
		}

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

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

		}

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

M
Mr.doob 已提交
2561 2562 2563
		if ( isCube ) {

			var textureProperties = properties.get( renderTarget.texture );
2564
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );
M
Mr.doob 已提交
2565 2566 2567

		}

M
Mr.doob 已提交
2568 2569
	};

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

0
06wj 已提交
2572
		if ( ! ( renderTarget && renderTarget.isWebGLRenderTarget ) ) {
2573

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

G
gero3 已提交
2577
		}
2578

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

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

G
gero3 已提交
2583
			var restore = false;
2584

M
Mr.doob 已提交
2585
			if ( framebuffer !== _currentFramebuffer ) {
2586

M
Mr.doob 已提交
2587
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
2588

G
gero3 已提交
2589
				restore = true;
2590

G
gero3 已提交
2591
			}
2592

M
Mr.doob 已提交
2593
			try {
2594

M
Mr.doob 已提交
2595
				var texture = renderTarget.texture;
M
Mr.doob 已提交
2596 2597
				var textureFormat = texture.format;
				var textureType = texture.type;
2598

2599
				if ( textureFormat !== RGBAFormat && utils.convert( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {
2600

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

M
Mr.doob 已提交
2604
				}
2605

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

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

M
Mr.doob 已提交
2613
				}
2614

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

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

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

2621
						_gl.readPixels( x, y, width, height, utils.convert( textureFormat ), utils.convert( textureType ), buffer );
2622 2623

					}
2624

M
Mr.doob 已提交
2625
				} else {
M
Mr.doob 已提交
2626

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

				}
M
Mr.doob 已提交
2630

M
Mr.doob 已提交
2631
			} finally {
M
Mr.doob 已提交
2632

M
Mr.doob 已提交
2633 2634 2635
				if ( restore ) {

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

M
Mr.doob 已提交
2637 2638 2639
				}

			}
M
Mr.doob 已提交
2640 2641 2642

		}

M
Mr.doob 已提交
2643 2644
	};

2645
	this.copyFramebufferToTexture = function ( position, texture, level ) {
2646 2647 2648

		var width = texture.image.width;
		var height = texture.image.height;
2649
		var glFormat = utils.convert( texture.format );
2650 2651 2652

		this.setTexture2D( texture, 0 );

2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665
		_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 );

		this.setTexture2D( dstTexture, 0 );

2666 2667 2668 2669 2670 2671 2672 2673 2674
		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 );

		}
2675 2676 2677

	};

M
Mr.doob 已提交
2678
}
R
Rich Harris 已提交
2679

T
Tristan VALCKE 已提交
2680

2681
export { WebGLRenderer };