WebGLRenderer.js 58.8 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 128 129
		_currentRenderTarget = null,
		_currentFramebuffer = null,
		_currentMaterialId = - 1,
		_currentGeometryProgram = '',
130

131
		_currentCamera = null,
132
		_currentArrayCamera = null,
M
Mr.doob 已提交
133

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

138
		//
139

140
		_usedTextureUnits = 0,
M
Mr.doob 已提交
141

142
		//
M
Mr.doob 已提交
143

144 145
		_width = _canvas.width,
		_height = _canvas.height,
M
Mr.doob 已提交
146

147
		_pixelRatio = 1,
M
Mr.doob 已提交
148

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

153
		// frustum
M
Mr.doob 已提交
154

155
		_frustum = new Frustum(),
M
Mr.doob 已提交
156

157
		// clipping
T
tschw 已提交
158

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

163
		// camera matrices cache
M
Mr.doob 已提交
164

165
		_projScreenMatrix = new Matrix4(),
M
Mr.doob 已提交
166

M
Mugen87 已提交
167
		_vector3 = new Vector3();
A
Atrahasis 已提交
168

169 170 171 172 173
	function getTargetPixelRatio() {

		return _currentRenderTarget === null ? _pixelRatio : 1;

	}
174

M
Mr.doob 已提交
175 176 177 178
	// initialize

	var _gl;

M
Mr.doob 已提交
179 180
	try {

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

191 192
		// event listeners must be registered before WebGL context is created, see #12753

193
		_canvas.addEventListener( 'webglcontextlost', onContextLost, false );
194
		_canvas.addEventListener( 'webglcontextrestored', onContextRestore, false );
195

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

		if ( _gl === null ) {

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

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

			} else {

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

			}
M
Mr.doob 已提交
209 210 211

		}

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

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

	}

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

234
	var background, morphtargets, bufferRenderer, indexedBufferRenderer;
M
Mugen87 已提交
235
	var spriteRenderer;
236

237
	var utils;
238

239
	function initGLContext() {
240

241 242 243 244 245 246 247
		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 已提交
248
		extensions.get( 'OES_element_index_uint' );
249
		extensions.get( 'ANGLE_instanced_arrays' );
250

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

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

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

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

270
		background = new WebGLBackground( _this, state, objects, _premultipliedAlpha );
271

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

275
		spriteRenderer = new WebGLSpriteRenderer( _this, _gl, state, textures, capabilities );
276

M
Mugen87 已提交
277
		info.programs = programCache.programs;
278

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

287
	}
M
Mr.doob 已提交
288

289
	initGLContext();
M
Mr.doob 已提交
290

291
	// vr
M
Mr.doob 已提交
292

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

295
	this.vr = vr;
M
Mr.doob 已提交
296 297

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

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

301
	this.shadowMap = shadowMap;
M
Mr.doob 已提交
302

M
Mr.doob 已提交
303 304 305 306 307 308 309 310
	// API

	this.getContext = function () {

		return _gl;

	};

311 312 313 314 315 316
	this.getContextAttributes = function () {

		return _gl.getContextAttributes();

	};

317 318
	this.forceContextLoss = function () {

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

	};

324
	this.forceContextRestore = function () {
M
Mr.doob 已提交
325

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

	};

331 332
	this.getPixelRatio = function () {

333
		return _pixelRatio;
334 335 336 337 338

	};

	this.setPixelRatio = function ( value ) {

339 340 341 342
		if ( value === undefined ) return;

		_pixelRatio = value;

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

	};

347 348 349
	this.getSize = function () {

		return {
350 351
			width: _width,
			height: _height
352 353 354 355
		};

	};

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

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

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

		}

365 366 367
		_width = width;
		_height = height;

368 369
		_canvas.width = width * _pixelRatio;
		_canvas.height = height * _pixelRatio;
370

371
		if ( updateStyle !== false ) {
372

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

G
gero3 已提交
376
		}
M
Mr.doob 已提交
377

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

	};

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

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

	};

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

	};

405
	this.getCurrentViewport = function () {
M
Mugen87 已提交
406

407
		return _currentViewport;
M
Mugen87 已提交
408 409 410

	};

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

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

M
Mr.doob 已提交
416 417
	};

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

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

M
Mr.doob 已提交
423 424
	};

425 426
	this.setScissorTest = function ( boolean ) {

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

	};

	// Clearing

M
Mr.doob 已提交
433
	this.getClearColor = function () {
M
Mr.doob 已提交
434

435
		return background.getClearColor();
M
Mr.doob 已提交
436 437 438

	};

439
	this.setClearColor = function () {
440

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

	};

M
Mr.doob 已提交
445
	this.getClearAlpha = function () {
M
Mr.doob 已提交
446

447
		return background.getClearAlpha();
M
Mr.doob 已提交
448 449 450

	};

M
Mugen87 已提交
451
	this.setClearAlpha = function () {
M
Mr.doob 已提交
452

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

	};

	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 );
466 467 468 469 470

	};

	this.clearColor = function () {

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

	};

	this.clearDepth = function () {

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

	};

	this.clearStencil = function () {

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

	};

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

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

	};

M
Mr.doob 已提交
494
	//
M
Mr.doob 已提交
495

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

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

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

506
		vr.dispose();
507

508
		animation.stop();
B
brunnerh 已提交
509

D
dubejf 已提交
510 511
	};

M
Mr.doob 已提交
512
	// Events
M
Mr.doob 已提交
513

D
dubejf 已提交
514 515 516 517
	function onContextLost( event ) {

		event.preventDefault();

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

520 521 522 523
		_isContextLost = true;

	}

M
Mugen87 已提交
524
	function onContextRestore( /* event */ ) {
D
dubejf 已提交
525

526
		console.log( 'THREE.WebGLRenderer: Context Restored.' );
527 528

		_isContextLost = false;
D
dubejf 已提交
529

530
		initGLContext();
D
dubejf 已提交
531

M
Mr.doob 已提交
532
	}
D
dubejf 已提交
533

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

		var material = event.target;

		material.removeEventListener( 'dispose', onMaterialDispose );

		deallocateMaterial( material );

542
	}
M
Mr.doob 已提交
543 544 545

	// Buffer deallocation

546
	function deallocateMaterial( material ) {
M
Mr.doob 已提交
547

548 549
		releaseMaterialProgramReference( material );

550
		properties.remove( material );
551

552
	}
553 554


555
	function releaseMaterialProgramReference( material ) {
556

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

		material.program = undefined;

561
		if ( programInfo !== undefined ) {
M
Mr.doob 已提交
562

563
			programCache.releaseProgram( programInfo );
M
Mr.doob 已提交
564

M
Mr.doob 已提交
565 566
		}

567
	}
M
Mr.doob 已提交
568 569 570

	// Buffer rendering

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

		object.render( function ( object ) {

			_this.renderBufferImmediate( object, program, material );

		} );

	}

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

583
		state.initAttributes();
584

585
		var buffers = properties.get( object );
586

587 588 589 590
		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 已提交
591

592
		var programAttributes = program.getAttributes();
593

M
Mr.doob 已提交
594 595
		if ( object.hasPositions ) {

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

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

		}

		if ( object.hasNormals ) {

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

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

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

615
					var array = object.normalArray;
M
Mr.doob 已提交
616

617 618 619
					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 已提交
620

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

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

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

				}

			}

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

639
			state.enableAttribute( programAttributes.normal );
640

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

		}

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

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

650
			state.enableAttribute( programAttributes.uv );
651

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

		}

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

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

661
			state.enableAttribute( programAttributes.color );
662

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

		}

667
		state.disableUnusedAttributes();
668

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

		object.count = 0;

	};

675
	this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {
676

677 678 679
		var frontFaceCW = ( object.isMesh && object.matrixWorld.determinant() < 0 );

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

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

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

		if ( geometryProgram !== _currentGeometryProgram ) {

			_currentGeometryProgram = geometryProgram;
			updateBuffers = true;

		}

693
		if ( object.morphTargetInfluences ) {
694

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

			updateBuffers = true;

		}

701 702
		//

703
		var index = geometry.index;
704
		var position = geometry.attributes.position;
705
		var rangeFactor = 1;
706

707 708
		if ( material.wireframe === true ) {

709
			index = geometries.getWireframeAttribute( geometry );
710
			rangeFactor = 2;
711 712 713

		}

M
Mr.doob 已提交
714
		var attribute;
M
Mr.doob 已提交
715
		var renderer = bufferRenderer;
716

717
		if ( index !== null ) {
718

M
Mr.doob 已提交
719
			attribute = attributes.get( index );
720

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

724
		}
M
Mr.doob 已提交
725

726
		if ( updateBuffers ) {
M
Mr.doob 已提交
727

728
			setupVertexAttributes( material, program, geometry );
M
Mr.doob 已提交
729

730
			if ( index !== null ) {
731

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

			}

736
		}
737

738 739
		//

740
		var dataCount = Infinity;
741

M
Mr.doob 已提交
742
		if ( index !== null ) {
743

M
Mr.doob 已提交
744
			dataCount = index.count;
745

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

M
Mr.doob 已提交
748
			dataCount = position.count;
749

M
Mr.doob 已提交
750
		}
751

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

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

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

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

763 764
		if ( drawCount === 0 ) return;

M
Mr.doob 已提交
765
		//
766

767
		if ( object.isMesh ) {
768

769
			if ( material.wireframe === true ) {
770

771
				state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );
772
				renderer.setMode( _gl.LINES );
773

774
			} else {
M
Mr.doob 已提交
775 776

				switch ( object.drawMode ) {
777

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

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

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

				}
791

792
			}
793

794

795
		} else if ( object.isLine ) {
796

797
			var lineWidth = material.linewidth;
798

799
			if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material
800

801
			state.setLineWidth( lineWidth * getTargetPixelRatio() );
802

803
			if ( object.isLineSegments ) {
804

805
				renderer.setMode( _gl.LINES );
806

807 808 809 810
			} else if ( object.isLineLoop ) {

				renderer.setMode( _gl.LINE_LOOP );

811
			} else {
812

813
				renderer.setMode( _gl.LINE_STRIP );
814 815

			}
M
Mr.doob 已提交
816

817
		} else if ( object.isPoints ) {
818 819

			renderer.setMode( _gl.POINTS );
820 821

		}
822

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

			if ( geometry.maxInstancedCount > 0 ) {

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

J
jfranc 已提交
829
			}
830 831 832

		} else {

M
Mr.doob 已提交
833
			renderer.render( drawStart, drawCount );
834

M
Mr.doob 已提交
835 836 837 838
		}

	};

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

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

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

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

M
Mr.doob 已提交
848 849 850
			}

		}
B
Ben Adams 已提交
851

852 853
		state.initAttributes();

854
		var geometryAttributes = geometry.attributes;
855

856
		var programAttributes = program.getAttributes();
857

858
		var materialDefaultAttributeValues = material.defaultAttributeValues;
859

860
		for ( var name in programAttributes ) {
861

862
			var programAttribute = programAttributes[ name ];
M
Mr.doob 已提交
863

M
Mr.doob 已提交
864
			if ( programAttribute >= 0 ) {
M
Mr.doob 已提交
865

866
				var geometryAttribute = geometryAttributes[ name ];
867

M
Mr.doob 已提交
868
				if ( geometryAttribute !== undefined ) {
M
Mr.doob 已提交
869

870
					var normalized = geometryAttribute.normalized;
871
					var size = geometryAttribute.itemSize;
872

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

875 876 877 878
					// TODO Attribute may not be available on context restore

					if ( attribute === undefined ) continue;

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

A
aardgoose 已提交
883
					if ( geometryAttribute.isInterleavedBufferAttribute ) {
884

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

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

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

M
Mr.doob 已提交
893
							if ( geometry.maxInstancedCount === undefined ) {
894

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

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

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

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

M
Mr.doob 已提交
903
						}
B
Ben Adams 已提交
904

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

M
Mr.doob 已提交
908
					} else {
B
Ben Adams 已提交
909

A
aardgoose 已提交
910
						if ( geometryAttribute.isInstancedBufferAttribute ) {
B
Ben Adams 已提交
911

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

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

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

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

M
Mr.doob 已提交
920 921 922 923
						} else {

							state.enableAttribute( programAttribute );

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

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

B
Ben Adams 已提交
929
					}
M
Mr.doob 已提交
930

931 932
				} else if ( materialDefaultAttributeValues !== undefined ) {

T
tschw 已提交
933
					var value = materialDefaultAttributeValues[ name ];
934

935
					if ( value !== undefined ) {
M
Mr.doob 已提交
936

937
						switch ( value.length ) {
M
Mr.doob 已提交
938

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

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

947 948 949
							case 4:
								_gl.vertexAttrib4fv( programAttribute, value );
								break;
950

951 952
							default:
								_gl.vertexAttrib1fv( programAttribute, value );
953 954

						}
M
Mr.doob 已提交
955 956 957 958 959 960 961 962

					}

				}

			}

		}
963

964
		state.disableUnusedAttributes();
965

M
Mr.doob 已提交
966 967
	}

M
Mr.doob 已提交
968
	// Compile
M
Mr.doob 已提交
969

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

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

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

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

979
				currentRenderState.pushLight( object );
980 981 982

				if ( object.castShadow ) {

983
					currentRenderState.pushShadow( object );
984 985

				}
M
Mr.doob 已提交
986

G
gero3 已提交
987
			}
M
Mr.doob 已提交
988 989 990

		} );

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

		scene.traverse( function ( object ) {

			if ( object.material ) {

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

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

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

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

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

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

G
gero3 已提交
1009
				}
M
Mr.doob 已提交
1010

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

		} );
G
gero3 已提交
1014 1015

	};
1016

1017
	// Animation Loop
M
Mr.doob 已提交
1018

M
Mr.doob 已提交
1019
	var onAnimationFrameCallback = null;
1020

M
Mr.doob 已提交
1021
	function onAnimationFrame() {
1022

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

1026
	}
1027

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

1032
	this.setAnimationLoop = function ( callback ) {
1033

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

1037 1038
		animation.start();

1039 1040
	};

M
Mr.doob 已提交
1041 1042 1043
	// Rendering

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

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

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

		}

1052 1053
		if ( _isContextLost ) return;

M
Mr.doob 已提交
1054 1055
		// reset caching for this frame

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

		// update scene graph

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

		// update camera matrices and frustum

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

1068 1069 1070 1071 1072 1073
		if ( vr.enabled ) {

			camera = vr.getCamera( camera );

		}

1074 1075
		//

1076 1077
		currentRenderState = renderStates.get( scene, camera );
		currentRenderState.init();
1078

1079 1080
		scene.onBeforeRender( _this, scene, camera, renderTarget );

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

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

1087 1088 1089
		currentRenderList = renderLists.get( scene, camera );
		currentRenderList.init();

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

M
Mr.doob 已提交
1092
		if ( _this.sortObjects === true ) {
1093

1094
			currentRenderList.sort();
M
Mr.doob 已提交
1095

1096 1097
		}

M
Mr.doob 已提交
1098
		//
M
Mr.doob 已提交
1099

T
tschw 已提交
1100
		if ( _clippingEnabled ) _clipping.beginShadows();
T
tschw 已提交
1101

1102
		var shadowsArray = currentRenderState.state.shadowsArray;
1103

1104
		shadowMap.render( shadowsArray, scene, camera );
1105

1106
		currentRenderState.setupLights( camera );
1107

T
tschw 已提交
1108
		if ( _clippingEnabled ) _clipping.endShadows();
T
tschw 已提交
1109

M
Mr.doob 已提交
1110 1111
		//

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

1114 1115 1116 1117 1118 1119
		if ( renderTarget === undefined ) {

			renderTarget = null;

		}

M
Mr.doob 已提交
1120 1121
		this.setRenderTarget( renderTarget );

M
Mr.doob 已提交
1122 1123
		//

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

1126
		// render scene
M
Mr.doob 已提交
1127

1128 1129 1130
		var opaqueObjects = currentRenderList.opaque;
		var transparentObjects = currentRenderList.transparent;

M
Mr.doob 已提交
1131 1132
		if ( scene.overrideMaterial ) {

1133
			var overrideMaterial = scene.overrideMaterial;
M
Mr.doob 已提交
1134

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

M
Mr.doob 已提交
1138 1139 1140 1141
		} else {

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

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

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

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

		}

1150
		// custom renderers
M
Mr.doob 已提交
1151

1152
		var spritesArray = currentRenderState.state.spritesArray;
1153

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

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

M
Mr.doob 已提交
1158 1159
		if ( renderTarget ) {

1160
			textures.updateRenderTargetMipmap( renderTarget );
M
Mr.doob 已提交
1161 1162 1163

		}

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

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

1170
		state.setPolygonOffset( false );
1171

1172
		scene.onAfterRender( _this, scene, camera );
1173

M
Mr.doob 已提交
1174
		if ( vr.enabled ) {
1175

M
Mr.doob 已提交
1176
			vr.submitFrame();
1177

M
Mr.doob 已提交
1178
		}
M
Mr.doob 已提交
1179

M
Mr.doob 已提交
1180 1181
		// _gl.finish();

1182
		currentRenderList = null;
1183
		currentRenderState = null;
1184

M
Mr.doob 已提交
1185
	};
M
Mr.doob 已提交
1186

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

1190 1191
	var _sphere = new Sphere();

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

		var geometry = object.geometry;

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

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

		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 已提交
1217 1218

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

		var numPlanes = _clipping.numPlanes;

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

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

		return true;

	}
1240
	*/
T
tschw 已提交
1241

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

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

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

1248
		if ( visible ) {
1249

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

1252
				currentRenderState.pushLight( object );
1253 1254 1255

				if ( object.castShadow ) {

1256
					currentRenderState.pushShadow( object );
1257 1258

				}
M
Mr.doob 已提交
1259

1260
			} else if ( object.isSprite ) {
M
Mr.doob 已提交
1261

1262
				if ( ! object.frustumCulled || _frustum.intersectsSprite( object ) ) {
1263

1264
					currentRenderState.pushSprite( object );
M
Mr.doob 已提交
1265

1266
				}
M
Mr.doob 已提交
1267

1268
			} else if ( object.isImmediateRenderObject ) {
M
Mr.doob 已提交
1269

1270
				if ( sortObjects ) {
M
Mr.doob 已提交
1271

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

1275
				}
M
Mr.doob 已提交
1276

1277
				currentRenderList.push( object, null, object.material, _vector3.z, null );
1278

1279
			} else if ( object.isMesh || object.isLine || object.isPoints ) {
1280

1281
				if ( object.isSkinnedMesh ) {
1282

1283
					object.skeleton.update();
1284

1285
				}
1286

1287
				if ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) {
1288

1289 1290 1291 1292 1293 1294
					if ( sortObjects ) {

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

					}
1295

1296 1297
					var geometry = objects.update( object );
					var material = object.material;
1298

1299
					if ( Array.isArray( material ) ) {
1300

1301
						var groups = geometry.groups;
1302

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

1305 1306
							var group = groups[ i ];
							var groupMaterial = material[ group.materialIndex ];
1307

1308
							if ( groupMaterial && groupMaterial.visible ) {
1309

1310 1311 1312
								currentRenderList.push( object, geometry, groupMaterial, _vector3.z, group );

							}
M
Mr.doob 已提交
1313

M
Mr.doob 已提交
1314
						}
M
Mr.doob 已提交
1315

1316
					} else if ( material.visible ) {
1317

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

1320
					}
M
Mr.doob 已提交
1321

1322
				}
M
Mr.doob 已提交
1323

1324
			}
M
Mr.doob 已提交
1325

M
Mr.doob 已提交
1326
		}
M
Mr.doob 已提交
1327

M
Mr.doob 已提交
1328
		var children = object.children;
M
Mr.doob 已提交
1329

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

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

1334
		}
1335

1336
	}
M
Mr.doob 已提交
1337

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

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

1342
			var renderItem = renderList[ i ];
M
Mr.doob 已提交
1343

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

M
Mr.doob 已提交
1349
			if ( camera.isArrayCamera ) {
M
Mr.doob 已提交
1350

1351 1352
				_currentArrayCamera = camera;

M
Mr.doob 已提交
1353
				var cameras = camera.cameras;
M
Mr.doob 已提交
1354

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

M
Mr.doob 已提交
1357
					var camera2 = cameras[ j ];
M
Mr.doob 已提交
1358

1359
					if ( object.layers.test( camera2.layers ) ) {
1360

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

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

						} else {

							var bounds = camera2.bounds;
1368

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

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

						}
1377 1378 1379 1380

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

					}
M
Mr.doob 已提交
1381

M
Mr.doob 已提交
1382
				}
1383

M
Mr.doob 已提交
1384
			} else {
M
Mr.doob 已提交
1385

1386 1387
				_currentArrayCamera = null;

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

M
Mr.doob 已提交
1390
			}
M
Mr.doob 已提交
1391

1392
		}
M
Mr.doob 已提交
1393

1394
	}
G
gero3 已提交
1395

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

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

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

		if ( object.isImmediateRenderObject ) {

1406 1407 1408
			var frontFaceCW = ( object.isMesh && object.matrixWorld.determinant() < 0 );

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

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

			_currentGeometryProgram = '';

			renderObjectImmediate( object, program, material );

		} else {

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

		}

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

M
Mr.doob 已提交
1425 1426
	}

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

1429
		var materialProperties = properties.get( material );
G
gero3 已提交
1430

1431 1432
		var lights = currentRenderState.state.lights;
		var shadowsArray = currentRenderState.state.shadowsArray;
1433

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

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

1439
		var program = materialProperties.program;
T
tschw 已提交
1440
		var programChange = true;
1441

1442
		if ( program === undefined ) {
B
Ben Adams 已提交
1443

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

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

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

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

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

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

T
tschw 已提交
1459
			// same glsl and uniform list
T
tschw 已提交
1460 1461
			return;

T
tschw 已提交
1462
		} else {
B
Ben Adams 已提交
1463

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

		}

1469
		if ( programChange ) {
B
Ben Adams 已提交
1470

1471
			if ( parameters.shaderID ) {
B
Ben Adams 已提交
1472

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

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

1482
			} else {
B
Ben Adams 已提交
1483

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

1491
			}
G
gero3 已提交
1492

1493
			material.onBeforeCompile( materialProperties.shader, _this );
G
gero3 已提交
1494

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

1497 1498
			materialProperties.program = program;
			material.program = program;
1499 1500 1501

		}

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

		if ( material.morphTargets ) {

			material.numSupportedMorphTargets = 0;

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

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

					material.numSupportedMorphTargets ++;

				}

			}

		}

		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

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

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

					material.numSupportedMorphNormals ++;

				}

			}

		}

1536
		var uniforms = materialProperties.shader.uniforms;
T
tschw 已提交
1537

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

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

		}

1548
		materialProperties.fog = fog;
1549

1550
		// store the light setup it was created for
1551

1552
		materialProperties.lightsHash = lights.state.hash;
1553

M
Mr.doob 已提交
1554
		if ( material.lights ) {
1555 1556 1557

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

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

1573 1574
		}

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

T
tschw 已提交
1579
		materialProperties.uniformsList = uniformsList;
A
arose 已提交
1580

M
Mr.doob 已提交
1581
	}
M
Mr.doob 已提交
1582

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

		_usedTextureUnits = 0;

1587
		var materialProperties = properties.get( material );
1588
		var lights = currentRenderState.state.lights;
1589

T
tschw 已提交
1590 1591 1592 1593 1594
		if ( _clippingEnabled ) {

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

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

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

			}

		}

1609
		if ( material.needsUpdate === false ) {
1610

1611
			if ( materialProperties.program === undefined ) {
1612

1613
				material.needsUpdate = true;
1614

1615
			} else if ( material.fog && materialProperties.fog !== fog ) {
1616

M
Mr.doob 已提交
1617
				material.needsUpdate = true;
1618

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

1621
				material.needsUpdate = true;
1622

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

				material.needsUpdate = true;

1629
			}
1630 1631 1632 1633

		}

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

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

		}

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

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

1648
		if ( state.useProgram( program.program ) ) {
M
Mr.doob 已提交
1649

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

		}

		if ( material.id !== _currentMaterialId ) {

			_currentMaterialId = material.id;
1659

M
Mr.doob 已提交
1660 1661 1662 1663
			refreshMaterial = true;

		}

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

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

G
gero3 已提交
1668
			if ( capabilities.logarithmicDepthBuffer ) {
1669

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

			}

1675
			// Avoid unneeded uniform updates per ArrayCamera's sub-camera
1676

1677
			if ( _currentCamera !== ( _currentArrayCamera || camera ) ) {
1678

1679
				_currentCamera = ( _currentArrayCamera || camera );
1680 1681 1682 1683 1684 1685

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

			}
M
Mr.doob 已提交
1689

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

1693
			if ( material.isShaderMaterial ||
1694 1695 1696
				material.isMeshPhongMaterial ||
				material.isMeshStandardMaterial ||
				material.envMap ) {
1697

T
tschw 已提交
1698 1699 1700
				var uCamPos = p_uniforms.map.cameraPosition;

				if ( uCamPos !== undefined ) {
1701

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

				}

			}

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

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

			}

M
Mr.doob 已提交
1720 1721 1722 1723 1724 1725
		}

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

1726
		if ( material.skinning ) {
M
Mr.doob 已提交
1727

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

T
tschw 已提交
1731
			var skeleton = object.skeleton;
1732

T
tschw 已提交
1733
			if ( skeleton ) {
1734

1735 1736
				var bones = skeleton.bones;

1737
				if ( capabilities.floatVertexTextures ) {
M
Mr.doob 已提交
1738

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

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

					}

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

T
tschw 已提交
1768
				} else {
M
Mr.doob 已提交
1769

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

				}

			}

		}

		if ( refreshMaterial ) {

1780 1781 1782
			p_uniforms.setValue( _gl, 'toneMappingExposure', _this.toneMappingExposure );
			p_uniforms.setValue( _gl, 'toneMappingWhitePoint', _this.toneMappingWhitePoint );

M
Mr.doob 已提交
1783
			if ( material.lights ) {
M
Mr.doob 已提交
1784

1785
				// the current material requires lighting info
M
Mr.doob 已提交
1786

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

T
tschw 已提交
1794
				markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
G
gero3 已提交
1795

T
tschw 已提交
1796
			}
G
gero3 已提交
1797

T
tschw 已提交
1798
			// refresh uniforms common to several materials
G
gero3 已提交
1799

T
tschw 已提交
1800
			if ( fog && material.fog ) {
G
gero3 已提交
1801

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

			}

1806
			if ( material.isMeshBasicMaterial ) {
M
Mr.doob 已提交
1807 1808 1809

				refreshUniformsCommon( m_uniforms, material );

1810
			} else if ( material.isMeshLambertMaterial ) {
M
Mr.doob 已提交
1811

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

1815
			} else if ( material.isMeshPhongMaterial ) {
M
Mr.doob 已提交
1816

1817
				refreshUniformsCommon( m_uniforms, material );
M
Mr.doob 已提交
1818

1819
				if ( material.isMeshToonMaterial ) {
M
Mr.doob 已提交
1820

1821
					refreshUniformsToon( m_uniforms, material );
M
Mr.doob 已提交
1822

1823
				} else {
1824

1825
					refreshUniformsPhong( m_uniforms, material );
1826

1827
				}
T
Takahiro 已提交
1828

1829
			} else if ( material.isMeshStandardMaterial ) {
T
Takahiro 已提交
1830

1831
				refreshUniformsCommon( m_uniforms, material );
1832

1833
				if ( material.isMeshPhysicalMaterial ) {
1834

1835
					refreshUniformsPhysical( m_uniforms, material );
W
WestLangley 已提交
1836

1837
				} else {
W
WestLangley 已提交
1838

1839
					refreshUniformsStandard( m_uniforms, material );
W
WestLangley 已提交
1840

1841
				}
W
WestLangley 已提交
1842

1843
			} else if ( material.isMeshDepthMaterial ) {
M
Mr.doob 已提交
1844

1845
				refreshUniformsCommon( m_uniforms, material );
W
WestLangley 已提交
1846
				refreshUniformsDepth( m_uniforms, material );
1847

W
WestLangley 已提交
1848
			} else if ( material.isMeshDistanceMaterial ) {
1849

1850
				refreshUniformsCommon( m_uniforms, material );
W
WestLangley 已提交
1851
				refreshUniformsDistance( m_uniforms, material );
1852

1853
			} else if ( material.isMeshNormalMaterial ) {
M
Mr.doob 已提交
1854

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

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

				refreshUniformsLine( m_uniforms, material );

				if ( material.isLineDashedMaterial ) {

					refreshUniformsDash( m_uniforms, material );

				}

			} else if ( material.isPointsMaterial ) {

				refreshUniformsPoints( m_uniforms, material );

1872 1873 1874 1875 1876
			} else if ( material.isShadowMaterial ) {

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

M
Mr.doob 已提交
1877 1878
			}

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

1882 1883
			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 已提交
1884

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

		}

1889 1890 1891 1892 1893 1894
		if ( material.isShaderMaterial && material.uniformsNeedUpdate === true ) {

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

		}
M
Mr.doob 已提交
1895

T
tschw 已提交
1896
		// common matrices
M
Mr.doob 已提交
1897

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

T
tschw 已提交
1902
		return program;
A
arose 已提交
1903 1904 1905

	}

M
Mr.doob 已提交
1906 1907
	// Uniforms (refresh uniforms objects)

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

		uniforms.opacity.value = material.opacity;

1912 1913 1914 1915 1916
		if ( material.color ) {

			uniforms.diffuse.value = material.color;

		}
M
Mr.doob 已提交
1917

1918
		if ( material.emissive ) {
M
Mr.doob 已提交
1919

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

1955
			uniforms.maxMipLevel.value = properties.get( material.envMap ).__maxMipLevel;
1956

1957
		}
M
Mr.doob 已提交
1958

1959 1960 1961 1962 1963 1964 1965
		if ( material.lightMap ) {

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

		}

1966
		if ( material.aoMap ) {
1967

1968 1969
			uniforms.aoMap.value = material.aoMap;
			uniforms.aoMapIntensity.value = material.aoMapIntensity;
1970 1971 1972

		}

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

		var uvScaleMap;

		if ( material.map ) {

			uvScaleMap = material.map;

		} else if ( material.specularMap ) {

			uvScaleMap = material.specularMap;

1991 1992 1993 1994
		} else if ( material.displacementMap ) {

			uvScaleMap = material.displacementMap;

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

			uvScaleMap = material.normalMap;

		} else if ( material.bumpMap ) {

			uvScaleMap = material.bumpMap;

2003 2004 2005 2006 2007 2008 2009 2010
		} else if ( material.roughnessMap ) {

			uvScaleMap = material.roughnessMap;

		} else if ( material.metalnessMap ) {

			uvScaleMap = material.metalnessMap;

2011 2012 2013 2014
		} else if ( material.alphaMap ) {

			uvScaleMap = material.alphaMap;

2015 2016 2017 2018
		} else if ( material.emissiveMap ) {

			uvScaleMap = material.emissiveMap;

M
Mr.doob 已提交
2019 2020 2021 2022
		}

		if ( uvScaleMap !== undefined ) {

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

				uvScaleMap = uvScaleMap.texture;

			}

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

W
WestLangley 已提交
2032
				uvScaleMap.updateMatrix();
M
Mr.doob 已提交
2033

W
WestLangley 已提交
2034
			}
2035

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

		}

M
Mr.doob 已提交
2040
	}
M
Mr.doob 已提交
2041

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

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

M
Mr.doob 已提交
2047
	}
M
Mr.doob 已提交
2048

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

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

M
Mr.doob 已提交
2055
	}
M
Mr.doob 已提交
2056

M
Mr.doob 已提交
2057
	function refreshUniformsPoints( uniforms, material ) {
M
Mr.doob 已提交
2058

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

		uniforms.map.value = material.map;

2066 2067
		if ( material.map !== null ) {

W
WestLangley 已提交
2068
			if ( material.map.matrixAutoUpdate === true ) {
2069

W
WestLangley 已提交
2070
				material.map.updateMatrix();
W
WestLangley 已提交
2071 2072

			}
2073

2074
			uniforms.uvTransform.value.copy( material.map.matrix );
2075 2076 2077

		}

M
Mr.doob 已提交
2078
	}
M
Mr.doob 已提交
2079

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

		uniforms.fogColor.value = fog.color;

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

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

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

			uniforms.fogDensity.value = fog.density;

		}

M
Mr.doob 已提交
2095
	}
M
Mr.doob 已提交
2096

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

		if ( material.emissiveMap ) {

			uniforms.emissiveMap.value = material.emissiveMap;

		}

	}

M
Mr.doob 已提交
2107
	function refreshUniformsPhong( uniforms, material ) {
M
Mr.doob 已提交
2108

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

2112
		if ( material.emissiveMap ) {
2113

2114
			uniforms.emissiveMap.value = material.emissiveMap;
2115

2116
		}
M
Mr.doob 已提交
2117

2118 2119 2120 2121
		if ( material.bumpMap ) {

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

2124
		}
M
Mr.doob 已提交
2125

2126 2127 2128 2129
		if ( material.normalMap ) {

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

		}
M
Mr.doob 已提交
2133

2134 2135 2136 2137 2138
		if ( material.displacementMap ) {

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

2140
		}
2141

T
Takahiro 已提交
2142 2143 2144 2145 2146 2147
	}

	function refreshUniformsToon( uniforms, material ) {

		refreshUniformsPhong( uniforms, material );

T
Takahiro 已提交
2148
		if ( material.gradientMap ) {
T
Takahiro 已提交
2149

T
Takahiro 已提交
2150
			uniforms.gradientMap.value = material.gradientMap;
T
Takahiro 已提交
2151 2152 2153

		}

2154 2155
	}

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

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

		}

		if ( material.normalMap ) {

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

		}

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

2214 2215 2216
		uniforms.clearCoat.value = material.clearCoat;
		uniforms.clearCoatRoughness.value = material.clearCoatRoughness;

W
WestLangley 已提交
2217 2218 2219 2220
		refreshUniformsStandard( uniforms, material );

	}

W
WestLangley 已提交
2221 2222 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
	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;

	}

2249 2250 2251 2252 2253 2254
	function refreshUniformsNormal( uniforms, material ) {

		if ( material.bumpMap ) {

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

		}

		if ( material.normalMap ) {

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

		}

		if ( material.displacementMap ) {

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

		}

	}

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

M
Mr.doob 已提交
2279
	function markUniformsLightsNeedsUpdate( uniforms, value ) {
2280

M
Mr.doob 已提交
2281
		uniforms.ambientLightColor.needsUpdate = value;
2282

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

M
Mr.doob 已提交
2289
	}
2290

M
Mr.doob 已提交
2291 2292
	// Textures

T
tschw 已提交
2293 2294 2295 2296 2297 2298
	function allocTextureUnit() {

		var textureUnit = _usedTextureUnits;

		if ( textureUnit >= capabilities.maxTextures ) {

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

		}

		_usedTextureUnits += 1;

		return textureUnit;

	}

2309
	this.allocTextureUnit = allocTextureUnit;
T
tschw 已提交
2310

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

2314
		var warned = false;
T
tschw 已提交
2315

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

T
Takahiro 已提交
2319
			if ( texture && texture.isWebGLRenderTarget ) {
T
tschw 已提交
2320

2321
				if ( ! warned ) {
T
tschw 已提交
2322

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

2326
				}
T
tschw 已提交
2327

2328
				texture = texture.texture;
T
tschw 已提交
2329

2330
			}
T
tschw 已提交
2331

2332
			textures.setTexture2D( texture, slot );
T
tschw 已提交
2333

2334
		};
T
tschw 已提交
2335

2336
	}() );
T
tschw 已提交
2337

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

		var warned = false;

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

			if ( ! warned ) {

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

			}

2351
			textures.setTexture2D( texture, slot );
2352 2353 2354 2355 2356

		};

	}() );

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

		var warned = false;

W
WestLangley 已提交
2361
		return function setTextureCube( texture, slot ) {
2362 2363

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

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

				// CompressedTexture can have Array in image :/

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

			} else {

				// assumed: texture property of THREE.WebGLRenderTargetCube

2391
				textures.setTextureCubeDynamic( texture, slot );
2392 2393 2394 2395 2396 2397

			}

		};

	}() );
T
tschw 已提交
2398

2399
	this.getRenderTarget = function () {
2400 2401 2402

		return _currentRenderTarget;

M
Michael Herzog 已提交
2403
	};
2404

2405
	this.setRenderTarget = function ( renderTarget ) {
M
Mr.doob 已提交
2406

2407 2408
		_currentRenderTarget = renderTarget;

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

2411
			textures.setupRenderTarget( renderTarget );
M
Mr.doob 已提交
2412 2413 2414

		}

M
Mr.doob 已提交
2415
		var framebuffer = null;
M
Mr.doob 已提交
2416
		var isCube = false;
M
Mr.doob 已提交
2417 2418 2419

		if ( renderTarget ) {

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

M
Mr.doob 已提交
2422
			if ( renderTarget.isWebGLRenderTargetCube ) {
M
Mr.doob 已提交
2423

M
Mr.doob 已提交
2424
				framebuffer = __webglFramebuffer[ renderTarget.activeCubeFace ];
M
Mr.doob 已提交
2425
				isCube = true;
M
Mr.doob 已提交
2426 2427 2428

			} else {

M
Mr.doob 已提交
2429
				framebuffer = __webglFramebuffer;
M
Mr.doob 已提交
2430 2431 2432

			}

M
Mr.doob 已提交
2433
			_currentViewport.copy( renderTarget.viewport );
2434 2435
			_currentScissor.copy( renderTarget.scissor );
			_currentScissorTest = renderTarget.scissorTest;
2436

M
Mr.doob 已提交
2437 2438
		} else {

M
Mr.doob 已提交
2439
			_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );
2440
			_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );
2441
			_currentScissorTest = _scissorTest;
2442

M
Mr.doob 已提交
2443 2444
		}

M
Mr.doob 已提交
2445
		if ( _currentFramebuffer !== framebuffer ) {
M
Mr.doob 已提交
2446 2447 2448 2449 2450 2451

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

		}

M
Mr.doob 已提交
2452
		state.viewport( _currentViewport );
2453 2454
		state.scissor( _currentScissor );
		state.setScissorTest( _currentScissorTest );
2455

M
Mr.doob 已提交
2456 2457 2458
		if ( isCube ) {

			var textureProperties = properties.get( renderTarget.texture );
2459
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );
M
Mr.doob 已提交
2460 2461 2462

		}

M
Mr.doob 已提交
2463 2464
	};

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

0
06wj 已提交
2467
		if ( ! ( renderTarget && renderTarget.isWebGLRenderTarget ) ) {
2468

2469
			console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
G
gero3 已提交
2470
			return;
2471

G
gero3 已提交
2472
		}
2473

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

M
Mr.doob 已提交
2476
		if ( framebuffer ) {
2477

G
gero3 已提交
2478
			var restore = false;
2479

M
Mr.doob 已提交
2480
			if ( framebuffer !== _currentFramebuffer ) {
2481

M
Mr.doob 已提交
2482
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
2483

G
gero3 已提交
2484
				restore = true;
2485

G
gero3 已提交
2486
			}
2487

M
Mr.doob 已提交
2488
			try {
2489

M
Mr.doob 已提交
2490
				var texture = renderTarget.texture;
M
Mr.doob 已提交
2491 2492
				var textureFormat = texture.format;
				var textureType = texture.type;
2493

2494
				if ( textureFormat !== RGBAFormat && utils.convert( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {
2495

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

M
Mr.doob 已提交
2499
				}
2500

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

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

M
Mr.doob 已提交
2508
				}
2509

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

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

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

2516
						_gl.readPixels( x, y, width, height, utils.convert( textureFormat ), utils.convert( textureType ), buffer );
2517 2518

					}
2519

M
Mr.doob 已提交
2520
				} else {
M
Mr.doob 已提交
2521

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

				}
M
Mr.doob 已提交
2525

M
Mr.doob 已提交
2526
			} finally {
M
Mr.doob 已提交
2527

M
Mr.doob 已提交
2528 2529 2530
				if ( restore ) {

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

M
Mr.doob 已提交
2532 2533 2534
				}

			}
M
Mr.doob 已提交
2535 2536 2537

		}

M
Mr.doob 已提交
2538 2539
	};

2540
	this.copyFramebufferToTexture = function ( position, texture, level ) {
2541 2542 2543

		var width = texture.image.width;
		var height = texture.image.height;
2544
		var glFormat = utils.convert( texture.format );
2545 2546 2547

		this.setTexture2D( texture, 0 );

2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560
		_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 );

2561 2562 2563 2564 2565 2566 2567 2568 2569
		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 );

		}
2570 2571 2572

	};

M
Mr.doob 已提交
2573
}
R
Rich Harris 已提交
2574

T
Tristan VALCKE 已提交
2575

2576
export { WebGLRenderer };