WebGLRenderer.js 58.9 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 680 681
		var frontFaceCW = ( object.isMesh && object.matrixWorld.determinant() < 0 );

		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

M
Mr.doob 已提交
1023
	function onAnimationFrame() {
1024

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

1028
	}
1029

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

1034
	this.setAnimationLoop = function ( callback ) {
1035

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

1039 1040
		animation.start();

1041 1042
	};

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

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

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

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

		}

1054 1055
		if ( _isContextLost ) return;

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

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

		// update scene graph

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

		// update camera matrices and frustum

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

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

			camera = vr.getCamera( camera );

		}

1076 1077
		//

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

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

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

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

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

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

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

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

1098 1099
		}

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

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

1104
		var shadowsArray = currentRenderState.state.shadowsArray;
1105

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

1108
		currentRenderState.setupLights( camera );
1109

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

M
Mr.doob 已提交
1112 1113
		//

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

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

			renderTarget = null;

		}

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

M
Mr.doob 已提交
1124 1125
		//

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

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

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

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

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

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

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

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

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

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

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

		}

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

1154
		var spritesArray = currentRenderState.state.spritesArray;
1155

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

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

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

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

		}

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

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

1172
		state.setPolygonOffset( false );
1173

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

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

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

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

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

1184
		currentRenderList = null;
1185
		currentRenderState = null;
1186

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

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

1192 1193
	var _sphere = new Sphere();

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

		var geometry = object.geometry;

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

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

		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 已提交
1219 1220

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

		var numPlanes = _clipping.numPlanes;

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

		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 已提交
1237
		} while ( ++ i !== numPlanes );
T
tschw 已提交
1238 1239 1240 1241

		return true;

	}
1242
	*/
T
tschw 已提交
1243

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

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

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

1250
		if ( visible ) {
1251

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

1254
				currentRenderState.pushLight( object );
1255 1256 1257

				if ( object.castShadow ) {

1258
					currentRenderState.pushShadow( object );
1259 1260

				}
M
Mr.doob 已提交
1261

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

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

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

1268
				}
M
Mr.doob 已提交
1269

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

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

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

1277
				}
M
Mr.doob 已提交
1278

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

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

1283
				if ( object.isSkinnedMesh ) {
1284

1285
					object.skeleton.update();
1286

1287
				}
1288

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

1291 1292 1293 1294 1295 1296
					if ( sortObjects ) {

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

					}
1297

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

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

1303
						var groups = geometry.groups;
1304

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

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

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

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

							}
M
Mr.doob 已提交
1315

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

1318
					} else if ( material.visible ) {
1319

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

1322
					}
M
Mr.doob 已提交
1323

1324
				}
M
Mr.doob 已提交
1325

1326
			}
M
Mr.doob 已提交
1327

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

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

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

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

1336
		}
1337

1338
	}
M
Mr.doob 已提交
1339

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

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

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

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

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

1353 1354
				_currentArrayCamera = camera;

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

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

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

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

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

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

						} else {

							var bounds = camera2.bounds;
1370

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

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

						}
1379 1380 1381 1382

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

					}
M
Mr.doob 已提交
1383

M
Mr.doob 已提交
1384
				}
1385

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

1388 1389
				_currentArrayCamera = null;

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

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

1394
		}
M
Mr.doob 已提交
1395

1396
	}
G
gero3 已提交
1397

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

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

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

		if ( object.isImmediateRenderObject ) {

1408 1409 1410
			var frontFaceCW = ( object.isMesh && object.matrixWorld.determinant() < 0 );

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

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

			_currentGeometryProgram = '';

			renderObjectImmediate( object, program, material );

		} else {

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

		}

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

M
Mr.doob 已提交
1427 1428
	}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		}

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

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

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

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

1484
			} else {
B
Ben Adams 已提交
1485

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

1493
			}
G
gero3 已提交
1494

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

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

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

		}

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

		if ( material.morphTargets ) {

			material.numSupportedMorphTargets = 0;

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

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

					material.numSupportedMorphTargets ++;

				}

			}

		}

		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

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

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

					material.numSupportedMorphNormals ++;

				}

			}

		}

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

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

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

		}

1550
		materialProperties.fog = fog;
1551

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

1554
		materialProperties.lightsHash = lights.state.hash;
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

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

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

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

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

			}

		}

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

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

1615
				material.needsUpdate = true;
1616

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

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

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

1623
				material.needsUpdate = true;
1624

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

				material.needsUpdate = true;

1631
			}
1632 1633 1634 1635

		}

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

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

		}

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

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

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

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

		}

		if ( material.id !== _currentMaterialId ) {

			_currentMaterialId = material.id;
1661

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

		}

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

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

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

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

			}

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

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

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

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

			}
M
Mr.doob 已提交
1691

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

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

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

				if ( uCamPos !== undefined ) {
1703

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

				}

			}

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

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

			}

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

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

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

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

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

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

1737 1738
				var bones = skeleton.bones;

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

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

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

					}

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

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

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

				}

			}

		}

		if ( refreshMaterial ) {

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

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

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

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

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

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

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

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

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

			}

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

				refreshUniformsCommon( m_uniforms, material );

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

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

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

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

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

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

1825
				} else {
1826

1827
					refreshUniformsPhong( m_uniforms, material );
1828

1829
				}
T
Takahiro 已提交
1830

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

1833
				refreshUniformsCommon( m_uniforms, material );
1834

1835
				if ( material.isMeshPhysicalMaterial ) {
1836

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

1839
				} else {
W
WestLangley 已提交
1840

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

1843
				}
W
WestLangley 已提交
1844

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

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

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

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

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

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

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

				refreshUniformsLine( m_uniforms, material );

				if ( material.isLineDashedMaterial ) {

					refreshUniformsDash( m_uniforms, material );

				}

			} else if ( material.isPointsMaterial ) {

				refreshUniformsPoints( m_uniforms, material );

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

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

M
Mr.doob 已提交
1879 1880
			}

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

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

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

		}

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

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

		}
M
Mr.doob 已提交
1897

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

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

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

	}

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

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

		uniforms.opacity.value = material.opacity;

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

			uniforms.diffuse.value = material.color;

		}
M
Mr.doob 已提交
1919

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

1922
			uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );
M
Mr.doob 已提交
1923 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
		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;

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

1959
		}
M
Mr.doob 已提交
1960

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

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

		}

1968
		if ( material.aoMap ) {
1969

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

		}

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

		var uvScaleMap;

		if ( material.map ) {

			uvScaleMap = material.map;

		} else if ( material.specularMap ) {

			uvScaleMap = material.specularMap;

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

			uvScaleMap = material.displacementMap;

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

			uvScaleMap = material.normalMap;

		} else if ( material.bumpMap ) {

			uvScaleMap = material.bumpMap;

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

			uvScaleMap = material.roughnessMap;

		} else if ( material.metalnessMap ) {

			uvScaleMap = material.metalnessMap;

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

			uvScaleMap = material.alphaMap;

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

			uvScaleMap = material.emissiveMap;

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

		if ( uvScaleMap !== undefined ) {

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

				uvScaleMap = uvScaleMap.texture;

			}

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

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

W
WestLangley 已提交
2036
			}
2037

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

		}

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

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

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

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

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

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

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

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

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

		uniforms.map.value = material.map;

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

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

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

			}
2075

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

		}

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

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

		uniforms.fogColor.value = fog.color;

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

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

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

			uniforms.fogDensity.value = fog.density;

		}

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

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

		if ( material.emissiveMap ) {

			uniforms.emissiveMap.value = material.emissiveMap;

		}

	}

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

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

2114
		if ( material.emissiveMap ) {
2115

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

2118
		}
M
Mr.doob 已提交
2119

2120 2121 2122 2123
		if ( material.bumpMap ) {

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

2126
		}
M
Mr.doob 已提交
2127

2128 2129 2130 2131
		if ( material.normalMap ) {

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

		}
M
Mr.doob 已提交
2135

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

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

2142
		}
2143

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

	function refreshUniformsToon( uniforms, material ) {

		refreshUniformsPhong( uniforms, material );

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

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

		}

2156 2157
	}

M
Mr.doob 已提交
2158
	function refreshUniformsStandard( uniforms, material ) {
W
WestLangley 已提交
2159 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

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

		}

		if ( material.normalMap ) {

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

		}

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

2216 2217 2218
		uniforms.clearCoat.value = material.clearCoat;
		uniforms.clearCoatRoughness.value = material.clearCoatRoughness;

W
WestLangley 已提交
2219 2220 2221 2222
		refreshUniformsStandard( uniforms, material );

	}

W
WestLangley 已提交
2223 2224 2225 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
	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;

	}

2251 2252 2253 2254 2255 2256
	function refreshUniformsNormal( uniforms, material ) {

		if ( material.bumpMap ) {

			uniforms.bumpMap.value = material.bumpMap;
			uniforms.bumpScale.value = material.bumpScale;
2257
			if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1;
2258 2259 2260 2261 2262 2263 2264

		}

		if ( material.normalMap ) {

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

		}

		if ( material.displacementMap ) {

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

		}

	}

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

M
Mr.doob 已提交
2281
	function markUniformsLightsNeedsUpdate( uniforms, value ) {
2282

M
Mr.doob 已提交
2283
		uniforms.ambientLightColor.needsUpdate = value;
2284

B
Ben Houston 已提交
2285 2286 2287
		uniforms.directionalLights.needsUpdate = value;
		uniforms.pointLights.needsUpdate = value;
		uniforms.spotLights.needsUpdate = value;
2288
		uniforms.rectAreaLights.needsUpdate = value;
B
Ben Houston 已提交
2289
		uniforms.hemisphereLights.needsUpdate = value;
2290

M
Mr.doob 已提交
2291
	}
2292

M
Mr.doob 已提交
2293 2294
	// Textures

T
tschw 已提交
2295 2296 2297 2298 2299 2300
	function allocTextureUnit() {

		var textureUnit = _usedTextureUnits;

		if ( textureUnit >= capabilities.maxTextures ) {

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

		}

		_usedTextureUnits += 1;

		return textureUnit;

	}

2311
	this.allocTextureUnit = allocTextureUnit;
T
tschw 已提交
2312

2313
	// this.setTexture2D = setTexture2D;
M
Mr.doob 已提交
2314
	this.setTexture2D = ( function () {
T
tschw 已提交
2315

2316
		var warned = false;
T
tschw 已提交
2317

2318
		// backwards compatibility: peel texture.texture
W
WestLangley 已提交
2319
		return function setTexture2D( texture, slot ) {
T
tschw 已提交
2320

T
Takahiro 已提交
2321
			if ( texture && texture.isWebGLRenderTarget ) {
T
tschw 已提交
2322

2323
				if ( ! warned ) {
T
tschw 已提交
2324

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

2328
				}
T
tschw 已提交
2329

2330
				texture = texture.texture;
T
tschw 已提交
2331

2332
			}
T
tschw 已提交
2333

2334
			textures.setTexture2D( texture, slot );
T
tschw 已提交
2335

2336
		};
T
tschw 已提交
2337

2338
	}() );
T
tschw 已提交
2339

M
Mr.doob 已提交
2340
	this.setTexture = ( function () {
2341 2342 2343

		var warned = false;

W
WestLangley 已提交
2344
		return function setTexture( texture, slot ) {
2345 2346 2347 2348 2349 2350 2351 2352

			if ( ! warned ) {

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

			}

2353
			textures.setTexture2D( texture, slot );
2354 2355 2356 2357 2358

		};

	}() );

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

		var warned = false;

W
WestLangley 已提交
2363
		return function setTextureCube( texture, slot ) {
2364 2365

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

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

				// CompressedTexture can have Array in image :/

				// this function alone should take care of cube textures
2387
				textures.setTextureCube( texture, slot );
2388 2389 2390 2391 2392

			} else {

				// assumed: texture property of THREE.WebGLRenderTargetCube

2393
				textures.setTextureCubeDynamic( texture, slot );
2394 2395 2396 2397 2398 2399

			}

		};

	}() );
T
tschw 已提交
2400

2401 2402 2403 2404 2405 2406 2407 2408
	//

	this.setFramebuffer = function ( value ) {

		_framebuffer = value;

	};

2409
	this.getRenderTarget = function () {
2410 2411 2412

		return _currentRenderTarget;

M
Michael Herzog 已提交
2413
	};
2414

2415
	this.setRenderTarget = function ( renderTarget ) {
M
Mr.doob 已提交
2416

2417 2418
		_currentRenderTarget = renderTarget;

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

2421
			textures.setupRenderTarget( renderTarget );
M
Mr.doob 已提交
2422 2423 2424

		}

2425
		var framebuffer = _framebuffer;
M
Mr.doob 已提交
2426
		var isCube = false;
M
Mr.doob 已提交
2427 2428 2429

		if ( renderTarget ) {

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

M
Mr.doob 已提交
2432
			if ( renderTarget.isWebGLRenderTargetCube ) {
M
Mr.doob 已提交
2433

M
Mr.doob 已提交
2434
				framebuffer = __webglFramebuffer[ renderTarget.activeCubeFace ];
M
Mr.doob 已提交
2435
				isCube = true;
M
Mr.doob 已提交
2436 2437 2438

			} else {

M
Mr.doob 已提交
2439
				framebuffer = __webglFramebuffer;
M
Mr.doob 已提交
2440 2441 2442

			}

M
Mr.doob 已提交
2443
			_currentViewport.copy( renderTarget.viewport );
2444 2445
			_currentScissor.copy( renderTarget.scissor );
			_currentScissorTest = renderTarget.scissorTest;
2446

M
Mr.doob 已提交
2447 2448
		} else {

M
Mr.doob 已提交
2449
			_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );
2450
			_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );
2451
			_currentScissorTest = _scissorTest;
2452

M
Mr.doob 已提交
2453 2454
		}

M
Mr.doob 已提交
2455
		if ( _currentFramebuffer !== framebuffer ) {
M
Mr.doob 已提交
2456 2457 2458 2459 2460 2461

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

		}

M
Mr.doob 已提交
2462
		state.viewport( _currentViewport );
2463 2464
		state.scissor( _currentScissor );
		state.setScissorTest( _currentScissorTest );
2465

M
Mr.doob 已提交
2466 2467 2468
		if ( isCube ) {

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

		}

M
Mr.doob 已提交
2473 2474
	};

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

0
06wj 已提交
2477
		if ( ! ( renderTarget && renderTarget.isWebGLRenderTarget ) ) {
2478

2479
			console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
G
gero3 已提交
2480
			return;
2481

G
gero3 已提交
2482
		}
2483

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

M
Mr.doob 已提交
2486
		if ( framebuffer ) {
2487

G
gero3 已提交
2488
			var restore = false;
2489

M
Mr.doob 已提交
2490
			if ( framebuffer !== _currentFramebuffer ) {
2491

M
Mr.doob 已提交
2492
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
2493

G
gero3 已提交
2494
				restore = true;
2495

G
gero3 已提交
2496
			}
2497

M
Mr.doob 已提交
2498
			try {
2499

M
Mr.doob 已提交
2500
				var texture = renderTarget.texture;
M
Mr.doob 已提交
2501 2502
				var textureFormat = texture.format;
				var textureType = texture.type;
2503

2504
				if ( textureFormat !== RGBAFormat && utils.convert( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {
2505

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

M
Mr.doob 已提交
2509
				}
2510

2511
				if ( textureType !== UnsignedByteType && utils.convert( textureType ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE ) && // IE11, Edge and Chrome Mac < 52 (#9513)
2512 2513
					! ( 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' ) ) ) {
2514

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

M
Mr.doob 已提交
2518
				}
2519

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

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

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

2526
						_gl.readPixels( x, y, width, height, utils.convert( textureFormat ), utils.convert( textureType ), buffer );
2527 2528

					}
2529

M
Mr.doob 已提交
2530
				} else {
M
Mr.doob 已提交
2531

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

				}
M
Mr.doob 已提交
2535

M
Mr.doob 已提交
2536
			} finally {
M
Mr.doob 已提交
2537

M
Mr.doob 已提交
2538 2539 2540
				if ( restore ) {

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

M
Mr.doob 已提交
2542 2543 2544
				}

			}
M
Mr.doob 已提交
2545 2546 2547

		}

M
Mr.doob 已提交
2548 2549
	};

2550
	this.copyFramebufferToTexture = function ( position, texture, level ) {
2551 2552 2553

		var width = texture.image.width;
		var height = texture.image.height;
2554
		var glFormat = utils.convert( texture.format );
2555 2556 2557

		this.setTexture2D( texture, 0 );

2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570
		_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 );

2571 2572 2573 2574 2575 2576 2577 2578 2579
		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 );

		}
2580 2581 2582

	};

M
Mr.doob 已提交
2583
}
R
Rich Harris 已提交
2584

T
Tristan VALCKE 已提交
2585

2586
export { WebGLRenderer };