WebGLRenderer.js 59.0 KB
Newer Older
M
Mr.doob 已提交
1 2 3 4 5 6 7 8 9 10
import {
	REVISION,
	RGBAFormat,
	HalfFloatType,
	FloatType,
	UnsignedByteType,
	TriangleFanDrawMode,
	TriangleStripDrawMode,
	TrianglesDrawMode,
	NoColors,
11 12
	LinearToneMapping,
	BackSide
M
Mr.doob 已提交
13
} from '../constants.js';
B
bentok 已提交
14 15
import { _Math } from '../math/Math.js';
import { DataTexture } from '../textures/DataTexture.js';
M
Mr.doob 已提交
16 17 18
import { Frustum } from '../math/Frustum.js';
import { Matrix4 } from '../math/Matrix4.js';
import { ShaderLib } from './shaders/ShaderLib.js';
B
bentok 已提交
19 20
import { UniformsLib } from './shaders/UniformsLib.js';
import { UniformsUtils } from './shaders/UniformsUtils.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 40
import { WebGLRenderLists } from './webgl/WebGLRenderLists.js';
import { WebGLRenderStates } from './webgl/WebGLRenderStates.js';
import { WebGLShadowMap } from './webgl/WebGLShadowMap.js';
import { WebGLSpriteRenderer } from './webgl/WebGLSpriteRenderer.js';
B
bentok 已提交
41
import { WebGLState } from './webgl/WebGLState.js';
M
Mr.doob 已提交
42 43
import { WebGLTextures } from './webgl/WebGLTextures.js';
import { WebGLUniforms } from './webgl/WebGLUniforms.js';
B
bentok 已提交
44
import { WebGLUtils } from './webgl/WebGLUtils.js';
M
Mr.doob 已提交
45
import { WebVRManager } from './webvr/WebVRManager.js';
M
Mr.doob 已提交
46
import { WebXRManager } from './webvr/WebXRManager.js';
R
Rich Harris 已提交
47

M
Mr.doob 已提交
48 49 50 51 52
/**
 * @author supereggbert / http://www.paulbrunt.co.uk/
 * @author mrdoob / http://mrdoob.com/
 * @author alteredq / http://alteredqualia.com/
 * @author szimek / https://github.com/szimek/
T
tschw 已提交
53
 * @author tschw
M
Mr.doob 已提交
54 55
 */

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

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

	parameters = parameters || {};

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

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

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

M
Mr.doob 已提交
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
	// 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 已提交
92 93 94 95 96
	// user-defined clipping

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

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

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

103 104
	// physical lights

105
	this.physicallyCorrectLights = false;
106

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

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

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

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

	// internal properties

	var _this = this,

122 123
		_isContextLost = false,

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

126 127
		_framebuffer = null,

128 129 130 131
		_currentRenderTarget = null,
		_currentFramebuffer = null,
		_currentMaterialId = - 1,
		_currentGeometryProgram = '',
132

133
		_currentCamera = null,
134
		_currentArrayCamera = null,
M
Mr.doob 已提交
135

M
Mr.doob 已提交
136
		_currentViewport = new Vector4(),
137 138
		_currentScissor = new Vector4(),
		_currentScissorTest = null,
139

140
		//
141

142
		_usedTextureUnits = 0,
M
Mr.doob 已提交
143

144
		//
M
Mr.doob 已提交
145

146 147
		_width = _canvas.width,
		_height = _canvas.height,
M
Mr.doob 已提交
148

149
		_pixelRatio = 1,
M
Mr.doob 已提交
150

M
Mr.doob 已提交
151
		_viewport = new Vector4( 0, 0, _width, _height ),
152 153
		_scissor = new Vector4( 0, 0, _width, _height ),
		_scissorTest = false,
154

155
		// frustum
M
Mr.doob 已提交
156

157
		_frustum = new Frustum(),
M
Mr.doob 已提交
158

159
		// clipping
T
tschw 已提交
160

161 162 163
		_clipping = new WebGLClipping(),
		_clippingEnabled = false,
		_localClippingEnabled = false,
T
tschw 已提交
164

165
		// camera matrices cache
M
Mr.doob 已提交
166

167
		_projScreenMatrix = new Matrix4(),
M
Mr.doob 已提交
168

M
Mugen87 已提交
169
		_vector3 = new Vector3();
A
Atrahasis 已提交
170

171 172 173 174 175
	function getTargetPixelRatio() {

		return _currentRenderTarget === null ? _pixelRatio : 1;

	}
176

M
Mr.doob 已提交
177 178 179 180
	// initialize

	var _gl;

M
Mr.doob 已提交
181 182
	try {

183
		var contextAttributes = {
M
Mr.doob 已提交
184 185 186 187 188
			alpha: _alpha,
			depth: _depth,
			stencil: _stencil,
			antialias: _antialias,
			premultipliedAlpha: _premultipliedAlpha,
189
			preserveDrawingBuffer: _preserveDrawingBuffer,
L
Luigi De Rosa 已提交
190
			powerPreference: _powerPreference
M
Mr.doob 已提交
191 192
		};

193 194
		// event listeners must be registered before WebGL context is created, see #12753

195
		_canvas.addEventListener( 'webglcontextlost', onContextLost, false );
196
		_canvas.addEventListener( 'webglcontextrestored', onContextRestore, false );
197

198
		_gl = _context || _canvas.getContext( 'webgl', contextAttributes ) || _canvas.getContext( 'experimental-webgl', contextAttributes );
M
Mr.doob 已提交
199 200 201

		if ( _gl === null ) {

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

D
Daniel Hritzkiv 已提交
204
				throw new Error( 'Error creating WebGL context with your selected attributes.' );
205 206 207

			} else {

D
Daniel Hritzkiv 已提交
208
				throw new Error( 'Error creating WebGL context.' );
209 210

			}
M
Mr.doob 已提交
211 212 213

		}

214 215 216 217 218 219 220 221 222 223 224 225
		// 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 已提交
226 227
	} catch ( error ) {

D
Daniel Hritzkiv 已提交
228
		console.error( 'THREE.WebGLRenderer: ' + error.message );
M
Mr.doob 已提交
229 230 231

	}

M
Mugen87 已提交
232
	var extensions, capabilities, state, info;
233
	var properties, textures, attributes, geometries, objects;
234
	var programCache, renderLists, renderStates;
235

236
	var background, morphtargets, bufferRenderer, indexedBufferRenderer;
M
Mugen87 已提交
237
	var spriteRenderer;
238

239
	var utils;
240

241
	function initGLContext() {
242

243 244 245 246 247 248 249
		extensions = new WebGLExtensions( _gl );
		extensions.get( 'WEBGL_depth_texture' );
		extensions.get( 'OES_texture_float' );
		extensions.get( 'OES_texture_float_linear' );
		extensions.get( 'OES_texture_half_float' );
		extensions.get( 'OES_texture_half_float_linear' );
		extensions.get( 'OES_standard_derivatives' );
M
Mugen87 已提交
250
		extensions.get( 'OES_element_index_uint' );
251
		extensions.get( 'ANGLE_instanced_arrays' );
252

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

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

257
		state = new WebGLState( _gl, extensions, utils );
258 259
		state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );
		state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );
M
Mr.doob 已提交
260

M
Mugen87 已提交
261
		info = new WebGLInfo( _gl );
262
		properties = new WebGLProperties();
M
Mugen87 已提交
263
		textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info );
264
		attributes = new WebGLAttributes( _gl );
M
Mugen87 已提交
265 266
		geometries = new WebGLGeometries( _gl, attributes, info );
		objects = new WebGLObjects( geometries, info );
267
		morphtargets = new WebGLMorphtargets( _gl );
268
		programCache = new WebGLPrograms( _this, extensions, capabilities );
269
		renderLists = new WebGLRenderLists();
270
		renderStates = new WebGLRenderStates();
M
Mr.doob 已提交
271

272
		background = new WebGLBackground( _this, state, objects, _premultipliedAlpha );
273

M
Mugen87 已提交
274 275
		bufferRenderer = new WebGLBufferRenderer( _gl, extensions, info );
		indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, info );
276

277
		spriteRenderer = new WebGLSpriteRenderer( _this, _gl, state, textures, capabilities );
278

M
Mugen87 已提交
279
		info.programs = programCache.programs;
280

281 282 283 284 285 286
		_this.context = _gl;
		_this.capabilities = capabilities;
		_this.extensions = extensions;
		_this.properties = properties;
		_this.renderLists = renderLists;
		_this.state = state;
M
Mugen87 已提交
287
		_this.info = info;
M
Mr.doob 已提交
288

289
	}
M
Mr.doob 已提交
290

291
	initGLContext();
M
Mr.doob 已提交
292

293
	// vr
M
Mr.doob 已提交
294

295
	var vr = ( 'xr' in navigator ) ? new WebXRManager( _this ) : new WebVRManager( _this );
M
Mr.doob 已提交
296

297
	this.vr = vr;
M
Mr.doob 已提交
298 299

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

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

303
	this.shadowMap = shadowMap;
M
Mr.doob 已提交
304

M
Mr.doob 已提交
305 306 307 308 309 310 311 312
	// API

	this.getContext = function () {

		return _gl;

	};

313 314 315 316 317 318
	this.getContextAttributes = function () {

		return _gl.getContextAttributes();

	};

319 320
	this.forceContextLoss = function () {

M
Michael Bond 已提交
321 322
		var extension = extensions.get( 'WEBGL_lose_context' );
		if ( extension ) extension.loseContext();
323 324 325

	};

326
	this.forceContextRestore = function () {
M
Mr.doob 已提交
327

328 329
		var extension = extensions.get( 'WEBGL_lose_context' );
		if ( extension ) extension.restoreContext();
M
Mr.doob 已提交
330 331 332

	};

333 334
	this.getPixelRatio = function () {

335
		return _pixelRatio;
336 337 338 339 340

	};

	this.setPixelRatio = function ( value ) {

341 342 343 344
		if ( value === undefined ) return;

		_pixelRatio = value;

M
Mr.doob 已提交
345
		this.setSize( _width, _height, false );
346 347 348

	};

349 350 351
	this.getSize = function () {

		return {
352 353
			width: _width,
			height: _height
354 355 356 357
		};

	};

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

M
Mr.doob 已提交
360
		if ( vr.isPresenting() ) {
361 362 363 364 365 366

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

		}

367 368 369
		_width = width;
		_height = height;

370 371
		_canvas.width = width * _pixelRatio;
		_canvas.height = height * _pixelRatio;
372

373
		if ( updateStyle !== false ) {
374

G
gero3 已提交
375 376
			_canvas.style.width = width + 'px';
			_canvas.style.height = height + 'px';
377

G
gero3 已提交
378
		}
M
Mr.doob 已提交
379

380
		this.setViewport( 0, 0, width, height );
M
Mr.doob 已提交
381 382 383

	};

M
Mr.doob 已提交
384 385 386 387 388 389 390 391 392
	this.getDrawingBufferSize = function () {

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

	};

393 394 395 396 397 398 399 400 401 402 403 404 405 406
	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 );

	};

407
	this.getCurrentViewport = function () {
M
Mugen87 已提交
408

409
		return _currentViewport;
M
Mugen87 已提交
410 411 412

	};

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

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

M
Mr.doob 已提交
418 419
	};

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

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

M
Mr.doob 已提交
425 426
	};

427 428
	this.setScissorTest = function ( boolean ) {

429
		state.setScissorTest( _scissorTest = boolean );
M
Mr.doob 已提交
430 431 432 433 434

	};

	// Clearing

M
Mr.doob 已提交
435
	this.getClearColor = function () {
M
Mr.doob 已提交
436

437
		return background.getClearColor();
M
Mr.doob 已提交
438 439 440

	};

441
	this.setClearColor = function () {
442

443
		background.setClearColor.apply( background, arguments );
M
Mr.doob 已提交
444 445 446

	};

M
Mr.doob 已提交
447
	this.getClearAlpha = function () {
M
Mr.doob 已提交
448

449
		return background.getClearAlpha();
M
Mr.doob 已提交
450 451 452

	};

M
Mugen87 已提交
453
	this.setClearAlpha = function () {
M
Mr.doob 已提交
454

455
		background.setClearAlpha.apply( background, arguments );
M
Mr.doob 已提交
456 457 458 459 460 461 462 463 464 465 466 467

	};

	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 );
468 469 470 471 472

	};

	this.clearColor = function () {

M
Mr.doob 已提交
473
		this.clear( true, false, false );
474 475 476 477 478

	};

	this.clearDepth = function () {

M
Mr.doob 已提交
479
		this.clear( false, true, false );
480 481 482 483 484

	};

	this.clearStencil = function () {

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

	};

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

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

	};

M
Mr.doob 已提交
496
	//
M
Mr.doob 已提交
497

M
Mr.doob 已提交
498
	this.dispose = function () {
D
dubejf 已提交
499 500

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

503
		renderLists.dispose();
504
		renderStates.dispose();
M
Mugen87 已提交
505 506
		properties.dispose();
		objects.dispose();
507

508
		vr.dispose();
509

510
		animation.stop();
B
brunnerh 已提交
511

D
dubejf 已提交
512 513
	};

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

D
dubejf 已提交
516 517 518 519
	function onContextLost( event ) {

		event.preventDefault();

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

522 523 524 525
		_isContextLost = true;

	}

M
Mugen87 已提交
526
	function onContextRestore( /* event */ ) {
D
dubejf 已提交
527

528
		console.log( 'THREE.WebGLRenderer: Context Restored.' );
529 530

		_isContextLost = false;
D
dubejf 已提交
531

532
		initGLContext();
D
dubejf 已提交
533

M
Mr.doob 已提交
534
	}
D
dubejf 已提交
535

536
	function onMaterialDispose( event ) {
M
Mr.doob 已提交
537 538 539 540 541 542 543

		var material = event.target;

		material.removeEventListener( 'dispose', onMaterialDispose );

		deallocateMaterial( material );

544
	}
M
Mr.doob 已提交
545 546 547

	// Buffer deallocation

548
	function deallocateMaterial( material ) {
M
Mr.doob 已提交
549

550 551
		releaseMaterialProgramReference( material );

552
		properties.remove( material );
553

554
	}
555 556


557
	function releaseMaterialProgramReference( material ) {
558

559
		var programInfo = properties.get( material ).program;
M
Mr.doob 已提交
560 561 562

		material.program = undefined;

563
		if ( programInfo !== undefined ) {
M
Mr.doob 已提交
564

565
			programCache.releaseProgram( programInfo );
M
Mr.doob 已提交
566

M
Mr.doob 已提交
567 568
		}

569
	}
M
Mr.doob 已提交
570 571 572

	// Buffer rendering

M
Mr.doob 已提交
573 574 575 576 577 578 579 580 581 582
	function renderObjectImmediate( object, program, material ) {

		object.render( function ( object ) {

			_this.renderBufferImmediate( object, program, material );

		} );

	}

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

585
		state.initAttributes();
586

587
		var buffers = properties.get( object );
588

589 590 591 592
		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 已提交
593

594
		var programAttributes = program.getAttributes();
595

M
Mr.doob 已提交
596 597
		if ( object.hasPositions ) {

598
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );
M
Mr.doob 已提交
599
			_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );
600

601 602
			state.enableAttribute( programAttributes.position );
			_gl.vertexAttribPointer( programAttributes.position, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
603 604 605 606 607

		}

		if ( object.hasNormals ) {

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

610
			if ( ! material.isMeshPhongMaterial &&
611
				! material.isMeshStandardMaterial &&
612
				! material.isMeshNormalMaterial &&
613
				material.flatShading === true ) {
M
Mr.doob 已提交
614

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

617
					var array = object.normalArray;
M
Mr.doob 已提交
618

619 620 621
					var nx = ( array[ i + 0 ] + array[ i + 3 ] + array[ i + 6 ] ) / 3;
					var ny = ( array[ i + 1 ] + array[ i + 4 ] + array[ i + 7 ] ) / 3;
					var nz = ( array[ i + 2 ] + array[ i + 5 ] + array[ i + 8 ] ) / 3;
M
Mr.doob 已提交
622

623 624 625
					array[ i + 0 ] = nx;
					array[ i + 1 ] = ny;
					array[ i + 2 ] = nz;
M
Mr.doob 已提交
626

627 628 629
					array[ i + 3 ] = nx;
					array[ i + 4 ] = ny;
					array[ i + 5 ] = nz;
M
Mr.doob 已提交
630

631 632 633
					array[ i + 6 ] = nx;
					array[ i + 7 ] = ny;
					array[ i + 8 ] = nz;
M
Mr.doob 已提交
634 635 636 637 638 639

				}

			}

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

641
			state.enableAttribute( programAttributes.normal );
642

643
			_gl.vertexAttribPointer( programAttributes.normal, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
644 645 646 647 648

		}

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

649
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );
M
Mr.doob 已提交
650
			_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );
651

652
			state.enableAttribute( programAttributes.uv );
653

654
			_gl.vertexAttribPointer( programAttributes.uv, 2, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
655 656 657

		}

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

660
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );
M
Mr.doob 已提交
661
			_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );
662

663
			state.enableAttribute( programAttributes.color );
664

665
			_gl.vertexAttribPointer( programAttributes.color, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
666 667 668

		}

669
		state.disableUnusedAttributes();
670

M
Mr.doob 已提交
671 672 673 674 675 676
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );

		object.count = 0;

	};

677
	this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {
678

679
		var frontFaceCW = ( object.isMesh && object.normalMatrix.determinant() < 0 );
680 681

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

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

M
Mr.doob 已提交
686
		var updateBuffers = false;
M
Mr.doob 已提交
687 688 689 690 691 692 693 694

		if ( geometryProgram !== _currentGeometryProgram ) {

			_currentGeometryProgram = geometryProgram;
			updateBuffers = true;

		}

695
		if ( object.morphTargetInfluences ) {
696

697
			morphtargets.update( object, geometry, material, program );
M
Mr.doob 已提交
698 699 700 701 702

			updateBuffers = true;

		}

703 704
		//

705
		var index = geometry.index;
706
		var position = geometry.attributes.position;
707
		var rangeFactor = 1;
708

709 710
		if ( material.wireframe === true ) {

711
			index = geometries.getWireframeAttribute( geometry );
712
			rangeFactor = 2;
713 714 715

		}

M
Mr.doob 已提交
716
		var attribute;
M
Mr.doob 已提交
717
		var renderer = bufferRenderer;
718

719
		if ( index !== null ) {
720

M
Mr.doob 已提交
721
			attribute = attributes.get( index );
722

723
			renderer = indexedBufferRenderer;
M
Mr.doob 已提交
724
			renderer.setIndex( attribute );
725

726
		}
M
Mr.doob 已提交
727

728
		if ( updateBuffers ) {
M
Mr.doob 已提交
729

730
			setupVertexAttributes( material, program, geometry );
M
Mr.doob 已提交
731

732
			if ( index !== null ) {
733

M
Mr.doob 已提交
734
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, attribute.buffer );
735 736 737

			}

738
		}
739

740 741
		//

742
		var dataCount = Infinity;
743

M
Mr.doob 已提交
744
		if ( index !== null ) {
745

M
Mr.doob 已提交
746
			dataCount = index.count;
747

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

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

M
Mr.doob 已提交
752
		}
753

M
Mr.doob 已提交
754 755
		var rangeStart = geometry.drawRange.start * rangeFactor;
		var rangeCount = geometry.drawRange.count * rangeFactor;
756

M
Mr.doob 已提交
757 758
		var groupStart = group !== null ? group.start * rangeFactor : 0;
		var groupCount = group !== null ? group.count * rangeFactor : Infinity;
759

M
Mr.doob 已提交
760
		var drawStart = Math.max( rangeStart, groupStart );
761
		var drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1;
M
Mr.doob 已提交
762 763 764

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

765 766
		if ( drawCount === 0 ) return;

M
Mr.doob 已提交
767
		//
768

769
		if ( object.isMesh ) {
770

771
			if ( material.wireframe === true ) {
772

773
				state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );
774
				renderer.setMode( _gl.LINES );
775

776
			} else {
M
Mr.doob 已提交
777 778

				switch ( object.drawMode ) {
779

R
Rich Harris 已提交
780
					case TrianglesDrawMode:
B
Ben Adams 已提交
781 782 783
						renderer.setMode( _gl.TRIANGLES );
						break;

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

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

				}
793

794
			}
795

796

797
		} else if ( object.isLine ) {
798

799
			var lineWidth = material.linewidth;
800

801
			if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material
802

803
			state.setLineWidth( lineWidth * getTargetPixelRatio() );
804

805
			if ( object.isLineSegments ) {
806

807
				renderer.setMode( _gl.LINES );
808

809 810 811 812
			} else if ( object.isLineLoop ) {

				renderer.setMode( _gl.LINE_LOOP );

813
			} else {
814

815
				renderer.setMode( _gl.LINE_STRIP );
816 817

			}
M
Mr.doob 已提交
818

819
		} else if ( object.isPoints ) {
820 821

			renderer.setMode( _gl.POINTS );
822 823

		}
824

T
Takahiro 已提交
825
		if ( geometry && geometry.isInstancedBufferGeometry ) {
M
Mr.doob 已提交
826 827 828

			if ( geometry.maxInstancedCount > 0 ) {

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

J
jfranc 已提交
831
			}
832 833 834

		} else {

M
Mr.doob 已提交
835
			renderer.render( drawStart, drawCount );
836

M
Mr.doob 已提交
837 838 839 840
		}

	};

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

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

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

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

M
Mr.doob 已提交
850 851 852
			}

		}
B
Ben Adams 已提交
853

854 855
		state.initAttributes();

856
		var geometryAttributes = geometry.attributes;
857

858
		var programAttributes = program.getAttributes();
859

860
		var materialDefaultAttributeValues = material.defaultAttributeValues;
861

862
		for ( var name in programAttributes ) {
863

864
			var programAttribute = programAttributes[ name ];
M
Mr.doob 已提交
865

M
Mr.doob 已提交
866
			if ( programAttribute >= 0 ) {
M
Mr.doob 已提交
867

868
				var geometryAttribute = geometryAttributes[ name ];
869

M
Mr.doob 已提交
870
				if ( geometryAttribute !== undefined ) {
M
Mr.doob 已提交
871

872
					var normalized = geometryAttribute.normalized;
873
					var size = geometryAttribute.itemSize;
874

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

877 878 879 880
					// TODO Attribute may not be available on context restore

					if ( attribute === undefined ) continue;

M
Mr.doob 已提交
881 882 883
					var buffer = attribute.buffer;
					var type = attribute.type;
					var bytesPerElement = attribute.bytesPerElement;
884

A
aardgoose 已提交
885
					if ( geometryAttribute.isInterleavedBufferAttribute ) {
886

M
Mr.doob 已提交
887 888 889 890
						var data = geometryAttribute.data;
						var stride = data.stride;
						var offset = geometryAttribute.offset;

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

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

M
Mr.doob 已提交
895
							if ( geometry.maxInstancedCount === undefined ) {
896

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

M
Mr.doob 已提交
899
							}
B
Ben Adams 已提交
900

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

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

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

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

M
Mr.doob 已提交
910
					} else {
B
Ben Adams 已提交
911

A
aardgoose 已提交
912
						if ( geometryAttribute.isInstancedBufferAttribute ) {
B
Ben Adams 已提交
913

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

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

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

M
Mr.doob 已提交
920
							}
B
Ben Adams 已提交
921

M
Mr.doob 已提交
922 923 924 925
						} else {

							state.enableAttribute( programAttribute );

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

M
Mr.doob 已提交
928
						_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
929
						_gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, 0 );
M
Mr.doob 已提交
930

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

933 934
				} else if ( materialDefaultAttributeValues !== undefined ) {

T
tschw 已提交
935
					var value = materialDefaultAttributeValues[ name ];
936

937
					if ( value !== undefined ) {
M
Mr.doob 已提交
938

939
						switch ( value.length ) {
M
Mr.doob 已提交
940

941 942 943
							case 2:
								_gl.vertexAttrib2fv( programAttribute, value );
								break;
M
Mr.doob 已提交
944

945 946 947
							case 3:
								_gl.vertexAttrib3fv( programAttribute, value );
								break;
M
Mr.doob 已提交
948

949 950 951
							case 4:
								_gl.vertexAttrib4fv( programAttribute, value );
								break;
952

953 954
							default:
								_gl.vertexAttrib1fv( programAttribute, value );
955 956

						}
M
Mr.doob 已提交
957 958 959 960 961 962 963 964

					}

				}

			}

		}
965

966
		state.disableUnusedAttributes();
967

M
Mr.doob 已提交
968 969
	}

M
Mr.doob 已提交
970
	// Compile
M
Mr.doob 已提交
971

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

M
Mr.doob 已提交
974
		currentRenderState = renderStates.get( scene, camera );
975
		currentRenderState.init();
976

M
Mr.doob 已提交
977
		scene.traverse( function ( object ) {
G
gero3 已提交
978 979

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

981
				currentRenderState.pushLight( object );
982 983 984

				if ( object.castShadow ) {

985
					currentRenderState.pushShadow( object );
986 987

				}
M
Mr.doob 已提交
988

G
gero3 已提交
989
			}
M
Mr.doob 已提交
990 991 992

		} );

993
		currentRenderState.setupLights( camera );
M
Mr.doob 已提交
994 995 996 997 998

		scene.traverse( function ( object ) {

			if ( object.material ) {

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

G
gero3 已提交
1001
					for ( var i = 0; i < object.material.length; i ++ ) {
M
Mr.doob 已提交
1002 1003 1004

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

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

G
gero3 已提交
1007
				} else {
M
Mr.doob 已提交
1008 1009 1010

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

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

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

		} );
G
gero3 已提交
1016 1017

	};
1018

1019
	// Animation Loop
M
Mr.doob 已提交
1020

M
Mr.doob 已提交
1021
	var onAnimationFrameCallback = null;
1022

1023
	function onAnimationFrame( time ) {
1024

M
Mr.doob 已提交
1025
		if ( vr.isPresenting() ) return;
1026
		if ( onAnimationFrameCallback ) onAnimationFrameCallback( time );
1027

1028
	}
1029

M
Mr.doob 已提交
1030 1031
	var animation = new WebGLAnimation();
	animation.setAnimationLoop( onAnimationFrame );
1032 1033

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

1035
	this.setAnimationLoop = function ( callback ) {
1036

M
Mr.doob 已提交
1037 1038
		onAnimationFrameCallback = callback;
		vr.setAnimationLoop( callback );
1039

1040 1041
		animation.start();

1042 1043
	};

M
Mr.doob 已提交
1044 1045 1046
	// Rendering

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

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

1050
			console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );
M
Mr.doob 已提交
1051 1052 1053 1054
			return;

		}

1055 1056
		if ( _isContextLost ) return;

M
Mr.doob 已提交
1057 1058
		// reset caching for this frame

1059
		_currentGeometryProgram = '';
1060
		_currentMaterialId = - 1;
1061
		_currentCamera = null;
M
Mr.doob 已提交
1062 1063 1064

		// update scene graph

1065
		if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
M
Mr.doob 已提交
1066 1067 1068

		// update camera matrices and frustum

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

1071 1072 1073 1074 1075 1076
		if ( vr.enabled ) {

			camera = vr.getCamera( camera );

		}

1077 1078
		//

1079 1080
		currentRenderState = renderStates.get( scene, camera );
		currentRenderState.init();
1081

1082 1083
		scene.onBeforeRender( _this, scene, camera, renderTarget );

M
Mr.doob 已提交
1084 1085 1086
		_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
		_frustum.setFromMatrix( _projScreenMatrix );

T
tschw 已提交
1087
		_localClippingEnabled = this.localClippingEnabled;
M
Mr.doob 已提交
1088
		_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );
T
tschw 已提交
1089

1090 1091 1092
		currentRenderList = renderLists.get( scene, camera );
		currentRenderList.init();

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

M
Mr.doob 已提交
1095
		if ( _this.sortObjects === true ) {
1096

1097
			currentRenderList.sort();
M
Mr.doob 已提交
1098

1099 1100
		}

M
Mr.doob 已提交
1101
		//
M
Mr.doob 已提交
1102

T
tschw 已提交
1103
		if ( _clippingEnabled ) _clipping.beginShadows();
T
tschw 已提交
1104

1105
		var shadowsArray = currentRenderState.state.shadowsArray;
1106

1107
		shadowMap.render( shadowsArray, scene, camera );
1108

1109
		currentRenderState.setupLights( camera );
1110

T
tschw 已提交
1111
		if ( _clippingEnabled ) _clipping.endShadows();
T
tschw 已提交
1112

M
Mr.doob 已提交
1113 1114
		//

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

1117 1118 1119 1120 1121 1122
		if ( renderTarget === undefined ) {

			renderTarget = null;

		}

M
Mr.doob 已提交
1123 1124
		this.setRenderTarget( renderTarget );

M
Mr.doob 已提交
1125 1126
		//

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

1129
		// render scene
M
Mr.doob 已提交
1130

1131 1132 1133
		var opaqueObjects = currentRenderList.opaque;
		var transparentObjects = currentRenderList.transparent;

M
Mr.doob 已提交
1134 1135
		if ( scene.overrideMaterial ) {

1136
			var overrideMaterial = scene.overrideMaterial;
M
Mr.doob 已提交
1137

M
Mr.doob 已提交
1138 1139
			if ( opaqueObjects.length ) renderObjects( opaqueObjects, scene, camera, overrideMaterial );
			if ( transparentObjects.length ) renderObjects( transparentObjects, scene, camera, overrideMaterial );
1140

M
Mr.doob 已提交
1141 1142 1143 1144
		} else {

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

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

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

M
Mr.doob 已提交
1149
			if ( transparentObjects.length ) renderObjects( transparentObjects, scene, camera );
M
Mr.doob 已提交
1150 1151 1152

		}

1153
		// custom renderers
M
Mr.doob 已提交
1154

1155
		var spritesArray = currentRenderState.state.spritesArray;
1156

1157
		spriteRenderer.render( spritesArray, scene, camera );
M
Mr.doob 已提交
1158 1159 1160

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

M
Mr.doob 已提交
1161 1162
		if ( renderTarget ) {

1163
			textures.updateRenderTargetMipmap( renderTarget );
M
Mr.doob 已提交
1164 1165 1166

		}

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

1169 1170 1171
		state.buffers.depth.setTest( true );
		state.buffers.depth.setMask( true );
		state.buffers.color.setMask( true );
M
Mr.doob 已提交
1172

1173
		state.setPolygonOffset( false );
1174

1175
		scene.onAfterRender( _this, scene, camera );
1176

M
Mr.doob 已提交
1177
		if ( vr.enabled ) {
1178

M
Mr.doob 已提交
1179
			vr.submitFrame();
1180

M
Mr.doob 已提交
1181
		}
M
Mr.doob 已提交
1182

M
Mr.doob 已提交
1183 1184
		// _gl.finish();

1185
		currentRenderList = null;
1186
		currentRenderState = null;
1187

M
Mr.doob 已提交
1188
	};
M
Mr.doob 已提交
1189

1190
	/*
M
Mr.doob 已提交
1191 1192
	// TODO Duplicated code (Frustum)

1193 1194
	var _sphere = new Sphere();

T
tschw 已提交
1195 1196 1197 1198 1199 1200 1201
	function isObjectViewable( object ) {

		var geometry = object.geometry;

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

M
Mr.doob 已提交
1202
		_sphere.copy( geometry.boundingSphere ).
1203
		applyMatrix4( object.matrixWorld );
M
Mr.doob 已提交
1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219

		return isSphereViewable( _sphere );

	}

	function isSpriteViewable( sprite ) {

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

		return isSphereViewable( _sphere );

	}

	function isSphereViewable( sphere ) {
T
tschw 已提交
1220 1221

		if ( ! _frustum.intersectsSphere( sphere ) ) return false;
T
tschw 已提交
1222 1223 1224 1225

		var numPlanes = _clipping.numPlanes;

		if ( numPlanes === 0 ) return true;
T
tschw 已提交
1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237

		var planes = _this.clippingPlanes,

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

		do {

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

T
tschw 已提交
1238
		} while ( ++ i !== numPlanes );
T
tschw 已提交
1239 1240 1241 1242

		return true;

	}
1243
	*/
T
tschw 已提交
1244

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

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

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

1251
		if ( visible ) {
1252

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

1255
				currentRenderState.pushLight( object );
1256 1257 1258

				if ( object.castShadow ) {

1259
					currentRenderState.pushShadow( object );
1260 1261

				}
M
Mr.doob 已提交
1262

1263
			} else if ( object.isSprite ) {
M
Mr.doob 已提交
1264

1265
				if ( ! object.frustumCulled || _frustum.intersectsSprite( object ) ) {
1266

1267
					currentRenderState.pushSprite( object );
M
Mr.doob 已提交
1268

1269
				}
M
Mr.doob 已提交
1270

1271
			} else if ( object.isImmediateRenderObject ) {
M
Mr.doob 已提交
1272

1273
				if ( sortObjects ) {
M
Mr.doob 已提交
1274

1275 1276
					_vector3.setFromMatrixPosition( object.matrixWorld )
						.applyMatrix4( _projScreenMatrix );
M
Mr.doob 已提交
1277

1278
				}
M
Mr.doob 已提交
1279

1280
				currentRenderList.push( object, null, object.material, _vector3.z, null );
1281

1282
			} else if ( object.isMesh || object.isLine || object.isPoints ) {
1283

1284
				if ( object.isSkinnedMesh ) {
1285

1286
					object.skeleton.update();
1287

1288
				}
1289

1290
				if ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) {
1291

1292 1293 1294 1295 1296 1297
					if ( sortObjects ) {

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

					}
1298

1299 1300
					var geometry = objects.update( object );
					var material = object.material;
1301

1302
					if ( Array.isArray( material ) ) {
1303

1304
						var groups = geometry.groups;
1305

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

1308 1309
							var group = groups[ i ];
							var groupMaterial = material[ group.materialIndex ];
1310

1311
							if ( groupMaterial && groupMaterial.visible ) {
1312

1313 1314 1315
								currentRenderList.push( object, geometry, groupMaterial, _vector3.z, group );

							}
M
Mr.doob 已提交
1316

M
Mr.doob 已提交
1317
						}
M
Mr.doob 已提交
1318

1319
					} else if ( material.visible ) {
1320

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

1323
					}
M
Mr.doob 已提交
1324

1325
				}
M
Mr.doob 已提交
1326

1327
			}
M
Mr.doob 已提交
1328

M
Mr.doob 已提交
1329
		}
M
Mr.doob 已提交
1330

M
Mr.doob 已提交
1331
		var children = object.children;
M
Mr.doob 已提交
1332

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

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

1337
		}
1338

1339
	}
M
Mr.doob 已提交
1340

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

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

1345
			var renderItem = renderList[ i ];
M
Mr.doob 已提交
1346

1347
			var object = renderItem.object;
M
Mr.doob 已提交
1348 1349 1350
			var geometry = renderItem.geometry;
			var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;
			var group = renderItem.group;
M
Mr.doob 已提交
1351

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

1354 1355
				_currentArrayCamera = camera;

M
Mr.doob 已提交
1356
				var cameras = camera.cameras;
M
Mr.doob 已提交
1357

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

M
Mr.doob 已提交
1360
					var camera2 = cameras[ j ];
M
Mr.doob 已提交
1361

1362
					if ( object.layers.test( camera2.layers ) ) {
1363

M
Mr.doob 已提交
1364 1365 1366 1367 1368 1369 1370
						if ( 'viewport' in camera2 ) { // XR

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

						} else {

							var bounds = camera2.bounds;
1371

M
Mr.doob 已提交
1372 1373 1374 1375
							var x = bounds.x * _width;
							var y = bounds.y * _height;
							var width = bounds.z * _width;
							var height = bounds.w * _height;
M
Mr.doob 已提交
1376

M
Mr.doob 已提交
1377 1378 1379
							state.viewport( _currentViewport.set( x, y, width, height ).multiplyScalar( _pixelRatio ) );

						}
1380 1381 1382 1383

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

					}
M
Mr.doob 已提交
1384

M
Mr.doob 已提交
1385
				}
1386

M
Mr.doob 已提交
1387
			} else {
M
Mr.doob 已提交
1388

1389 1390
				_currentArrayCamera = null;

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

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

1395
		}
M
Mr.doob 已提交
1396

1397
	}
G
gero3 已提交
1398

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

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

M
Mr.doob 已提交
1404 1405 1406 1407 1408
		object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
		object.normalMatrix.getNormalMatrix( object.modelViewMatrix );

		if ( object.isImmediateRenderObject ) {

1409
			var frontFaceCW = ( object.isMesh && object.normalMatrix.determinant() < 0 );
1410 1411

			state.setMaterial( material, frontFaceCW );
M
Mr.doob 已提交
1412 1413 1414 1415 1416 1417 1418 1419 1420

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

			_currentGeometryProgram = '';

			renderObjectImmediate( object, program, material );

		} else {

M
Mugen87 已提交
1421
			_this.renderBufferDirect( camera, scene.fog, geometry, material, object, group );
M
Mr.doob 已提交
1422 1423 1424

		}

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

M
Mr.doob 已提交
1428 1429
	}

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

1432
		var materialProperties = properties.get( material );
G
gero3 已提交
1433

1434 1435
		var lights = currentRenderState.state.lights;
		var shadowsArray = currentRenderState.state.shadowsArray;
1436

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

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

1442
		var program = materialProperties.program;
T
tschw 已提交
1443
		var programChange = true;
1444

1445
		if ( program === undefined ) {
B
Ben Adams 已提交
1446

M
Mr.doob 已提交
1447 1448
			// new material
			material.addEventListener( 'dispose', onMaterialDispose );
B
Ben Adams 已提交
1449

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

M
Mr.doob 已提交
1452
			// changed glsl or parameters
1453
			releaseMaterialProgramReference( material );
B
Ben Adams 已提交
1454

1455 1456 1457 1458 1459
		} else if ( materialProperties.lightsHash !== lights.state.hash ) {

			properties.update( material, 'lightsHash', lights.state.hash );
			programChange = false;

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

T
tschw 已提交
1462
			// same glsl and uniform list
T
tschw 已提交
1463 1464
			return;

T
tschw 已提交
1465
		} else {
B
Ben Adams 已提交
1466

T
tschw 已提交
1467 1468
			// only rebuild uniform list
			programChange = false;
B
Ben Adams 已提交
1469 1470 1471

		}

1472
		if ( programChange ) {
B
Ben Adams 已提交
1473

1474
			if ( parameters.shaderID ) {
B
Ben Adams 已提交
1475

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

1478
				materialProperties.shader = {
1479
					name: material.type,
1480
					uniforms: UniformsUtils.clone( shader.uniforms ),
1481
					vertexShader: shader.vertexShader,
1482
					fragmentShader: shader.fragmentShader
1483
				};
B
Ben Adams 已提交
1484

1485
			} else {
B
Ben Adams 已提交
1486

1487
				materialProperties.shader = {
1488 1489 1490
					name: material.type,
					uniforms: material.uniforms,
					vertexShader: material.vertexShader,
1491
					fragmentShader: material.fragmentShader
1492
				};
G
gero3 已提交
1493

1494
			}
G
gero3 已提交
1495

1496
			material.onBeforeCompile( materialProperties.shader, _this );
G
gero3 已提交
1497

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

1500 1501
			materialProperties.program = program;
			material.program = program;
1502 1503 1504

		}

1505
		var programAttributes = program.getAttributes();
M
Mr.doob 已提交
1506 1507 1508 1509 1510

		if ( material.morphTargets ) {

			material.numSupportedMorphTargets = 0;

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

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

					material.numSupportedMorphTargets ++;

				}

			}

		}

		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

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

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

					material.numSupportedMorphNormals ++;

				}

			}

		}

1539
		var uniforms = materialProperties.shader.uniforms;
T
tschw 已提交
1540

1541
		if ( ! material.isShaderMaterial &&
1542 1543
			! material.isRawShaderMaterial ||
			material.clipping === true ) {
T
tschw 已提交
1544

T
tschw 已提交
1545
			materialProperties.numClippingPlanes = _clipping.numPlanes;
1546
			materialProperties.numIntersection = _clipping.numIntersection;
T
tschw 已提交
1547
			uniforms.clippingPlanes = _clipping.uniform;
T
tschw 已提交
1548 1549 1550

		}

1551
		materialProperties.fog = fog;
1552

1553
		// store the light setup it was created for
1554

1555
		materialProperties.lightsHash = lights.state.hash;
1556

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

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

1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573
			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;
1574
			// TODO (abelnation): add area lights shadow info to uniforms
1575

1576 1577
		}

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

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

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

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

		_usedTextureUnits = 0;

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

T
tschw 已提交
1593 1594 1595 1596 1597
		if ( _clippingEnabled ) {

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

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

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

			}

		}

1612
		if ( material.needsUpdate === false ) {
1613

1614
			if ( materialProperties.program === undefined ) {
1615

1616
				material.needsUpdate = true;
1617

1618
			} else if ( material.fog && materialProperties.fog !== fog ) {
1619

M
Mr.doob 已提交
1620
				material.needsUpdate = true;
1621

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

1624
				material.needsUpdate = true;
1625

1626
			} else if ( materialProperties.numClippingPlanes !== undefined &&
1627
				( materialProperties.numClippingPlanes !== _clipping.numPlanes ||
M
Mr.doob 已提交
1628
				materialProperties.numIntersection !== _clipping.numIntersection ) ) {
1629 1630 1631

				material.needsUpdate = true;

1632
			}
1633 1634 1635 1636

		}

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

1638
			initMaterial( material, fog, object );
M
Mr.doob 已提交
1639 1640 1641 1642
			material.needsUpdate = false;

		}

1643
		var refreshProgram = false;
M
Mr.doob 已提交
1644
		var refreshMaterial = false;
1645
		var refreshLights = false;
M
Mr.doob 已提交
1646

1647
		var program = materialProperties.program,
1648
			p_uniforms = program.getUniforms(),
1649
			m_uniforms = materialProperties.shader.uniforms;
M
Mr.doob 已提交
1650

1651
		if ( state.useProgram( program.program ) ) {
M
Mr.doob 已提交
1652

1653
			refreshProgram = true;
M
Mr.doob 已提交
1654
			refreshMaterial = true;
1655
			refreshLights = true;
M
Mr.doob 已提交
1656 1657 1658 1659 1660 1661

		}

		if ( material.id !== _currentMaterialId ) {

			_currentMaterialId = material.id;
1662

M
Mr.doob 已提交
1663 1664 1665 1666
			refreshMaterial = true;

		}

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

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

G
gero3 已提交
1671
			if ( capabilities.logarithmicDepthBuffer ) {
1672

T
tschw 已提交
1673
				p_uniforms.setValue( _gl, 'logDepthBufFC',
1674
					2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
1675 1676 1677

			}

1678
			// Avoid unneeded uniform updates per ArrayCamera's sub-camera
1679

1680
			if ( _currentCamera !== ( _currentArrayCamera || camera ) ) {
1681

1682
				_currentCamera = ( _currentArrayCamera || camera );
1683 1684 1685 1686 1687 1688

				// 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 已提交
1689
				refreshLights = true;		// remains set until update done
1690 1691

			}
M
Mr.doob 已提交
1692

1693 1694 1695
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)

1696
			if ( material.isShaderMaterial ||
1697 1698 1699
				material.isMeshPhongMaterial ||
				material.isMeshStandardMaterial ||
				material.envMap ) {
1700

T
tschw 已提交
1701 1702 1703
				var uCamPos = p_uniforms.map.cameraPosition;

				if ( uCamPos !== undefined ) {
1704

T
tschw 已提交
1705
					uCamPos.setValue( _gl,
1706
						_vector3.setFromMatrixPosition( camera.matrixWorld ) );
1707 1708 1709 1710 1711

				}

			}

1712
			if ( material.isMeshPhongMaterial ||
1713 1714 1715 1716
				material.isMeshLambertMaterial ||
				material.isMeshBasicMaterial ||
				material.isMeshStandardMaterial ||
				material.isShaderMaterial ||
1717
				material.skinning ) {
1718

T
tschw 已提交
1719
				p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );
1720 1721 1722

			}

M
Mr.doob 已提交
1723 1724 1725 1726 1727 1728
		}

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

1729
		if ( material.skinning ) {
M
Mr.doob 已提交
1730

T
tschw 已提交
1731 1732
			p_uniforms.setOptional( _gl, object, 'bindMatrix' );
			p_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );
1733

T
tschw 已提交
1734
			var skeleton = object.skeleton;
1735

T
tschw 已提交
1736
			if ( skeleton ) {
1737

1738 1739
				var bones = skeleton.bones;

1740
				if ( capabilities.floatVertexTextures ) {
M
Mr.doob 已提交
1741

1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752
					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
1753
						size = _Math.ceilPowerOfTwo( size );
1754 1755 1756 1757 1758 1759
						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 );
1760
						boneTexture.needsUpdate = true;
1761 1762 1763 1764 1765 1766 1767

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

					}

M
Mr.doob 已提交
1768 1769
					p_uniforms.setValue( _gl, 'boneTexture', skeleton.boneTexture );
					p_uniforms.setValue( _gl, 'boneTextureSize', skeleton.boneTextureSize );
M
Mr.doob 已提交
1770

T
tschw 已提交
1771
				} else {
M
Mr.doob 已提交
1772

T
tschw 已提交
1773
					p_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );
M
Mr.doob 已提交
1774 1775 1776 1777 1778 1779 1780 1781 1782

				}

			}

		}

		if ( refreshMaterial ) {

1783 1784 1785
			p_uniforms.setValue( _gl, 'toneMappingExposure', _this.toneMappingExposure );
			p_uniforms.setValue( _gl, 'toneMappingWhitePoint', _this.toneMappingWhitePoint );

M
Mr.doob 已提交
1786
			if ( material.lights ) {
M
Mr.doob 已提交
1787

1788
				// the current material requires lighting info
M
Mr.doob 已提交
1789

T
tschw 已提交
1790 1791 1792 1793 1794 1795
				// 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 已提交
1796

T
tschw 已提交
1797
				markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
G
gero3 已提交
1798

T
tschw 已提交
1799
			}
G
gero3 已提交
1800

T
tschw 已提交
1801
			// refresh uniforms common to several materials
G
gero3 已提交
1802

T
tschw 已提交
1803
			if ( fog && material.fog ) {
G
gero3 已提交
1804

T
tschw 已提交
1805
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
1806 1807 1808

			}

1809
			if ( material.isMeshBasicMaterial ) {
M
Mr.doob 已提交
1810 1811 1812

				refreshUniformsCommon( m_uniforms, material );

1813
			} else if ( material.isMeshLambertMaterial ) {
M
Mr.doob 已提交
1814

1815 1816
				refreshUniformsCommon( m_uniforms, material );
				refreshUniformsLambert( m_uniforms, material );
M
Mr.doob 已提交
1817

1818
			} else if ( material.isMeshPhongMaterial ) {
M
Mr.doob 已提交
1819

1820
				refreshUniformsCommon( m_uniforms, material );
M
Mr.doob 已提交
1821

1822
				if ( material.isMeshToonMaterial ) {
M
Mr.doob 已提交
1823

1824
					refreshUniformsToon( m_uniforms, material );
M
Mr.doob 已提交
1825

1826
				} else {
1827

1828
					refreshUniformsPhong( m_uniforms, material );
1829

1830
				}
T
Takahiro 已提交
1831

1832
			} else if ( material.isMeshStandardMaterial ) {
T
Takahiro 已提交
1833

1834
				refreshUniformsCommon( m_uniforms, material );
1835

1836
				if ( material.isMeshPhysicalMaterial ) {
1837

1838
					refreshUniformsPhysical( m_uniforms, material );
W
WestLangley 已提交
1839

1840
				} else {
W
WestLangley 已提交
1841

1842
					refreshUniformsStandard( m_uniforms, material );
W
WestLangley 已提交
1843

1844
				}
W
WestLangley 已提交
1845

1846
			} else if ( material.isMeshDepthMaterial ) {
M
Mr.doob 已提交
1847

1848
				refreshUniformsCommon( m_uniforms, material );
W
WestLangley 已提交
1849
				refreshUniformsDepth( m_uniforms, material );
1850

W
WestLangley 已提交
1851
			} else if ( material.isMeshDistanceMaterial ) {
1852

1853
				refreshUniformsCommon( m_uniforms, material );
W
WestLangley 已提交
1854
				refreshUniformsDistance( m_uniforms, material );
1855

1856
			} else if ( material.isMeshNormalMaterial ) {
M
Mr.doob 已提交
1857

1858
				refreshUniformsCommon( m_uniforms, material );
1859
				refreshUniformsNormal( m_uniforms, material );
M
Mr.doob 已提交
1860

1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874
			} else if ( material.isLineBasicMaterial ) {

				refreshUniformsLine( m_uniforms, material );

				if ( material.isLineDashedMaterial ) {

					refreshUniformsDash( m_uniforms, material );

				}

			} else if ( material.isPointsMaterial ) {

				refreshUniformsPoints( m_uniforms, material );

1875 1876 1877 1878 1879
			} else if ( material.isShadowMaterial ) {

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

M
Mr.doob 已提交
1880 1881
			}

M
Mr.doob 已提交
1882 1883 1884
			// RectAreaLight Texture
			// TODO (mrdoob): Find a nicer implementation

1885 1886
			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 已提交
1887

1888
			WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, _this );
A
arose 已提交
1889 1890 1891

		}

1892 1893 1894 1895 1896 1897
		if ( material.isShaderMaterial && material.uniformsNeedUpdate === true ) {

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

		}
M
Mr.doob 已提交
1898

T
tschw 已提交
1899
		// common matrices
M
Mr.doob 已提交
1900

M
Mr.doob 已提交
1901 1902
		p_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix );
		p_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix );
T
tschw 已提交
1903
		p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );
A
arose 已提交
1904

T
tschw 已提交
1905
		return program;
A
arose 已提交
1906 1907 1908

	}

M
Mr.doob 已提交
1909 1910
	// Uniforms (refresh uniforms objects)

M
Mr.doob 已提交
1911
	function refreshUniformsCommon( uniforms, material ) {
M
Mr.doob 已提交
1912 1913 1914

		uniforms.opacity.value = material.opacity;

1915 1916 1917 1918 1919
		if ( material.color ) {

			uniforms.diffuse.value = material.color;

		}
M
Mr.doob 已提交
1920

1921
		if ( material.emissive ) {
M
Mr.doob 已提交
1922

1923
			uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );
M
Mr.doob 已提交
1924 1925 1926

		}

1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957
		if ( material.map ) {

			uniforms.map.value = material.map;

		}

		if ( material.alphaMap ) {

			uniforms.alphaMap.value = material.alphaMap;

		}

		if ( material.specularMap ) {

			uniforms.specularMap.value = material.specularMap;

		}

		if ( material.envMap ) {

			uniforms.envMap.value = material.envMap;

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

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

1958
			uniforms.maxMipLevel.value = properties.get( material.envMap ).__maxMipLevel;
1959

1960
		}
M
Mr.doob 已提交
1961

1962 1963 1964 1965 1966 1967 1968
		if ( material.lightMap ) {

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

		}

1969
		if ( material.aoMap ) {
1970

1971 1972
			uniforms.aoMap.value = material.aoMap;
			uniforms.aoMapIntensity.value = material.aoMapIntensity;
1973 1974 1975

		}

M
Mr.doob 已提交
1976
		// uv repeat and offset setting priorities
M
Mr.doob 已提交
1977 1978 1979 1980 1981
		// 1. color map
		// 2. specular map
		// 3. normal map
		// 4. bump map
		// 5. alpha map
1982
		// 6. emissive map
M
Mr.doob 已提交
1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993

		var uvScaleMap;

		if ( material.map ) {

			uvScaleMap = material.map;

		} else if ( material.specularMap ) {

			uvScaleMap = material.specularMap;

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

			uvScaleMap = material.displacementMap;

M
Mr.doob 已提交
1998 1999 2000 2001 2002 2003 2004 2005
		} else if ( material.normalMap ) {

			uvScaleMap = material.normalMap;

		} else if ( material.bumpMap ) {

			uvScaleMap = material.bumpMap;

2006 2007 2008 2009 2010 2011 2012 2013
		} else if ( material.roughnessMap ) {

			uvScaleMap = material.roughnessMap;

		} else if ( material.metalnessMap ) {

			uvScaleMap = material.metalnessMap;

2014 2015 2016 2017
		} else if ( material.alphaMap ) {

			uvScaleMap = material.alphaMap;

2018 2019 2020 2021
		} else if ( material.emissiveMap ) {

			uvScaleMap = material.emissiveMap;

M
Mr.doob 已提交
2022 2023 2024 2025
		}

		if ( uvScaleMap !== undefined ) {

2026
			// backwards compatibility
2027
			if ( uvScaleMap.isWebGLRenderTarget ) {
M
Mr.doob 已提交
2028 2029 2030 2031 2032

				uvScaleMap = uvScaleMap.texture;

			}

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

W
WestLangley 已提交
2035
				uvScaleMap.updateMatrix();
M
Mr.doob 已提交
2036

W
WestLangley 已提交
2037
			}
2038

2039
			uniforms.uvTransform.value.copy( uvScaleMap.matrix );
M
Mr.doob 已提交
2040 2041 2042

		}

M
Mr.doob 已提交
2043
	}
M
Mr.doob 已提交
2044

M
Mr.doob 已提交
2045
	function refreshUniformsLine( uniforms, material ) {
M
Mr.doob 已提交
2046 2047 2048 2049

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

M
Mr.doob 已提交
2050
	}
M
Mr.doob 已提交
2051

M
Mr.doob 已提交
2052
	function refreshUniformsDash( uniforms, material ) {
M
Mr.doob 已提交
2053 2054 2055 2056 2057

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

M
Mr.doob 已提交
2058
	}
M
Mr.doob 已提交
2059

M
Mr.doob 已提交
2060
	function refreshUniformsPoints( uniforms, material ) {
M
Mr.doob 已提交
2061

2062
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
2063
		uniforms.opacity.value = material.opacity;
2064
		uniforms.size.value = material.size * _pixelRatio;
2065
		uniforms.scale.value = _height * 0.5;
M
Mr.doob 已提交
2066 2067 2068

		uniforms.map.value = material.map;

2069 2070
		if ( material.map !== null ) {

W
WestLangley 已提交
2071
			if ( material.map.matrixAutoUpdate === true ) {
2072

W
WestLangley 已提交
2073
				material.map.updateMatrix();
W
WestLangley 已提交
2074 2075

			}
2076

2077
			uniforms.uvTransform.value.copy( material.map.matrix );
2078 2079 2080

		}

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

M
Mr.doob 已提交
2083
	function refreshUniformsFog( uniforms, fog ) {
M
Mr.doob 已提交
2084 2085 2086

		uniforms.fogColor.value = fog.color;

2087
		if ( fog.isFog ) {
M
Mr.doob 已提交
2088 2089 2090 2091

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

2092
		} else if ( fog.isFogExp2 ) {
M
Mr.doob 已提交
2093 2094 2095 2096 2097

			uniforms.fogDensity.value = fog.density;

		}

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

M
Mr.doob 已提交
2100
	function refreshUniformsLambert( uniforms, material ) {
2101 2102 2103 2104 2105 2106 2107 2108 2109

		if ( material.emissiveMap ) {

			uniforms.emissiveMap.value = material.emissiveMap;

		}

	}

M
Mr.doob 已提交
2110
	function refreshUniformsPhong( uniforms, material ) {
M
Mr.doob 已提交
2111

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

2115
		if ( material.emissiveMap ) {
2116

2117
			uniforms.emissiveMap.value = material.emissiveMap;
2118

2119
		}
M
Mr.doob 已提交
2120

2121 2122 2123 2124
		if ( material.bumpMap ) {

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

2127
		}
M
Mr.doob 已提交
2128

2129 2130 2131 2132
		if ( material.normalMap ) {

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

		}
M
Mr.doob 已提交
2136

2137 2138 2139 2140 2141
		if ( material.displacementMap ) {

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

2143
		}
2144

T
Takahiro 已提交
2145 2146 2147 2148 2149 2150
	}

	function refreshUniformsToon( uniforms, material ) {

		refreshUniformsPhong( uniforms, material );

T
Takahiro 已提交
2151
		if ( material.gradientMap ) {
T
Takahiro 已提交
2152

T
Takahiro 已提交
2153
			uniforms.gradientMap.value = material.gradientMap;
T
Takahiro 已提交
2154 2155 2156

		}

2157 2158
	}

M
Mr.doob 已提交
2159
	function refreshUniformsStandard( uniforms, material ) {
W
WestLangley 已提交
2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185

		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;
2186
			if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1;
W
WestLangley 已提交
2187 2188 2189 2190 2191 2192 2193

		}

		if ( material.normalMap ) {

			uniforms.normalMap.value = material.normalMap;
			uniforms.normalScale.value.copy( material.normalScale );
2194
			if ( material.side === BackSide ) uniforms.normalScale.value.negate();
W
WestLangley 已提交
2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214

		}

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

2217 2218 2219 2220
		refreshUniformsStandard( uniforms, material );

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

2221 2222 2223
		uniforms.clearCoat.value = material.clearCoat;
		uniforms.clearCoatRoughness.value = material.clearCoatRoughness;

W
WestLangley 已提交
2224 2225
	}

W
WestLangley 已提交
2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253
	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;

	}

2254 2255 2256 2257 2258 2259
	function refreshUniformsNormal( uniforms, material ) {

		if ( material.bumpMap ) {

			uniforms.bumpMap.value = material.bumpMap;
			uniforms.bumpScale.value = material.bumpScale;
2260
			if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1;
2261 2262 2263 2264 2265 2266 2267

		}

		if ( material.normalMap ) {

			uniforms.normalMap.value = material.normalMap;
			uniforms.normalScale.value.copy( material.normalScale );
2268
			if ( material.side === BackSide ) uniforms.normalScale.value.negate();
2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281

		}

		if ( material.displacementMap ) {

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

		}

	}

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

M
Mr.doob 已提交
2284
	function markUniformsLightsNeedsUpdate( uniforms, value ) {
2285

M
Mr.doob 已提交
2286
		uniforms.ambientLightColor.needsUpdate = value;
2287

B
Ben Houston 已提交
2288 2289 2290
		uniforms.directionalLights.needsUpdate = value;
		uniforms.pointLights.needsUpdate = value;
		uniforms.spotLights.needsUpdate = value;
2291
		uniforms.rectAreaLights.needsUpdate = value;
B
Ben Houston 已提交
2292
		uniforms.hemisphereLights.needsUpdate = value;
2293

M
Mr.doob 已提交
2294
	}
2295

M
Mr.doob 已提交
2296 2297
	// Textures

T
tschw 已提交
2298 2299 2300 2301 2302 2303
	function allocTextureUnit() {

		var textureUnit = _usedTextureUnits;

		if ( textureUnit >= capabilities.maxTextures ) {

M
Mugen87 已提交
2304
			console.warn( 'THREE.WebGLRenderer: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );
T
tschw 已提交
2305 2306 2307 2308 2309 2310 2311 2312 2313

		}

		_usedTextureUnits += 1;

		return textureUnit;

	}

2314
	this.allocTextureUnit = allocTextureUnit;
T
tschw 已提交
2315

2316
	// this.setTexture2D = setTexture2D;
M
Mr.doob 已提交
2317
	this.setTexture2D = ( function () {
T
tschw 已提交
2318

2319
		var warned = false;
T
tschw 已提交
2320

2321
		// backwards compatibility: peel texture.texture
W
WestLangley 已提交
2322
		return function setTexture2D( texture, slot ) {
T
tschw 已提交
2323

T
Takahiro 已提交
2324
			if ( texture && texture.isWebGLRenderTarget ) {
T
tschw 已提交
2325

2326
				if ( ! warned ) {
T
tschw 已提交
2327

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

2331
				}
T
tschw 已提交
2332

2333
				texture = texture.texture;
T
tschw 已提交
2334

2335
			}
T
tschw 已提交
2336

2337
			textures.setTexture2D( texture, slot );
T
tschw 已提交
2338

2339
		};
T
tschw 已提交
2340

2341
	}() );
T
tschw 已提交
2342

M
Mr.doob 已提交
2343
	this.setTexture = ( function () {
2344 2345 2346

		var warned = false;

W
WestLangley 已提交
2347
		return function setTexture( texture, slot ) {
2348 2349 2350 2351 2352 2353 2354 2355

			if ( ! warned ) {

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

			}

2356
			textures.setTexture2D( texture, slot );
2357 2358 2359 2360 2361

		};

	}() );

M
Mr.doob 已提交
2362
	this.setTextureCube = ( function () {
2363 2364 2365

		var warned = false;

W
WestLangley 已提交
2366
		return function setTextureCube( texture, slot ) {
2367 2368

			// backwards compatibility: peel texture.texture
T
Takahiro 已提交
2369
			if ( texture && texture.isWebGLRenderTargetCube ) {
2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383

				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 已提交
2384
			if ( ( texture && texture.isCubeTexture ) ||
2385
				( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {
2386 2387 2388 2389

				// CompressedTexture can have Array in image :/

				// this function alone should take care of cube textures
2390
				textures.setTextureCube( texture, slot );
2391 2392 2393 2394 2395

			} else {

				// assumed: texture property of THREE.WebGLRenderTargetCube

2396
				textures.setTextureCubeDynamic( texture, slot );
2397 2398 2399 2400 2401 2402

			}

		};

	}() );
T
tschw 已提交
2403

2404 2405 2406 2407 2408 2409 2410 2411
	//

	this.setFramebuffer = function ( value ) {

		_framebuffer = value;

	};

2412
	this.getRenderTarget = function () {
2413 2414 2415

		return _currentRenderTarget;

M
Michael Herzog 已提交
2416
	};
2417

2418
	this.setRenderTarget = function ( renderTarget ) {
M
Mr.doob 已提交
2419

2420 2421
		_currentRenderTarget = renderTarget;

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

2424
			textures.setupRenderTarget( renderTarget );
M
Mr.doob 已提交
2425 2426 2427

		}

2428
		var framebuffer = _framebuffer;
M
Mr.doob 已提交
2429
		var isCube = false;
M
Mr.doob 已提交
2430 2431 2432

		if ( renderTarget ) {

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

M
Mr.doob 已提交
2435
			if ( renderTarget.isWebGLRenderTargetCube ) {
M
Mr.doob 已提交
2436

M
Mr.doob 已提交
2437
				framebuffer = __webglFramebuffer[ renderTarget.activeCubeFace ];
M
Mr.doob 已提交
2438
				isCube = true;
M
Mr.doob 已提交
2439 2440 2441

			} else {

M
Mr.doob 已提交
2442
				framebuffer = __webglFramebuffer;
M
Mr.doob 已提交
2443 2444 2445

			}

M
Mr.doob 已提交
2446
			_currentViewport.copy( renderTarget.viewport );
2447 2448
			_currentScissor.copy( renderTarget.scissor );
			_currentScissorTest = renderTarget.scissorTest;
2449

M
Mr.doob 已提交
2450 2451
		} else {

M
Mr.doob 已提交
2452
			_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );
2453
			_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );
2454
			_currentScissorTest = _scissorTest;
2455

M
Mr.doob 已提交
2456 2457
		}

M
Mr.doob 已提交
2458
		if ( _currentFramebuffer !== framebuffer ) {
M
Mr.doob 已提交
2459 2460 2461 2462 2463 2464

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

		}

M
Mr.doob 已提交
2465
		state.viewport( _currentViewport );
2466 2467
		state.scissor( _currentScissor );
		state.setScissorTest( _currentScissorTest );
2468

M
Mr.doob 已提交
2469 2470 2471
		if ( isCube ) {

			var textureProperties = properties.get( renderTarget.texture );
2472
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );
M
Mr.doob 已提交
2473 2474 2475

		}

M
Mr.doob 已提交
2476 2477
	};

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

0
06wj 已提交
2480
		if ( ! ( renderTarget && renderTarget.isWebGLRenderTarget ) ) {
2481

2482
			console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
G
gero3 已提交
2483
			return;
2484

G
gero3 已提交
2485
		}
2486

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

M
Mr.doob 已提交
2489
		if ( framebuffer ) {
2490

G
gero3 已提交
2491
			var restore = false;
2492

M
Mr.doob 已提交
2493
			if ( framebuffer !== _currentFramebuffer ) {
2494

M
Mr.doob 已提交
2495
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
2496

G
gero3 已提交
2497
				restore = true;
2498

G
gero3 已提交
2499
			}
2500

M
Mr.doob 已提交
2501
			try {
2502

M
Mr.doob 已提交
2503
				var texture = renderTarget.texture;
M
Mr.doob 已提交
2504 2505
				var textureFormat = texture.format;
				var textureType = texture.type;
2506

2507
				if ( textureFormat !== RGBAFormat && utils.convert( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {
2508

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

M
Mr.doob 已提交
2512
				}
2513

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

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

M
Mr.doob 已提交
2521
				}
2522

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

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

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

2529
						_gl.readPixels( x, y, width, height, utils.convert( textureFormat ), utils.convert( textureType ), buffer );
2530 2531

					}
2532

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

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

				}
M
Mr.doob 已提交
2538

M
Mr.doob 已提交
2539
			} finally {
M
Mr.doob 已提交
2540

M
Mr.doob 已提交
2541 2542 2543
				if ( restore ) {

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

M
Mr.doob 已提交
2545 2546 2547
				}

			}
M
Mr.doob 已提交
2548 2549 2550

		}

M
Mr.doob 已提交
2551 2552
	};

2553
	this.copyFramebufferToTexture = function ( position, texture, level ) {
2554 2555 2556

		var width = texture.image.width;
		var height = texture.image.height;
2557
		var glFormat = utils.convert( texture.format );
2558 2559 2560

		this.setTexture2D( texture, 0 );

2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573
		_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 );

2574 2575 2576 2577 2578 2579 2580 2581 2582
		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 );

		}
2583 2584 2585

	};

M
Mr.doob 已提交
2586
}
R
Rich Harris 已提交
2587

T
Tristan VALCKE 已提交
2588

2589
export { WebGLRenderer };