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

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

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

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

	parameters = parameters || {};

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

64 65 66 67 68
		_alpha = parameters.alpha !== undefined ? parameters.alpha : false,
		_depth = parameters.depth !== undefined ? parameters.depth : true,
		_stencil = parameters.stencil !== undefined ? parameters.stencil : true,
		_antialias = parameters.antialias !== undefined ? parameters.antialias : false,
		_premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,
69
		_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false,
70 71
		_powerPreference = parameters.powerPreference !== undefined ? parameters.powerPreference : 'default',
		_failIfMajorPerformanceCaveat = parameters.failIfMajorPerformanceCaveat !== undefined ? parameters.failIfMajorPerformanceCaveat : false;
M
Mr.doob 已提交
72

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

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

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

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

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

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

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

	// scene graph

	this.sortObjects = true;

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

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

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

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

113 114
	// physical lights

115
	this.physicallyCorrectLights = false;
116

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

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

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

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

	// internal properties

	var _this = this,

132 133
		_isContextLost = false,

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

136 137
		_framebuffer = null,

138 139 140
		_currentRenderTarget = null,
		_currentFramebuffer = null,
		_currentMaterialId = - 1,
141 142 143 144

		// geometry and program caching

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

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

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

157
		//
158

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

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

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

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

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

172
		// clipping
T
tschw 已提交
173

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

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

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

M
Mugen87 已提交
182
		_vector3 = new Vector3();
A
Atrahasis 已提交
183

184 185 186 187 188
	function getTargetPixelRatio() {

		return _currentRenderTarget === null ? _pixelRatio : 1;

	}
189

M
Mr.doob 已提交
190 191 192 193
	// initialize

	var _gl;

M
Mr.doob 已提交
194 195
	try {

196
		var contextAttributes = {
M
Mr.doob 已提交
197 198 199 200 201
			alpha: _alpha,
			depth: _depth,
			stencil: _stencil,
			antialias: _antialias,
			premultipliedAlpha: _premultipliedAlpha,
202
			preserveDrawingBuffer: _preserveDrawingBuffer,
203
			powerPreference: _powerPreference,
M
Mr.doob 已提交
204
			failIfMajorPerformanceCaveat: _failIfMajorPerformanceCaveat,
205
			xrCompatible: true
M
Mr.doob 已提交
206 207
		};

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

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

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

		if ( _gl === null ) {

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

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

			} else {

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

			}
M
Mr.doob 已提交
226 227 228

		}

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

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

	}

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

252
	var background, morphtargets, bufferRenderer, indexedBufferRenderer;
253

254
	var utils;
255

256
	function initGLContext() {
257

258
		extensions = new WebGLExtensions( _gl );
259

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

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

			extensions.get( 'WEBGL_depth_texture' );
			extensions.get( 'OES_texture_float' );
			extensions.get( 'OES_texture_half_float' );
			extensions.get( 'OES_texture_half_float_linear' );
			extensions.get( 'OES_standard_derivatives' );
			extensions.get( 'OES_element_index_uint' );
			extensions.get( 'ANGLE_instanced_arrays' );

		}

274
		extensions.get( 'OES_texture_float_linear' );
275

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

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

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

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

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

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

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

308
	}
M
Mr.doob 已提交
309

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

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

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

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

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

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

322
	this.shadowMap = shadowMap;
M
Mr.doob 已提交
323

M
Mr.doob 已提交
324 325 326 327 328 329 330 331
	// API

	this.getContext = function () {

		return _gl;

	};

332 333 334 335 336 337
	this.getContextAttributes = function () {

		return _gl.getContextAttributes();

	};

338 339
	this.forceContextLoss = function () {

M
Michael Bond 已提交
340 341
		var extension = extensions.get( 'WEBGL_lose_context' );
		if ( extension ) extension.loseContext();
342 343 344

	};

345
	this.forceContextRestore = function () {
M
Mr.doob 已提交
346

347 348
		var extension = extensions.get( 'WEBGL_lose_context' );
		if ( extension ) extension.restoreContext();
M
Mr.doob 已提交
349 350 351

	};

352 353
	this.getPixelRatio = function () {

354
		return _pixelRatio;
355 356 357 358 359

	};

	this.setPixelRatio = function ( value ) {

360 361 362 363
		if ( value === undefined ) return;

		_pixelRatio = value;

M
Mr.doob 已提交
364
		this.setSize( _width, _height, false );
365 366 367

	};

368
	this.getSize = function ( target ) {
369

370 371 372 373 374 375 376 377 378
		if ( target === undefined ) {

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

			target = new Vector2();

		}

		return target.set( _width, _height );
379 380 381

	};

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

M
Mr.doob 已提交
384
		if ( vr.isPresenting() ) {
385 386 387 388 389 390

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

		}

391 392 393
		_width = width;
		_height = height;

394 395
		_canvas.width = width * _pixelRatio;
		_canvas.height = height * _pixelRatio;
396

397
		if ( updateStyle !== false ) {
398

G
gero3 已提交
399 400
			_canvas.style.width = width + 'px';
			_canvas.style.height = height + 'px';
401

G
gero3 已提交
402
		}
M
Mr.doob 已提交
403

404
		this.setViewport( 0, 0, width, height );
M
Mr.doob 已提交
405 406 407

	};

408
	this.getDrawingBufferSize = function ( target ) {
M
Mr.doob 已提交
409

410 411 412 413 414 415 416 417 418
		if ( target === undefined ) {

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

			target = new Vector2();

		}

		return target.set( _width * _pixelRatio, _height * _pixelRatio );
M
Mr.doob 已提交
419 420 421

	};

422 423 424 425 426 427 428 429 430 431 432 433 434 435
	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 );

	};

436
	this.getCurrentViewport = function ( target ) {
M
Mugen87 已提交
437

438 439 440 441 442 443 444 445 446
		if ( target === undefined ) {

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

			target = new Vector4();

		}

		return target.copy( _currentViewport );
M
Mugen87 已提交
447 448 449

	};

450 451 452
	this.getViewport = function ( target ) {

		return target.copy( _viewport );
M
Mugen87 已提交
453 454 455

	};

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

458 459 460 461 462 463 464 465 466 467
		if ( x.isVector4 ) {

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

		} else {

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

		}

468
		state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );
469

M
Mr.doob 已提交
470 471
	};

472 473 474 475 476 477
	this.getScissor = function ( target ) {

		return target.copy( _scissor );

	};

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

480 481 482 483 484 485 486 487 488 489
		if ( x.isVector4 ) {

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

		} else {

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

		}

490
		state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );
491

M
Mr.doob 已提交
492 493
	};

494 495 496 497 498 499
	this.getScissorTest = function () {

		return _scissorTest;

	};

500 501
	this.setScissorTest = function ( boolean ) {

502
		state.setScissorTest( _scissorTest = boolean );
M
Mr.doob 已提交
503 504 505 506 507

	};

	// Clearing

M
Mr.doob 已提交
508
	this.getClearColor = function () {
M
Mr.doob 已提交
509

510
		return background.getClearColor();
M
Mr.doob 已提交
511 512 513

	};

514
	this.setClearColor = function () {
515

516
		background.setClearColor.apply( background, arguments );
M
Mr.doob 已提交
517 518 519

	};

M
Mr.doob 已提交
520
	this.getClearAlpha = function () {
M
Mr.doob 已提交
521

522
		return background.getClearAlpha();
M
Mr.doob 已提交
523 524 525

	};

M
Mugen87 已提交
526
	this.setClearAlpha = function () {
M
Mr.doob 已提交
527

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

	};

	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 );
541 542 543 544 545

	};

	this.clearColor = function () {

M
Mr.doob 已提交
546
		this.clear( true, false, false );
547 548 549 550 551

	};

	this.clearDepth = function () {

M
Mr.doob 已提交
552
		this.clear( false, true, false );
553 554 555 556 557

	};

	this.clearStencil = function () {

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

	};

M
Mr.doob 已提交
562
	//
M
Mr.doob 已提交
563

M
Mr.doob 已提交
564
	this.dispose = function () {
D
dubejf 已提交
565 566

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

569
		renderLists.dispose();
570
		renderStates.dispose();
M
Mugen87 已提交
571 572
		properties.dispose();
		objects.dispose();
573

574
		vr.dispose();
575

576
		animation.stop();
B
brunnerh 已提交
577

D
dubejf 已提交
578 579
	};

M
Mr.doob 已提交
580
	// Events
M
Mr.doob 已提交
581

D
dubejf 已提交
582 583 584 585
	function onContextLost( event ) {

		event.preventDefault();

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

588 589 590 591
		_isContextLost = true;

	}

M
Mugen87 已提交
592
	function onContextRestore( /* event */ ) {
D
dubejf 已提交
593

594
		console.log( 'THREE.WebGLRenderer: Context Restored.' );
595 596

		_isContextLost = false;
D
dubejf 已提交
597

598
		initGLContext();
D
dubejf 已提交
599

M
Mr.doob 已提交
600
	}
D
dubejf 已提交
601

602
	function onMaterialDispose( event ) {
M
Mr.doob 已提交
603 604 605 606 607 608 609

		var material = event.target;

		material.removeEventListener( 'dispose', onMaterialDispose );

		deallocateMaterial( material );

610
	}
M
Mr.doob 已提交
611 612 613

	// Buffer deallocation

614
	function deallocateMaterial( material ) {
M
Mr.doob 已提交
615

616 617
		releaseMaterialProgramReference( material );

618
		properties.remove( material );
619

620
	}
621 622


623
	function releaseMaterialProgramReference( material ) {
624

625
		var programInfo = properties.get( material ).program;
M
Mr.doob 已提交
626 627 628

		material.program = undefined;

629
		if ( programInfo !== undefined ) {
M
Mr.doob 已提交
630

631
			programCache.releaseProgram( programInfo );
M
Mr.doob 已提交
632

M
Mr.doob 已提交
633 634
		}

635
	}
M
Mr.doob 已提交
636 637 638

	// Buffer rendering

M
Mr.doob 已提交
639
	function renderObjectImmediate( object, program ) {
M
Mr.doob 已提交
640 641 642

		object.render( function ( object ) {

M
Mr.doob 已提交
643
			_this.renderBufferImmediate( object, program );
M
Mr.doob 已提交
644 645 646 647 648

		} );

	}

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

651
		state.initAttributes();
652

653
		var buffers = properties.get( object );
654

655 656 657 658
		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 已提交
659

660
		var programAttributes = program.getAttributes();
661

M
Mr.doob 已提交
662 663
		if ( object.hasPositions ) {

664
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );
M
Mr.doob 已提交
665
			_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );
666

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

		}

		if ( object.hasNormals ) {

674
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.normal );
M
Mr.doob 已提交
675
			_gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );
676

677 678
			state.enableAttribute( programAttributes.normal );
			_gl.vertexAttribPointer( programAttributes.normal, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
679 680 681

		}

682
		if ( object.hasUvs ) {
M
Mr.doob 已提交
683

684
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );
M
Mr.doob 已提交
685
			_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );
686

687
			state.enableAttribute( programAttributes.uv );
688
			_gl.vertexAttribPointer( programAttributes.uv, 2, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
689 690 691

		}

692
		if ( object.hasColors ) {
M
Mr.doob 已提交
693

694
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );
M
Mr.doob 已提交
695
			_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );
696

697 698
			state.enableAttribute( programAttributes.color );
			_gl.vertexAttribPointer( programAttributes.color, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
699 700 701

		}

702
		state.disableUnusedAttributes();
703

M
Mr.doob 已提交
704 705 706 707 708 709
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );

		object.count = 0;

	};

710
	this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {
711

712
		var frontFaceCW = ( object.isMesh && object.matrixWorld.determinant() < 0 );
713 714

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

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

M
Mr.doob 已提交
718
		var updateBuffers = false;
M
Mr.doob 已提交
719

720 721 722
		if ( _currentGeometryProgram.geometry !== geometry.id ||
			_currentGeometryProgram.program !== program.id ||
			_currentGeometryProgram.wireframe !== ( material.wireframe === true ) ) {
M
Mr.doob 已提交
723

M
Mr.doob 已提交
724 725
			_currentGeometryProgram.geometry = geometry.id;
			_currentGeometryProgram.program = program.id;
726
			_currentGeometryProgram.wireframe = material.wireframe === true;
M
Mr.doob 已提交
727 728 729 730
			updateBuffers = true;

		}

731
		if ( object.morphTargetInfluences ) {
732

733
			morphtargets.update( object, geometry, material, program );
M
Mr.doob 已提交
734 735 736 737 738

			updateBuffers = true;

		}

739 740
		//

741
		var index = geometry.index;
742
		var position = geometry.attributes.position;
743
		var rangeFactor = 1;
744

745 746
		if ( material.wireframe === true ) {

747
			index = geometries.getWireframeAttribute( geometry );
748
			rangeFactor = 2;
749 750 751

		}

M
Mr.doob 已提交
752
		var attribute;
M
Mr.doob 已提交
753
		var renderer = bufferRenderer;
754

755
		if ( index !== null ) {
756

M
Mr.doob 已提交
757
			attribute = attributes.get( index );
758

759
			renderer = indexedBufferRenderer;
M
Mr.doob 已提交
760
			renderer.setIndex( attribute );
761

762
		}
M
Mr.doob 已提交
763

764
		if ( updateBuffers ) {
M
Mr.doob 已提交
765

766
			setupVertexAttributes( material, program, geometry );
M
Mr.doob 已提交
767

768
			if ( index !== null ) {
769

M
Mr.doob 已提交
770
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, attribute.buffer );
771 772 773

			}

774
		}
775

776 777
		//

778
		var dataCount = Infinity;
779

M
Mr.doob 已提交
780
		if ( index !== null ) {
781

M
Mr.doob 已提交
782
			dataCount = index.count;
783

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

M
Mr.doob 已提交
786
			dataCount = position.count;
787

M
Mr.doob 已提交
788
		}
789

M
Mr.doob 已提交
790 791
		var rangeStart = geometry.drawRange.start * rangeFactor;
		var rangeCount = geometry.drawRange.count * rangeFactor;
792

M
Mr.doob 已提交
793 794
		var groupStart = group !== null ? group.start * rangeFactor : 0;
		var groupCount = group !== null ? group.count * rangeFactor : Infinity;
795

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

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

801 802
		if ( drawCount === 0 ) return;

M
Mr.doob 已提交
803
		//
804

805
		if ( object.isMesh ) {
806

807
			if ( material.wireframe === true ) {
808

809
				state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );
810
				renderer.setMode( _gl.LINES );
811

812
			} else {
M
Mr.doob 已提交
813 814

				switch ( object.drawMode ) {
815

R
Rich Harris 已提交
816
					case TrianglesDrawMode:
B
Ben Adams 已提交
817 818 819
						renderer.setMode( _gl.TRIANGLES );
						break;

R
Rich Harris 已提交
820
					case TriangleStripDrawMode:
B
Ben Adams 已提交
821 822 823
						renderer.setMode( _gl.TRIANGLE_STRIP );
						break;

R
Rich Harris 已提交
824
					case TriangleFanDrawMode:
B
Ben Adams 已提交
825 826 827 828
						renderer.setMode( _gl.TRIANGLE_FAN );
						break;

				}
829

830
			}
831

832

833
		} else if ( object.isLine ) {
834

835
			var lineWidth = material.linewidth;
836

837
			if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material
838

839
			state.setLineWidth( lineWidth * getTargetPixelRatio() );
840

841
			if ( object.isLineSegments ) {
842

843
				renderer.setMode( _gl.LINES );
844

845 846 847 848
			} else if ( object.isLineLoop ) {

				renderer.setMode( _gl.LINE_LOOP );

849
			} else {
850

851
				renderer.setMode( _gl.LINE_STRIP );
852 853

			}
M
Mr.doob 已提交
854

855
		} else if ( object.isPoints ) {
856 857

			renderer.setMode( _gl.POINTS );
858

859 860 861 862
		} else if ( object.isSprite ) {

			renderer.setMode( _gl.TRIANGLES );

863
		}
864

T
Takahiro 已提交
865
		if ( geometry && geometry.isInstancedBufferGeometry ) {
M
Mr.doob 已提交
866 867 868

			if ( geometry.maxInstancedCount > 0 ) {

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

J
jfranc 已提交
871
			}
872 873 874

		} else {

M
Mr.doob 已提交
875
			renderer.render( drawStart, drawCount );
876

M
Mr.doob 已提交
877 878 879 880
		}

	};

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

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

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

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

M
Mr.doob 已提交
890 891 892
			}

		}
B
Ben Adams 已提交
893

894 895
		state.initAttributes();

896
		var geometryAttributes = geometry.attributes;
897

898
		var programAttributes = program.getAttributes();
899

900
		var materialDefaultAttributeValues = material.defaultAttributeValues;
901

902
		for ( var name in programAttributes ) {
903

904
			var programAttribute = programAttributes[ name ];
M
Mr.doob 已提交
905

M
Mr.doob 已提交
906
			if ( programAttribute >= 0 ) {
M
Mr.doob 已提交
907

908
				var geometryAttribute = geometryAttributes[ name ];
909

M
Mr.doob 已提交
910
				if ( geometryAttribute !== undefined ) {
M
Mr.doob 已提交
911

912
					var normalized = geometryAttribute.normalized;
913
					var size = geometryAttribute.itemSize;
914

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

917 918 919 920
					// TODO Attribute may not be available on context restore

					if ( attribute === undefined ) continue;

M
Mr.doob 已提交
921 922 923
					var buffer = attribute.buffer;
					var type = attribute.type;
					var bytesPerElement = attribute.bytesPerElement;
924

A
aardgoose 已提交
925
					if ( geometryAttribute.isInterleavedBufferAttribute ) {
926

M
Mr.doob 已提交
927 928 929 930
						var data = geometryAttribute.data;
						var stride = data.stride;
						var offset = geometryAttribute.offset;

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

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

M
Mr.doob 已提交
935
							if ( geometry.maxInstancedCount === undefined ) {
936

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

M
Mr.doob 已提交
939
							}
B
Ben Adams 已提交
940

M
Mr.doob 已提交
941
						} else {
B
Ben Adams 已提交
942

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

M
Mr.doob 已提交
945
						}
B
Ben Adams 已提交
946

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

M
Mr.doob 已提交
950
					} else {
B
Ben Adams 已提交
951

A
aardgoose 已提交
952
						if ( geometryAttribute.isInstancedBufferAttribute ) {
B
Ben Adams 已提交
953

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

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

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

M
Mr.doob 已提交
960
							}
B
Ben Adams 已提交
961

M
Mr.doob 已提交
962 963 964 965
						} else {

							state.enableAttribute( programAttribute );

M
Mr.doob 已提交
966
						}
B
Ben Adams 已提交
967

M
Mr.doob 已提交
968
						_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
969
						_gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, 0 );
M
Mr.doob 已提交
970

B
Ben Adams 已提交
971
					}
M
Mr.doob 已提交
972

973 974
				} else if ( materialDefaultAttributeValues !== undefined ) {

T
tschw 已提交
975
					var value = materialDefaultAttributeValues[ name ];
976

977
					if ( value !== undefined ) {
M
Mr.doob 已提交
978

979
						switch ( value.length ) {
M
Mr.doob 已提交
980

981 982 983
							case 2:
								_gl.vertexAttrib2fv( programAttribute, value );
								break;
M
Mr.doob 已提交
984

985 986 987
							case 3:
								_gl.vertexAttrib3fv( programAttribute, value );
								break;
M
Mr.doob 已提交
988

989 990 991
							case 4:
								_gl.vertexAttrib4fv( programAttribute, value );
								break;
992

993 994
							default:
								_gl.vertexAttrib1fv( programAttribute, value );
995 996

						}
M
Mr.doob 已提交
997 998 999 1000 1001 1002 1003 1004

					}

				}

			}

		}
1005

1006
		state.disableUnusedAttributes();
1007

M
Mr.doob 已提交
1008 1009
	}

M
Mr.doob 已提交
1010
	// Compile
M
Mr.doob 已提交
1011

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

M
Mr.doob 已提交
1014
		currentRenderState = renderStates.get( scene, camera );
1015
		currentRenderState.init();
1016

M
Mr.doob 已提交
1017
		scene.traverse( function ( object ) {
G
gero3 已提交
1018 1019

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

1021
				currentRenderState.pushLight( object );
1022 1023 1024

				if ( object.castShadow ) {

1025
					currentRenderState.pushShadow( object );
1026 1027

				}
M
Mr.doob 已提交
1028

G
gero3 已提交
1029
			}
M
Mr.doob 已提交
1030 1031 1032

		} );

1033
		currentRenderState.setupLights( camera );
M
Mr.doob 已提交
1034 1035 1036 1037 1038

		scene.traverse( function ( object ) {

			if ( object.material ) {

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

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

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

G
gero3 已提交
1045
					}
M
Mr.doob 已提交
1046

G
gero3 已提交
1047
				} else {
M
Mr.doob 已提交
1048 1049 1050

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

G
gero3 已提交
1051
				}
M
Mr.doob 已提交
1052

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

		} );
G
gero3 已提交
1056 1057

	};
1058

1059
	// Animation Loop
M
Mr.doob 已提交
1060

M
Mr.doob 已提交
1061
	var onAnimationFrameCallback = null;
1062

1063
	function onAnimationFrame( time ) {
1064

M
Mr.doob 已提交
1065
		if ( vr.isPresenting() ) return;
1066
		if ( onAnimationFrameCallback ) onAnimationFrameCallback( time );
1067

1068
	}
1069

M
Mr.doob 已提交
1070 1071
	var animation = new WebGLAnimation();
	animation.setAnimationLoop( onAnimationFrame );
1072 1073

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

1075
	this.setAnimationLoop = function ( callback ) {
1076

M
Mr.doob 已提交
1077 1078
		onAnimationFrameCallback = callback;
		vr.setAnimationLoop( callback );
1079

1080 1081
		animation.start();

1082 1083
	};

M
Mr.doob 已提交
1084 1085
	// Rendering

1086 1087
	this.render = function ( scene, camera ) {

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

		if ( arguments[ 2 ] !== undefined ) {

			console.warn( 'THREE.WebGLRenderer.render(): the renderTarget argument has been removed. Use .setRenderTarget() instead.' );
			renderTarget = arguments[ 2 ];

		}

		if ( arguments[ 3 ] !== undefined ) {

			console.warn( 'THREE.WebGLRenderer.render(): the forceClear argument has been removed. Use .clear() instead.' );
			forceClear = arguments[ 3 ];

		}
1103

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

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

		}

1111 1112
		if ( _isContextLost ) return;

M
Mr.doob 已提交
1113 1114
		// reset caching for this frame

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

		// update scene graph

1123
		if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
M
Mr.doob 已提交
1124 1125 1126

		// update camera matrices and frustum

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

1129 1130 1131 1132 1133 1134
		if ( vr.enabled ) {

			camera = vr.getCamera( camera );

		}

1135 1136
		//

1137 1138
		currentRenderState = renderStates.get( scene, camera );
		currentRenderState.init();
1139

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

M
Mr.doob 已提交
1142 1143 1144
		_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
		_frustum.setFromMatrix( _projScreenMatrix );

T
tschw 已提交
1145
		_localClippingEnabled = this.localClippingEnabled;
M
Mr.doob 已提交
1146
		_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );
T
tschw 已提交
1147

1148 1149 1150
		currentRenderList = renderLists.get( scene, camera );
		currentRenderList.init();

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

M
Mr.doob 已提交
1153
		if ( _this.sortObjects === true ) {
1154

1155
			currentRenderList.sort();
M
Mr.doob 已提交
1156

1157 1158
		}

M
Mr.doob 已提交
1159
		//
M
Mr.doob 已提交
1160

T
tschw 已提交
1161
		if ( _clippingEnabled ) _clipping.beginShadows();
T
tschw 已提交
1162

1163
		var shadowsArray = currentRenderState.state.shadowsArray;
1164

1165
		shadowMap.render( shadowsArray, scene, camera );
1166

1167
		currentRenderState.setupLights( camera );
1168

T
tschw 已提交
1169
		if ( _clippingEnabled ) _clipping.endShadows();
T
tschw 已提交
1170

M
Mr.doob 已提交
1171 1172
		//

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

1175
		if ( renderTarget !== undefined ) {
1176

1177
			this.setRenderTarget( renderTarget );
1178 1179 1180

		}

M
Mr.doob 已提交
1181 1182
		//

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

1185
		// render scene
M
Mr.doob 已提交
1186

1187 1188 1189
		var opaqueObjects = currentRenderList.opaque;
		var transparentObjects = currentRenderList.transparent;

M
Mr.doob 已提交
1190 1191
		if ( scene.overrideMaterial ) {

1192
			var overrideMaterial = scene.overrideMaterial;
M
Mr.doob 已提交
1193

M
Mr.doob 已提交
1194 1195
			if ( opaqueObjects.length ) renderObjects( opaqueObjects, scene, camera, overrideMaterial );
			if ( transparentObjects.length ) renderObjects( transparentObjects, scene, camera, overrideMaterial );
1196

M
Mr.doob 已提交
1197 1198
		} else {

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

M
Mr.doob 已提交
1201
			if ( opaqueObjects.length ) renderObjects( opaqueObjects, scene, camera );
1202 1203 1204

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

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

1207
		}
M
Mr.doob 已提交
1208

1209
		//
M
Mr.doob 已提交
1210

1211 1212 1213 1214
		scene.onAfterRender( _this, scene, camera );

		//

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

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

1219
			textures.updateRenderTargetMipmap( _currentRenderTarget );
M
Mr.doob 已提交
1220

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

1223
			textures.updateMultisampleRenderTarget( _currentRenderTarget );
1224

M
Mr.doob 已提交
1225 1226
		}

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

1229 1230 1231
		state.buffers.depth.setTest( true );
		state.buffers.depth.setMask( true );
		state.buffers.color.setMask( true );
M
Mr.doob 已提交
1232

1233
		state.setPolygonOffset( false );
1234

M
Mr.doob 已提交
1235
		if ( vr.enabled ) {
1236

1237
			vr.submitFrame();
1238

M
Mr.doob 已提交
1239
		}
M
Mr.doob 已提交
1240

M
Mr.doob 已提交
1241 1242
		// _gl.finish();

1243
		currentRenderList = null;
1244
		currentRenderState = null;
1245

M
Mr.doob 已提交
1246
	};
M
Mr.doob 已提交
1247

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

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

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

1254
		if ( visible ) {
1255

1256 1257 1258 1259 1260
			if ( object.isGroup ) {

				groupOrder = object.renderOrder;

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

1262
				currentRenderState.pushLight( object );
1263 1264 1265

				if ( object.castShadow ) {

1266
					currentRenderState.pushShadow( object );
1267 1268

				}
M
Mr.doob 已提交
1269

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

1272
				if ( ! object.frustumCulled || _frustum.intersectsSprite( object ) ) {
1273

1274 1275 1276 1277 1278 1279 1280 1281 1282 1283
					if ( sortObjects ) {

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

					}

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

1284 1285 1286 1287 1288
					if ( material.visible ) {

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

					}
M
Mr.doob 已提交
1289

1290
				}
M
Mr.doob 已提交
1291

1292
			} else if ( object.isImmediateRenderObject ) {
M
Mr.doob 已提交
1293

1294
				if ( sortObjects ) {
M
Mr.doob 已提交
1295

1296 1297
					_vector3.setFromMatrixPosition( object.matrixWorld )
						.applyMatrix4( _projScreenMatrix );
M
Mr.doob 已提交
1298

1299
				}
M
Mr.doob 已提交
1300

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

1303
			} else if ( object.isMesh || object.isLine || object.isPoints ) {
1304

1305
				if ( object.isSkinnedMesh ) {
1306

1307
					object.skeleton.update();
1308

1309
				}
1310

1311
				if ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) {
1312

1313 1314 1315 1316 1317 1318
					if ( sortObjects ) {

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

					}
1319

1320 1321
					var geometry = objects.update( object );
					var material = object.material;
1322

1323
					if ( Array.isArray( material ) ) {
1324

1325
						var groups = geometry.groups;
1326

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

1329 1330
							var group = groups[ i ];
							var groupMaterial = material[ group.materialIndex ];
1331

1332
							if ( groupMaterial && groupMaterial.visible ) {
1333

1334
								currentRenderList.push( object, geometry, groupMaterial, groupOrder, _vector3.z, group );
1335 1336

							}
M
Mr.doob 已提交
1337

M
Mr.doob 已提交
1338
						}
M
Mr.doob 已提交
1339

1340
					} else if ( material.visible ) {
1341

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

1344
					}
M
Mr.doob 已提交
1345

1346
				}
M
Mr.doob 已提交
1347

1348
			}
M
Mr.doob 已提交
1349

M
Mr.doob 已提交
1350
		}
M
Mr.doob 已提交
1351

M
Mr.doob 已提交
1352
		var children = object.children;
M
Mr.doob 已提交
1353

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

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

1358
		}
1359

1360
	}
M
Mr.doob 已提交
1361

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

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

1366
			var renderItem = renderList[ i ];
M
Mr.doob 已提交
1367

1368
			var object = renderItem.object;
M
Mr.doob 已提交
1369 1370 1371
			var geometry = renderItem.geometry;
			var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;
			var group = renderItem.group;
M
Mr.doob 已提交
1372

M
Mr.doob 已提交
1373
			if ( camera.isArrayCamera ) {
M
Mr.doob 已提交
1374

1375 1376
				_currentArrayCamera = camera;

M
Mr.doob 已提交
1377
				var cameras = camera.cameras;
M
Mr.doob 已提交
1378

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

M
Mr.doob 已提交
1381
					var camera2 = cameras[ j ];
M
Mr.doob 已提交
1382

1383
					if ( object.layers.test( camera2.layers ) ) {
1384

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

1387 1388
						currentRenderState.setupLights( camera2 );

1389 1390 1391
						renderObject( object, scene, camera2, geometry, material, group );

					}
M
Mr.doob 已提交
1392

M
Mr.doob 已提交
1393
				}
1394

M
Mr.doob 已提交
1395
			} else {
M
Mr.doob 已提交
1396

1397 1398
				_currentArrayCamera = null;

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

M
Mr.doob 已提交
1401
			}
M
Mr.doob 已提交
1402

1403
		}
M
Mr.doob 已提交
1404

1405
	}
G
gero3 已提交
1406

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

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

M
Mr.doob 已提交
1412 1413 1414 1415 1416
		object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
		object.normalMatrix.getNormalMatrix( object.modelViewMatrix );

		if ( object.isImmediateRenderObject ) {

1417
			state.setMaterial( material );
M
Mr.doob 已提交
1418 1419 1420

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

M
Mr.doob 已提交
1421 1422
			_currentGeometryProgram.geometry = null;
			_currentGeometryProgram.program = null;
1423
			_currentGeometryProgram.wireframe = false;
M
Mr.doob 已提交
1424

M
Mr.doob 已提交
1425
			renderObjectImmediate( object, program );
M
Mr.doob 已提交
1426 1427 1428

		} else {

M
Mugen87 已提交
1429
			_this.renderBufferDirect( camera, scene.fog, geometry, material, object, group );
M
Mr.doob 已提交
1430 1431 1432

		}

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

M
Mr.doob 已提交
1436 1437
	}

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

1440
		var materialProperties = properties.get( material );
G
gero3 已提交
1441

1442 1443
		var lights = currentRenderState.state.lights;
		var shadowsArray = currentRenderState.state.shadowsArray;
1444

M
Mr.doob 已提交
1445 1446 1447
		var lightsHash = materialProperties.lightsHash;
		var lightsStateHash = lights.state.hash;

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

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

1453
		var program = materialProperties.program;
T
tschw 已提交
1454
		var programChange = true;
1455

1456
		if ( program === undefined ) {
B
Ben Adams 已提交
1457

M
Mr.doob 已提交
1458 1459
			// new material
			material.addEventListener( 'dispose', onMaterialDispose );
B
Ben Adams 已提交
1460

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

M
Mr.doob 已提交
1463
			// changed glsl or parameters
1464
			releaseMaterialProgramReference( material );
B
Ben Adams 已提交
1465

M
Mr.doob 已提交
1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480
		} else if ( lightsHash.stateID !== lightsStateHash.stateID ||
			lightsHash.directionalLength !== lightsStateHash.directionalLength ||
			lightsHash.pointLength !== lightsStateHash.pointLength ||
			lightsHash.spotLength !== lightsStateHash.spotLength ||
			lightsHash.rectAreaLength !== lightsStateHash.rectAreaLength ||
			lightsHash.hemiLength !== lightsStateHash.hemiLength ||
			lightsHash.shadowsLength !== lightsStateHash.shadowsLength ) {

			lightsHash.stateID = lightsStateHash.stateID;
			lightsHash.directionalLength = lightsStateHash.directionalLength;
			lightsHash.pointLength = lightsStateHash.pointLength;
			lightsHash.spotLength = lightsStateHash.spotLength;
			lightsHash.rectAreaLength = lightsStateHash.rectAreaLength;
			lightsHash.hemiLength = lightsStateHash.hemiLength;
			lightsHash.shadowsLength = lightsStateHash.shadowsLength;
1481 1482 1483

			programChange = false;

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

T
tschw 已提交
1486
			// same glsl and uniform list
T
tschw 已提交
1487 1488
			return;

T
tschw 已提交
1489
		} else {
B
Ben Adams 已提交
1490

T
tschw 已提交
1491 1492
			// only rebuild uniform list
			programChange = false;
B
Ben Adams 已提交
1493 1494 1495

		}

1496
		if ( programChange ) {
B
Ben Adams 已提交
1497

1498
			if ( parameters.shaderID ) {
B
Ben Adams 已提交
1499

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

1502
				materialProperties.shader = {
1503
					name: material.type,
M
Mr.doob 已提交
1504
					uniforms: cloneUniforms( shader.uniforms ),
1505
					vertexShader: shader.vertexShader,
1506
					fragmentShader: shader.fragmentShader
1507
				};
B
Ben Adams 已提交
1508

1509
			} else {
B
Ben Adams 已提交
1510

1511
				materialProperties.shader = {
1512 1513 1514
					name: material.type,
					uniforms: material.uniforms,
					vertexShader: material.vertexShader,
1515
					fragmentShader: material.fragmentShader
1516
				};
G
gero3 已提交
1517

1518
			}
G
gero3 已提交
1519

1520
			material.onBeforeCompile( materialProperties.shader, _this );
G
gero3 已提交
1521

1522
			// Computing code again as onBeforeCompile may have changed the shaders
1523 1524
			code = programCache.getProgramCode( material, parameters );

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

1527 1528
			materialProperties.program = program;
			material.program = program;
1529 1530 1531

		}

1532
		var programAttributes = program.getAttributes();
M
Mr.doob 已提交
1533 1534 1535 1536 1537

		if ( material.morphTargets ) {

			material.numSupportedMorphTargets = 0;

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

1540
				if ( programAttributes[ 'morphTarget' + i ] >= 0 ) {
M
Mr.doob 已提交
1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553

					material.numSupportedMorphTargets ++;

				}

			}

		}

		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

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

1556
				if ( programAttributes[ 'morphNormal' + i ] >= 0 ) {
M
Mr.doob 已提交
1557 1558 1559 1560 1561 1562 1563 1564 1565

					material.numSupportedMorphNormals ++;

				}

			}

		}

1566
		var uniforms = materialProperties.shader.uniforms;
T
tschw 已提交
1567

1568
		if ( ! material.isShaderMaterial &&
1569 1570
			! material.isRawShaderMaterial ||
			material.clipping === true ) {
T
tschw 已提交
1571

T
tschw 已提交
1572
			materialProperties.numClippingPlanes = _clipping.numPlanes;
1573
			materialProperties.numIntersection = _clipping.numIntersection;
T
tschw 已提交
1574
			uniforms.clippingPlanes = _clipping.uniform;
T
tschw 已提交
1575 1576 1577

		}

1578
		materialProperties.fog = fog;
1579

1580
		// store the light setup it was created for
M
Mr.doob 已提交
1581
		if ( lightsHash === undefined ) {
1582

M
Mr.doob 已提交
1583
			materialProperties.lightsHash = lightsHash = {};
1584 1585 1586

		}

M
Mr.doob 已提交
1587 1588 1589 1590 1591 1592 1593
		lightsHash.stateID = lightsStateHash.stateID;
		lightsHash.directionalLength = lightsStateHash.directionalLength;
		lightsHash.pointLength = lightsStateHash.pointLength;
		lightsHash.spotLength = lightsStateHash.spotLength;
		lightsHash.rectAreaLength = lightsStateHash.rectAreaLength;
		lightsHash.hemiLength = lightsStateHash.hemiLength;
		lightsHash.shadowsLength = lightsStateHash.shadowsLength;
1594

M
Mr.doob 已提交
1595
		if ( material.lights ) {
1596 1597 1598

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

1599
			uniforms.ambientLightColor.value = lights.state.ambient;
W
WestLangley 已提交
1600
			uniforms.lightProbe.value = lights.state.probe;
1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612
			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;
1613
			// TODO (abelnation): add area lights shadow info to uniforms
1614

1615 1616
		}

T
tschw 已提交
1617 1618
		var progUniforms = materialProperties.program.getUniforms(),
			uniformsList =
1619
				WebGLUniforms.seqWithValue( progUniforms.seq, uniforms );
A
arose 已提交
1620

T
tschw 已提交
1621
		materialProperties.uniformsList = uniformsList;
A
arose 已提交
1622

M
Mr.doob 已提交
1623
	}
M
Mr.doob 已提交
1624

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

1627
		textures.resetTextureUnits();
M
Mr.doob 已提交
1628

1629
		var materialProperties = properties.get( material );
1630
		var lights = currentRenderState.state.lights;
1631

M
Mr.doob 已提交
1632 1633 1634
		var lightsHash = materialProperties.lightsHash;
		var lightsStateHash = lights.state.hash;

T
tschw 已提交
1635 1636 1637 1638 1639
		if ( _clippingEnabled ) {

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

				var useCache =
1640 1641
					camera === _currentCamera &&
					material.id === _currentMaterialId;
T
tschw 已提交
1642 1643 1644 1645

				// we might want to call this function with some ClippingGroup
				// object instead of the material, once it becomes feasible
				// (#8465, #8379)
T
tschw 已提交
1646
				_clipping.setState(
1647 1648
					material.clippingPlanes, material.clipIntersection, material.clipShadows,
					camera, materialProperties, useCache );
T
tschw 已提交
1649 1650 1651 1652 1653

			}

		}

1654
		if ( material.needsUpdate === false ) {
1655

1656
			if ( materialProperties.program === undefined ) {
1657

1658
				material.needsUpdate = true;
1659

1660
			} else if ( material.fog && materialProperties.fog !== fog ) {
1661

M
Mr.doob 已提交
1662
				material.needsUpdate = true;
1663

M
Mr.doob 已提交
1664 1665 1666 1667 1668 1669 1670
			} else if ( material.lights && ( lightsHash.stateID !== lightsStateHash.stateID ||
				lightsHash.directionalLength !== lightsStateHash.directionalLength ||
				lightsHash.pointLength !== lightsStateHash.pointLength ||
				lightsHash.spotLength !== lightsStateHash.spotLength ||
				lightsHash.rectAreaLength !== lightsStateHash.rectAreaLength ||
				lightsHash.hemiLength !== lightsStateHash.hemiLength ||
				lightsHash.shadowsLength !== lightsStateHash.shadowsLength ) ) {
1671

1672
				material.needsUpdate = true;
1673

1674
			} else if ( materialProperties.numClippingPlanes !== undefined &&
1675
				( materialProperties.numClippingPlanes !== _clipping.numPlanes ||
M
Mr.doob 已提交
1676
				materialProperties.numIntersection !== _clipping.numIntersection ) ) {
1677 1678 1679

				material.needsUpdate = true;

1680
			}
1681 1682 1683 1684

		}

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

1686
			initMaterial( material, fog, object );
M
Mr.doob 已提交
1687 1688 1689 1690
			material.needsUpdate = false;

		}

1691
		var refreshProgram = false;
M
Mr.doob 已提交
1692
		var refreshMaterial = false;
1693
		var refreshLights = false;
M
Mr.doob 已提交
1694

1695
		var program = materialProperties.program,
1696
			p_uniforms = program.getUniforms(),
1697
			m_uniforms = materialProperties.shader.uniforms;
M
Mr.doob 已提交
1698

1699
		if ( state.useProgram( program.program ) ) {
M
Mr.doob 已提交
1700

1701
			refreshProgram = true;
M
Mr.doob 已提交
1702
			refreshMaterial = true;
1703
			refreshLights = true;
M
Mr.doob 已提交
1704 1705 1706 1707 1708 1709

		}

		if ( material.id !== _currentMaterialId ) {

			_currentMaterialId = material.id;
1710

M
Mr.doob 已提交
1711 1712 1713 1714
			refreshMaterial = true;

		}

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

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

G
gero3 已提交
1719
			if ( capabilities.logarithmicDepthBuffer ) {
1720

T
tschw 已提交
1721
				p_uniforms.setValue( _gl, 'logDepthBufFC',
1722
					2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
1723 1724 1725

			}

1726
			if ( _currentCamera !== camera ) {
1727

1728
				_currentCamera = camera;
1729 1730 1731 1732 1733 1734

				// 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 已提交
1735
				refreshLights = true;		// remains set until update done
1736 1737

			}
M
Mr.doob 已提交
1738

1739 1740 1741
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)

1742
			if ( material.isShaderMaterial ||
1743 1744 1745
				material.isMeshPhongMaterial ||
				material.isMeshStandardMaterial ||
				material.envMap ) {
1746

T
tschw 已提交
1747 1748 1749
				var uCamPos = p_uniforms.map.cameraPosition;

				if ( uCamPos !== undefined ) {
1750

T
tschw 已提交
1751
					uCamPos.setValue( _gl,
1752
						_vector3.setFromMatrixPosition( camera.matrixWorld ) );
1753 1754 1755 1756 1757

				}

			}

1758
			if ( material.isMeshPhongMaterial ||
1759 1760 1761 1762
				material.isMeshLambertMaterial ||
				material.isMeshBasicMaterial ||
				material.isMeshStandardMaterial ||
				material.isShaderMaterial ||
1763
				material.skinning ) {
1764

T
tschw 已提交
1765
				p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );
1766 1767 1768

			}

M
Mr.doob 已提交
1769 1770 1771 1772 1773 1774
		}

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

1775
		if ( material.skinning ) {
M
Mr.doob 已提交
1776

T
tschw 已提交
1777 1778
			p_uniforms.setOptional( _gl, object, 'bindMatrix' );
			p_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );
1779

T
tschw 已提交
1780
			var skeleton = object.skeleton;
1781

T
tschw 已提交
1782
			if ( skeleton ) {
1783

1784 1785
				var bones = skeleton.bones;

1786
				if ( capabilities.floatVertexTextures ) {
M
Mr.doob 已提交
1787

1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798
					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
1799
						size = _Math.ceilPowerOfTwo( size );
1800 1801 1802 1803 1804 1805
						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 );
1806
						boneTexture.needsUpdate = true;
1807 1808 1809 1810 1811 1812 1813

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

					}

1814
					p_uniforms.setValue( _gl, 'boneTexture', skeleton.boneTexture, textures );
M
Mr.doob 已提交
1815
					p_uniforms.setValue( _gl, 'boneTextureSize', skeleton.boneTextureSize );
M
Mr.doob 已提交
1816

T
tschw 已提交
1817
				} else {
M
Mr.doob 已提交
1818

T
tschw 已提交
1819
					p_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );
M
Mr.doob 已提交
1820 1821 1822 1823 1824 1825 1826 1827 1828

				}

			}

		}

		if ( refreshMaterial ) {

1829 1830 1831
			p_uniforms.setValue( _gl, 'toneMappingExposure', _this.toneMappingExposure );
			p_uniforms.setValue( _gl, 'toneMappingWhitePoint', _this.toneMappingWhitePoint );

M
Mr.doob 已提交
1832
			if ( material.lights ) {
M
Mr.doob 已提交
1833

1834
				// the current material requires lighting info
M
Mr.doob 已提交
1835

T
tschw 已提交
1836 1837 1838 1839 1840 1841
				// 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 已提交
1842

T
tschw 已提交
1843
				markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
G
gero3 已提交
1844

T
tschw 已提交
1845
			}
G
gero3 已提交
1846

T
tschw 已提交
1847
			// refresh uniforms common to several materials
G
gero3 已提交
1848

T
tschw 已提交
1849
			if ( fog && material.fog ) {
G
gero3 已提交
1850

T
tschw 已提交
1851
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
1852 1853 1854

			}

1855
			if ( material.isMeshBasicMaterial ) {
M
Mr.doob 已提交
1856 1857 1858

				refreshUniformsCommon( m_uniforms, material );

1859
			} else if ( material.isMeshLambertMaterial ) {
M
Mr.doob 已提交
1860

1861 1862
				refreshUniformsCommon( m_uniforms, material );
				refreshUniformsLambert( m_uniforms, material );
M
Mr.doob 已提交
1863

1864
			} else if ( material.isMeshPhongMaterial ) {
M
Mr.doob 已提交
1865

1866
				refreshUniformsCommon( m_uniforms, material );
M
Mr.doob 已提交
1867

1868
				if ( material.isMeshToonMaterial ) {
M
Mr.doob 已提交
1869

1870
					refreshUniformsToon( m_uniforms, material );
M
Mr.doob 已提交
1871

1872
				} else {
1873

1874
					refreshUniformsPhong( m_uniforms, material );
1875

1876
				}
T
Takahiro 已提交
1877

1878
			} else if ( material.isMeshStandardMaterial ) {
T
Takahiro 已提交
1879

1880
				refreshUniformsCommon( m_uniforms, material );
1881

1882
				if ( material.isMeshPhysicalMaterial ) {
1883

1884
					refreshUniformsPhysical( m_uniforms, material );
W
WestLangley 已提交
1885

1886
				} else {
W
WestLangley 已提交
1887

1888
					refreshUniformsStandard( m_uniforms, material );
W
WestLangley 已提交
1889

1890
				}
W
WestLangley 已提交
1891

W
WestLangley 已提交
1892 1893 1894 1895 1896 1897
			} else if ( material.isMeshMatcapMaterial ) {

				refreshUniformsCommon( m_uniforms, material );

				refreshUniformsMatcap( m_uniforms, material );

1898
			} else if ( material.isMeshDepthMaterial ) {
M
Mr.doob 已提交
1899

1900
				refreshUniformsCommon( m_uniforms, material );
W
WestLangley 已提交
1901
				refreshUniformsDepth( m_uniforms, material );
1902

W
WestLangley 已提交
1903
			} else if ( material.isMeshDistanceMaterial ) {
1904

1905
				refreshUniformsCommon( m_uniforms, material );
W
WestLangley 已提交
1906
				refreshUniformsDistance( m_uniforms, material );
1907

1908
			} else if ( material.isMeshNormalMaterial ) {
M
Mr.doob 已提交
1909

1910
				refreshUniformsCommon( m_uniforms, material );
1911
				refreshUniformsNormal( m_uniforms, material );
M
Mr.doob 已提交
1912

1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926
			} else if ( material.isLineBasicMaterial ) {

				refreshUniformsLine( m_uniforms, material );

				if ( material.isLineDashedMaterial ) {

					refreshUniformsDash( m_uniforms, material );

				}

			} else if ( material.isPointsMaterial ) {

				refreshUniformsPoints( m_uniforms, material );

1927 1928 1929 1930
			} else if ( material.isSpriteMaterial ) {

				refreshUniformsSprites( m_uniforms, material );

1931 1932
			} else if ( material.isShadowMaterial ) {

T
Takahiro 已提交
1933
				m_uniforms.color.value.copy( material.color );
1934 1935
				m_uniforms.opacity.value = material.opacity;

M
Mr.doob 已提交
1936 1937
			}

M
Mr.doob 已提交
1938 1939 1940
			// RectAreaLight Texture
			// TODO (mrdoob): Find a nicer implementation

1941 1942
			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 已提交
1943

1944
			WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, textures );
A
arose 已提交
1945 1946 1947

		}

1948 1949
		if ( material.isShaderMaterial && material.uniformsNeedUpdate === true ) {

1950
			WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, textures );
1951 1952 1953
			material.uniformsNeedUpdate = false;

		}
M
Mr.doob 已提交
1954

1955 1956 1957 1958 1959 1960
		if ( material.isSpriteMaterial ) {

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

		}

T
tschw 已提交
1961
		// common matrices
M
Mr.doob 已提交
1962

M
Mr.doob 已提交
1963 1964
		p_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix );
		p_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix );
T
tschw 已提交
1965
		p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );
A
arose 已提交
1966

T
tschw 已提交
1967
		return program;
A
arose 已提交
1968 1969 1970

	}

M
Mr.doob 已提交
1971 1972
	// Uniforms (refresh uniforms objects)

M
Mr.doob 已提交
1973
	function refreshUniformsCommon( uniforms, material ) {
M
Mr.doob 已提交
1974 1975 1976

		uniforms.opacity.value = material.opacity;

1977 1978
		if ( material.color ) {

T
Takahiro 已提交
1979
			uniforms.diffuse.value.copy( material.color );
1980 1981

		}
M
Mr.doob 已提交
1982

1983
		if ( material.emissive ) {
M
Mr.doob 已提交
1984

1985
			uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );
M
Mr.doob 已提交
1986 1987 1988

		}

1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014
		if ( material.map ) {

			uniforms.map.value = material.map;

		}

		if ( material.alphaMap ) {

			uniforms.alphaMap.value = material.alphaMap;

		}

		if ( material.specularMap ) {

			uniforms.specularMap.value = material.specularMap;

		}

		if ( material.envMap ) {

			uniforms.envMap.value = material.envMap;

			// don't flip CubeTexture envMaps, flip everything else:
			//  WebGLRenderTargetCube will be flipped for backwards compatibility
			//  WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture
			// this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future
0
06wj 已提交
2015
			uniforms.flipEnvMap.value = material.envMap.isCubeTexture ? - 1 : 1;
2016 2017 2018 2019

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

2020
			uniforms.maxMipLevel.value = properties.get( material.envMap ).__maxMipLevel;
2021

2022
		}
M
Mr.doob 已提交
2023

2024 2025 2026 2027 2028 2029 2030
		if ( material.lightMap ) {

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

		}

2031
		if ( material.aoMap ) {
2032

2033 2034
			uniforms.aoMap.value = material.aoMap;
			uniforms.aoMapIntensity.value = material.aoMapIntensity;
2035 2036 2037

		}

M
Mr.doob 已提交
2038
		// uv repeat and offset setting priorities
M
Mr.doob 已提交
2039 2040 2041 2042 2043
		// 1. color map
		// 2. specular map
		// 3. normal map
		// 4. bump map
		// 5. alpha map
2044
		// 6. emissive map
M
Mr.doob 已提交
2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055

		var uvScaleMap;

		if ( material.map ) {

			uvScaleMap = material.map;

		} else if ( material.specularMap ) {

			uvScaleMap = material.specularMap;

2056 2057 2058 2059
		} else if ( material.displacementMap ) {

			uvScaleMap = material.displacementMap;

M
Mr.doob 已提交
2060 2061 2062 2063 2064 2065 2066 2067
		} else if ( material.normalMap ) {

			uvScaleMap = material.normalMap;

		} else if ( material.bumpMap ) {

			uvScaleMap = material.bumpMap;

2068 2069 2070 2071 2072 2073 2074 2075
		} else if ( material.roughnessMap ) {

			uvScaleMap = material.roughnessMap;

		} else if ( material.metalnessMap ) {

			uvScaleMap = material.metalnessMap;

2076 2077 2078 2079
		} else if ( material.alphaMap ) {

			uvScaleMap = material.alphaMap;

2080 2081 2082 2083
		} else if ( material.emissiveMap ) {

			uvScaleMap = material.emissiveMap;

M
Mr.doob 已提交
2084 2085 2086 2087
		}

		if ( uvScaleMap !== undefined ) {

2088
			// backwards compatibility
2089
			if ( uvScaleMap.isWebGLRenderTarget ) {
M
Mr.doob 已提交
2090 2091 2092 2093 2094

				uvScaleMap = uvScaleMap.texture;

			}

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

W
WestLangley 已提交
2097
				uvScaleMap.updateMatrix();
M
Mr.doob 已提交
2098

W
WestLangley 已提交
2099
			}
2100

2101
			uniforms.uvTransform.value.copy( uvScaleMap.matrix );
M
Mr.doob 已提交
2102 2103 2104

		}

M
Mr.doob 已提交
2105
	}
M
Mr.doob 已提交
2106

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

T
Takahiro 已提交
2109
		uniforms.diffuse.value.copy( material.color );
M
Mr.doob 已提交
2110 2111
		uniforms.opacity.value = material.opacity;

M
Mr.doob 已提交
2112
	}
M
Mr.doob 已提交
2113

M
Mr.doob 已提交
2114
	function refreshUniformsDash( uniforms, material ) {
M
Mr.doob 已提交
2115 2116 2117 2118 2119

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

M
Mr.doob 已提交
2120
	}
M
Mr.doob 已提交
2121

M
Mr.doob 已提交
2122
	function refreshUniformsPoints( uniforms, material ) {
M
Mr.doob 已提交
2123

T
Takahiro 已提交
2124
		uniforms.diffuse.value.copy( material.color );
M
Mr.doob 已提交
2125
		uniforms.opacity.value = material.opacity;
2126
		uniforms.size.value = material.size * _pixelRatio;
2127
		uniforms.scale.value = _height * 0.5;
M
Mr.doob 已提交
2128 2129 2130

		uniforms.map.value = material.map;

2131 2132
		if ( material.map !== null ) {

W
WestLangley 已提交
2133
			if ( material.map.matrixAutoUpdate === true ) {
2134

W
WestLangley 已提交
2135
				material.map.updateMatrix();
W
WestLangley 已提交
2136 2137

			}
2138

2139
			uniforms.uvTransform.value.copy( material.map.matrix );
2140 2141 2142

		}

2143 2144 2145 2146
	}

	function refreshUniformsSprites( uniforms, material ) {

T
Takahiro 已提交
2147
		uniforms.diffuse.value.copy( material.color );
2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163
		uniforms.opacity.value = material.opacity;
		uniforms.rotation.value = material.rotation;
		uniforms.map.value = material.map;

		if ( material.map !== null ) {

			if ( material.map.matrixAutoUpdate === true ) {

				material.map.updateMatrix();

			}

			uniforms.uvTransform.value.copy( material.map.matrix );

		}

M
Mr.doob 已提交
2164
	}
M
Mr.doob 已提交
2165

M
Mr.doob 已提交
2166
	function refreshUniformsFog( uniforms, fog ) {
M
Mr.doob 已提交
2167

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

2170
		if ( fog.isFog ) {
M
Mr.doob 已提交
2171 2172 2173 2174

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

2175
		} else if ( fog.isFogExp2 ) {
M
Mr.doob 已提交
2176 2177 2178 2179 2180

			uniforms.fogDensity.value = fog.density;

		}

M
Mr.doob 已提交
2181
	}
M
Mr.doob 已提交
2182

M
Mr.doob 已提交
2183
	function refreshUniformsLambert( uniforms, material ) {
2184 2185 2186 2187 2188 2189 2190 2191 2192

		if ( material.emissiveMap ) {

			uniforms.emissiveMap.value = material.emissiveMap;

		}

	}

M
Mr.doob 已提交
2193
	function refreshUniformsPhong( uniforms, material ) {
M
Mr.doob 已提交
2194

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

2198
		if ( material.emissiveMap ) {
2199

2200
			uniforms.emissiveMap.value = material.emissiveMap;
2201

2202
		}
M
Mr.doob 已提交
2203

2204 2205 2206 2207
		if ( material.bumpMap ) {

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

2210
		}
M
Mr.doob 已提交
2211

2212 2213 2214 2215
		if ( material.normalMap ) {

			uniforms.normalMap.value = material.normalMap;
			uniforms.normalScale.value.copy( material.normalScale );
2216
			if ( material.side === BackSide ) uniforms.normalScale.value.negate();
2217 2218

		}
M
Mr.doob 已提交
2219

2220 2221 2222 2223 2224
		if ( material.displacementMap ) {

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

2226
		}
2227

T
Takahiro 已提交
2228 2229 2230 2231 2232 2233
	}

	function refreshUniformsToon( uniforms, material ) {

		refreshUniformsPhong( uniforms, material );

T
Takahiro 已提交
2234
		if ( material.gradientMap ) {
T
Takahiro 已提交
2235

T
Takahiro 已提交
2236
			uniforms.gradientMap.value = material.gradientMap;
T
Takahiro 已提交
2237 2238 2239

		}

2240 2241
	}

M
Mr.doob 已提交
2242
	function refreshUniformsStandard( uniforms, material ) {
W
WestLangley 已提交
2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268

		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;
2269
			if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1;
W
WestLangley 已提交
2270 2271 2272 2273 2274 2275 2276

		}

		if ( material.normalMap ) {

			uniforms.normalMap.value = material.normalMap;
			uniforms.normalScale.value.copy( material.normalScale );
2277
			if ( material.side === BackSide ) uniforms.normalScale.value.negate();
W
WestLangley 已提交
2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297

		}

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

2300 2301 2302 2303
		refreshUniformsStandard( uniforms, material );

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

2304 2305 2306
		uniforms.clearCoat.value = material.clearCoat;
		uniforms.clearCoatRoughness.value = material.clearCoatRoughness;

W
WestLangley 已提交
2307 2308
	}

W
WestLangley 已提交
2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342
	function refreshUniformsMatcap( uniforms, material ) {

		if ( material.matcap ) {

			uniforms.matcap.value = material.matcap;

		}

		if ( material.bumpMap ) {

			uniforms.bumpMap.value = material.bumpMap;
			uniforms.bumpScale.value = material.bumpScale;
			if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1;

		}

		if ( material.normalMap ) {

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

		}

		if ( material.displacementMap ) {

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

		}

	}

W
WestLangley 已提交
2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370
	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;

	}

2371 2372 2373 2374 2375 2376
	function refreshUniformsNormal( uniforms, material ) {

		if ( material.bumpMap ) {

			uniforms.bumpMap.value = material.bumpMap;
			uniforms.bumpScale.value = material.bumpScale;
2377
			if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1;
2378 2379 2380 2381 2382 2383 2384

		}

		if ( material.normalMap ) {

			uniforms.normalMap.value = material.normalMap;
			uniforms.normalScale.value.copy( material.normalScale );
2385
			if ( material.side === BackSide ) uniforms.normalScale.value.negate();
2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398

		}

		if ( material.displacementMap ) {

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

		}

	}

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

M
Mr.doob 已提交
2401
	function markUniformsLightsNeedsUpdate( uniforms, value ) {
2402

M
Mr.doob 已提交
2403
		uniforms.ambientLightColor.needsUpdate = value;
W
WestLangley 已提交
2404
		uniforms.lightProbe.needsUpdate = value;
2405

B
Ben Houston 已提交
2406 2407 2408
		uniforms.directionalLights.needsUpdate = value;
		uniforms.pointLights.needsUpdate = value;
		uniforms.spotLights.needsUpdate = value;
2409
		uniforms.rectAreaLights.needsUpdate = value;
B
Ben Houston 已提交
2410
		uniforms.hemisphereLights.needsUpdate = value;
2411

M
Mr.doob 已提交
2412
	}
2413

2414 2415 2416
	//
	this.setFramebuffer = function ( value ) {

2417 2418
		if (_framebuffer !== value ) _gl.bindFramebuffer( _gl.FRAMEBUFFER, value );

2419 2420 2421 2422
		_framebuffer = value;

	};

2423
	this.getRenderTarget = function () {
2424 2425 2426

		return _currentRenderTarget;

M
Michael Herzog 已提交
2427
	};
2428

2429
	this.setRenderTarget = function ( renderTarget, activeCubeFace, activeMipMapLevel ) {
M
Mr.doob 已提交
2430

2431 2432
		_currentRenderTarget = renderTarget;

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

2435
			textures.setupRenderTarget( renderTarget );
M
Mr.doob 已提交
2436 2437 2438

		}

2439
		var framebuffer = _framebuffer;
M
Mr.doob 已提交
2440
		var isCube = false;
M
Mr.doob 已提交
2441 2442 2443

		if ( renderTarget ) {

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

M
Mr.doob 已提交
2446
			if ( renderTarget.isWebGLRenderTargetCube ) {
M
Mr.doob 已提交
2447

2448
				framebuffer = __webglFramebuffer[ activeCubeFace || 0 ];
M
Mr.doob 已提交
2449
				isCube = true;
M
Mr.doob 已提交
2450

2451 2452 2453 2454
			} else if ( renderTarget.isWebGLMultisampleRenderTarget ) {

				framebuffer = properties.get( renderTarget ).__webglMultisampledFramebuffer;

M
Mr.doob 已提交
2455 2456
			} else {

M
Mr.doob 已提交
2457
				framebuffer = __webglFramebuffer;
M
Mr.doob 已提交
2458 2459 2460

			}

M
Mr.doob 已提交
2461
			_currentViewport.copy( renderTarget.viewport );
2462 2463
			_currentScissor.copy( renderTarget.scissor );
			_currentScissorTest = renderTarget.scissorTest;
2464

M
Mr.doob 已提交
2465 2466
		} else {

M
Mr.doob 已提交
2467
			_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );
2468
			_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );
2469
			_currentScissorTest = _scissorTest;
2470

M
Mr.doob 已提交
2471 2472
		}

M
Mr.doob 已提交
2473
		if ( _currentFramebuffer !== framebuffer ) {
M
Mr.doob 已提交
2474 2475 2476 2477 2478 2479

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

		}

M
Mr.doob 已提交
2480
		state.viewport( _currentViewport );
2481 2482
		state.scissor( _currentScissor );
		state.setScissorTest( _currentScissorTest );
2483

M
Mr.doob 已提交
2484 2485 2486
		if ( isCube ) {

			var textureProperties = properties.get( renderTarget.texture );
2487
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + ( activeCubeFace || 0 ), textureProperties.__webglTexture, activeMipMapLevel || 0 );
M
Mr.doob 已提交
2488 2489 2490

		}

M
Mr.doob 已提交
2491 2492
	};

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

0
06wj 已提交
2495
		if ( ! ( renderTarget && renderTarget.isWebGLRenderTarget ) ) {
2496

2497
			console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
G
gero3 已提交
2498
			return;
2499

G
gero3 已提交
2500
		}
2501

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

2504
		if ( renderTarget.isWebGLRenderTargetCube && activeCubeFaceIndex !== undefined ) {
2505 2506 2507 2508 2509

			framebuffer = framebuffer[ activeCubeFaceIndex ];

		}

M
Mr.doob 已提交
2510
		if ( framebuffer ) {
2511

G
gero3 已提交
2512
			var restore = false;
2513

M
Mr.doob 已提交
2514
			if ( framebuffer !== _currentFramebuffer ) {
2515

M
Mr.doob 已提交
2516
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
2517

G
gero3 已提交
2518
				restore = true;
2519

G
gero3 已提交
2520
			}
2521

M
Mr.doob 已提交
2522
			try {
2523

M
Mr.doob 已提交
2524
				var texture = renderTarget.texture;
M
Mr.doob 已提交
2525 2526
				var textureFormat = texture.format;
				var textureType = texture.type;
2527

2528
				if ( textureFormat !== RGBAFormat && utils.convert( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {
2529

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

M
Mr.doob 已提交
2533
				}
2534

2535
				if ( textureType !== UnsignedByteType && utils.convert( textureType ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE ) && // IE11, Edge and Chrome Mac < 52 (#9513)
T
Takahiro 已提交
2536 2537
					! ( textureType === FloatType && ( capabilities.isWebGL2 || extensions.get( 'OES_texture_float' ) || extensions.get( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox
					! ( textureType === HalfFloatType && ( capabilities.isWebGL2 ? extensions.get( 'EXT_color_buffer_float' ) : extensions.get( 'EXT_color_buffer_half_float' ) ) ) ) {
2538

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

M
Mr.doob 已提交
2542
				}
2543

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

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

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

2550
						_gl.readPixels( x, y, width, height, utils.convert( textureFormat ), utils.convert( textureType ), buffer );
2551 2552

					}
2553

M
Mr.doob 已提交
2554
				} else {
M
Mr.doob 已提交
2555

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

				}
M
Mr.doob 已提交
2559

M
Mr.doob 已提交
2560
			} finally {
M
Mr.doob 已提交
2561

M
Mr.doob 已提交
2562 2563 2564
				if ( restore ) {

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

M
Mr.doob 已提交
2566 2567 2568
				}

			}
M
Mr.doob 已提交
2569 2570 2571

		}

M
Mr.doob 已提交
2572 2573
	};

2574
	this.copyFramebufferToTexture = function ( position, texture, level ) {
2575 2576 2577

		var width = texture.image.width;
		var height = texture.image.height;
2578
		var glFormat = utils.convert( texture.format );
2579

2580
		textures.setTexture2D( texture, 0 );
2581

2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592
		_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 );

2593
		textures.setTexture2D( dstTexture, 0 );
2594

2595 2596 2597 2598 2599 2600 2601 2602 2603
		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 );

		}
2604 2605 2606

	};

2607 2608 2609 2610 2611
	/*
	if ( typeof __THREE_DEVTOOLS__ !== undefined ) {
		__THREE_DEVTOOLS__.dispatchEvent( { type: 'renderer', value: this } );
	}
	*/
R
Rich Harris 已提交
2612

M
Mr.doob 已提交
2613
}
T
Tristan VALCKE 已提交
2614

2615
export { WebGLRenderer };