WebGLRenderer.js 59.5 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 19
import { UniformsLib } from './shaders/UniformsLib.js';
import { UniformsUtils } from './shaders/UniformsUtils.js';
M
Mr.doob 已提交
20 21
import { Vector3 } from '../math/Vector3.js';
import { Vector4 } from '../math/Vector4.js';
M
Mr.doob 已提交
22
import { WebGLAnimation } from './webgl/WebGLAnimation.js';
B
bentok 已提交
23 24 25
import { WebGLAttributes } from './webgl/WebGLAttributes.js';
import { WebGLBackground } from './webgl/WebGLBackground.js';
import { WebGLBufferRenderer } from './webgl/WebGLBufferRenderer.js';
M
Mr.doob 已提交
26 27 28
import { WebGLCapabilities } from './webgl/WebGLCapabilities.js';
import { WebGLClipping } from './webgl/WebGLClipping.js';
import { WebGLExtensions } from './webgl/WebGLExtensions.js';
B
bentok 已提交
29
import { WebGLGeometries } from './webgl/WebGLGeometries.js';
M
Mr.doob 已提交
30 31 32
import { WebGLIndexedBufferRenderer } from './webgl/WebGLIndexedBufferRenderer.js';
import { WebGLInfo } from './webgl/WebGLInfo.js';
import { WebGLMorphtargets } from './webgl/WebGLMorphtargets.js';
B
bentok 已提交
33 34 35
import { WebGLObjects } from './webgl/WebGLObjects.js';
import { WebGLPrograms } from './webgl/WebGLPrograms.js';
import { WebGLProperties } from './webgl/WebGLProperties.js';
M
Mr.doob 已提交
36 37 38
import { WebGLRenderLists } from './webgl/WebGLRenderLists.js';
import { WebGLRenderStates } from './webgl/WebGLRenderStates.js';
import { WebGLShadowMap } from './webgl/WebGLShadowMap.js';
B
bentok 已提交
39
import { WebGLState } from './webgl/WebGLState.js';
M
Mr.doob 已提交
40 41
import { WebGLTextures } from './webgl/WebGLTextures.js';
import { WebGLUniforms } from './webgl/WebGLUniforms.js';
B
bentok 已提交
42
import { WebGLUtils } from './webgl/WebGLUtils.js';
M
Mr.doob 已提交
43
import { WebVRManager } from './webvr/WebVRManager.js';
M
Mr.doob 已提交
44
import { WebXRManager } from './webvr/WebXRManager.js';
R
Rich Harris 已提交
45

M
Mr.doob 已提交
46 47 48 49 50
/**
 * @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 已提交
51
 * @author tschw
M
Mr.doob 已提交
52 53
 */

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

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

	parameters = parameters || {};

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

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

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

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

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

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

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

101 102
	// physical lights

103
	this.physicallyCorrectLights = false;
104

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

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

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

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

	// internal properties

	var _this = this,

120 121
		_isContextLost = false,

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

124 125
		_framebuffer = null,

126 127 128
		_currentRenderTarget = null,
		_currentFramebuffer = null,
		_currentMaterialId = - 1,
129 130 131 132 133 134 135 136

		// geometry and program caching

		_currentGeometryProgram = {
			geometryID: null,
			programID: null,
			wireframe: false
		},
137

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

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

145
		//
146

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

149
		//
M
Mr.doob 已提交
150

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

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

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

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

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

164
		// clipping
T
tschw 已提交
165

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

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

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

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

176 177 178 179 180
	function getTargetPixelRatio() {

		return _currentRenderTarget === null ? _pixelRatio : 1;

	}
181

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

	var _gl;

M
Mr.doob 已提交
186 187
	try {

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

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

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

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

		if ( _gl === null ) {

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

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

			} else {

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

			}
M
Mr.doob 已提交
216 217 218

		}

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

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

	}

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

241
	var background, morphtargets, bufferRenderer, indexedBufferRenderer;
242

243
	var utils;
244

245
	function initGLContext() {
246

247
		extensions = new WebGLExtensions( _gl );
248

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

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

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

		}

263
		extensions.get( 'OES_texture_float_linear' );
264

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

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

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

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

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

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

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

297
	}
M
Mr.doob 已提交
298

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

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

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

305
	this.vr = vr;
M
Mr.doob 已提交
306 307

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

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

311
	this.shadowMap = shadowMap;
M
Mr.doob 已提交
312

M
Mr.doob 已提交
313 314 315 316 317 318 319 320
	// API

	this.getContext = function () {

		return _gl;

	};

321 322 323 324 325 326
	this.getContextAttributes = function () {

		return _gl.getContextAttributes();

	};

327 328
	this.forceContextLoss = function () {

M
Michael Bond 已提交
329 330
		var extension = extensions.get( 'WEBGL_lose_context' );
		if ( extension ) extension.loseContext();
331 332 333

	};

334
	this.forceContextRestore = function () {
M
Mr.doob 已提交
335

336 337
		var extension = extensions.get( 'WEBGL_lose_context' );
		if ( extension ) extension.restoreContext();
M
Mr.doob 已提交
338 339 340

	};

341 342
	this.getPixelRatio = function () {

343
		return _pixelRatio;
344 345 346 347 348

	};

	this.setPixelRatio = function ( value ) {

349 350 351 352
		if ( value === undefined ) return;

		_pixelRatio = value;

M
Mr.doob 已提交
353
		this.setSize( _width, _height, false );
354 355 356

	};

357 358 359
	this.getSize = function () {

		return {
360 361
			width: _width,
			height: _height
362 363 364 365
		};

	};

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

M
Mr.doob 已提交
368
		if ( vr.isPresenting() ) {
369 370 371 372 373 374

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

		}

375 376 377
		_width = width;
		_height = height;

378 379
		_canvas.width = width * _pixelRatio;
		_canvas.height = height * _pixelRatio;
380

381
		if ( updateStyle !== false ) {
382

G
gero3 已提交
383 384
			_canvas.style.width = width + 'px';
			_canvas.style.height = height + 'px';
385

G
gero3 已提交
386
		}
M
Mr.doob 已提交
387

388
		this.setViewport( 0, 0, width, height );
M
Mr.doob 已提交
389 390 391

	};

M
Mr.doob 已提交
392 393 394 395 396 397 398 399 400
	this.getDrawingBufferSize = function () {

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

	};

401 402 403 404 405 406 407 408 409 410 411 412 413 414
	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 );

	};

415
	this.getCurrentViewport = function () {
M
Mugen87 已提交
416

417
		return _currentViewport;
M
Mugen87 已提交
418 419 420

	};

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

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

M
Mr.doob 已提交
426 427
	};

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

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

M
Mr.doob 已提交
433 434
	};

435 436
	this.setScissorTest = function ( boolean ) {

437
		state.setScissorTest( _scissorTest = boolean );
M
Mr.doob 已提交
438 439 440 441 442

	};

	// Clearing

M
Mr.doob 已提交
443
	this.getClearColor = function () {
M
Mr.doob 已提交
444

445
		return background.getClearColor();
M
Mr.doob 已提交
446 447 448

	};

449
	this.setClearColor = function () {
450

451
		background.setClearColor.apply( background, arguments );
M
Mr.doob 已提交
452 453 454

	};

M
Mr.doob 已提交
455
	this.getClearAlpha = function () {
M
Mr.doob 已提交
456

457
		return background.getClearAlpha();
M
Mr.doob 已提交
458 459 460

	};

M
Mugen87 已提交
461
	this.setClearAlpha = function () {
M
Mr.doob 已提交
462

463
		background.setClearAlpha.apply( background, arguments );
M
Mr.doob 已提交
464 465 466 467 468 469 470 471 472 473 474 475

	};

	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 );
476 477 478 479 480

	};

	this.clearColor = function () {

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

	};

	this.clearDepth = function () {

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

	};

	this.clearStencil = function () {

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

	};

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

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

	};

M
Mr.doob 已提交
504
	//
M
Mr.doob 已提交
505

M
Mr.doob 已提交
506
	this.dispose = function () {
D
dubejf 已提交
507 508

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

511
		renderLists.dispose();
512
		renderStates.dispose();
M
Mugen87 已提交
513 514
		properties.dispose();
		objects.dispose();
515

516
		vr.dispose();
517

518
		animation.stop();
B
brunnerh 已提交
519

D
dubejf 已提交
520 521
	};

M
Mr.doob 已提交
522
	// Events
M
Mr.doob 已提交
523

D
dubejf 已提交
524 525 526 527
	function onContextLost( event ) {

		event.preventDefault();

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

530 531 532 533
		_isContextLost = true;

	}

M
Mugen87 已提交
534
	function onContextRestore( /* event */ ) {
D
dubejf 已提交
535

536
		console.log( 'THREE.WebGLRenderer: Context Restored.' );
537 538

		_isContextLost = false;
D
dubejf 已提交
539

540
		initGLContext();
D
dubejf 已提交
541

M
Mr.doob 已提交
542
	}
D
dubejf 已提交
543

544
	function onMaterialDispose( event ) {
M
Mr.doob 已提交
545 546 547 548 549 550 551

		var material = event.target;

		material.removeEventListener( 'dispose', onMaterialDispose );

		deallocateMaterial( material );

552
	}
M
Mr.doob 已提交
553 554 555

	// Buffer deallocation

556
	function deallocateMaterial( material ) {
M
Mr.doob 已提交
557

558 559
		releaseMaterialProgramReference( material );

560
		properties.remove( material );
561

562
	}
563 564


565
	function releaseMaterialProgramReference( material ) {
566

567
		var programInfo = properties.get( material ).program;
M
Mr.doob 已提交
568 569 570

		material.program = undefined;

571
		if ( programInfo !== undefined ) {
M
Mr.doob 已提交
572

573
			programCache.releaseProgram( programInfo );
M
Mr.doob 已提交
574

M
Mr.doob 已提交
575 576
		}

577
	}
M
Mr.doob 已提交
578 579 580

	// Buffer rendering

M
Mr.doob 已提交
581
	function renderObjectImmediate( object, program ) {
M
Mr.doob 已提交
582 583 584

		object.render( function ( object ) {

M
Mr.doob 已提交
585
			_this.renderBufferImmediate( object, program );
M
Mr.doob 已提交
586 587 588 589 590

		} );

	}

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

593
		state.initAttributes();
594

595
		var buffers = properties.get( object );
596

597 598 599 600
		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 已提交
601

602
		var programAttributes = program.getAttributes();
603

M
Mr.doob 已提交
604 605
		if ( object.hasPositions ) {

606
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );
M
Mr.doob 已提交
607
			_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );
608

609 610
			state.enableAttribute( programAttributes.position );
			_gl.vertexAttribPointer( programAttributes.position, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
611 612 613 614 615

		}

		if ( object.hasNormals ) {

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

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

		}

624
		if ( object.hasUvs ) {
M
Mr.doob 已提交
625

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

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

		}

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

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

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

		}

644
		state.disableUnusedAttributes();
645

M
Mr.doob 已提交
646 647 648 649 650 651
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );

		object.count = 0;

	};

652
	this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {
653

654
		var frontFaceCW = ( object.isMesh && object.normalMatrix.determinant() < 0 );
655 656

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

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

M
Mr.doob 已提交
660
		var updateBuffers = false;
M
Mr.doob 已提交
661

662
		if ( geometry.id !== _currentGeometryProgram.geometryID || program.id !== _currentGeometryProgram.programID || material.wireframe !== _currentGeometryProgram.wireframe ) {
M
Mr.doob 已提交
663

664 665 666
			_currentGeometryProgram.geometryID = geometry.id;
			_currentGeometryProgram.programID = program.id;
			_currentGeometryProgram.wireframe = material.wireframe;
M
Mr.doob 已提交
667 668 669 670
			updateBuffers = true;

		}

671
		if ( object.morphTargetInfluences ) {
672

673
			morphtargets.update( object, geometry, material, program );
M
Mr.doob 已提交
674 675 676 677 678

			updateBuffers = true;

		}

679 680
		//

681
		var index = geometry.index;
682
		var position = geometry.attributes.position;
683
		var rangeFactor = 1;
684

685 686
		if ( material.wireframe === true ) {

687
			index = geometries.getWireframeAttribute( geometry );
688
			rangeFactor = 2;
689 690 691

		}

M
Mr.doob 已提交
692
		var attribute;
M
Mr.doob 已提交
693
		var renderer = bufferRenderer;
694

695
		if ( index !== null ) {
696

M
Mr.doob 已提交
697
			attribute = attributes.get( index );
698

699
			renderer = indexedBufferRenderer;
M
Mr.doob 已提交
700
			renderer.setIndex( attribute );
701

702
		}
M
Mr.doob 已提交
703

704
		if ( updateBuffers ) {
M
Mr.doob 已提交
705

706
			setupVertexAttributes( material, program, geometry );
M
Mr.doob 已提交
707

708
			if ( index !== null ) {
709

M
Mr.doob 已提交
710
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, attribute.buffer );
711 712 713

			}

714
		}
715

716 717
		//

718
		var dataCount = Infinity;
719

M
Mr.doob 已提交
720
		if ( index !== null ) {
721

M
Mr.doob 已提交
722
			dataCount = index.count;
723

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

M
Mr.doob 已提交
726
			dataCount = position.count;
727

M
Mr.doob 已提交
728
		}
729

M
Mr.doob 已提交
730 731
		var rangeStart = geometry.drawRange.start * rangeFactor;
		var rangeCount = geometry.drawRange.count * rangeFactor;
732

M
Mr.doob 已提交
733 734
		var groupStart = group !== null ? group.start * rangeFactor : 0;
		var groupCount = group !== null ? group.count * rangeFactor : Infinity;
735

M
Mr.doob 已提交
736
		var drawStart = Math.max( rangeStart, groupStart );
737
		var drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1;
M
Mr.doob 已提交
738 739 740

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

741 742
		if ( drawCount === 0 ) return;

M
Mr.doob 已提交
743
		//
744

745
		if ( object.isMesh ) {
746

747
			if ( material.wireframe === true ) {
748

749
				state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );
750
				renderer.setMode( _gl.LINES );
751

752
			} else {
M
Mr.doob 已提交
753 754

				switch ( object.drawMode ) {
755

R
Rich Harris 已提交
756
					case TrianglesDrawMode:
B
Ben Adams 已提交
757 758 759
						renderer.setMode( _gl.TRIANGLES );
						break;

R
Rich Harris 已提交
760
					case TriangleStripDrawMode:
B
Ben Adams 已提交
761 762 763
						renderer.setMode( _gl.TRIANGLE_STRIP );
						break;

R
Rich Harris 已提交
764
					case TriangleFanDrawMode:
B
Ben Adams 已提交
765 766 767 768
						renderer.setMode( _gl.TRIANGLE_FAN );
						break;

				}
769

770
			}
771

772

773
		} else if ( object.isLine ) {
774

775
			var lineWidth = material.linewidth;
776

777
			if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material
778

779
			state.setLineWidth( lineWidth * getTargetPixelRatio() );
780

781
			if ( object.isLineSegments ) {
782

783
				renderer.setMode( _gl.LINES );
784

785 786 787 788
			} else if ( object.isLineLoop ) {

				renderer.setMode( _gl.LINE_LOOP );

789
			} else {
790

791
				renderer.setMode( _gl.LINE_STRIP );
792 793

			}
M
Mr.doob 已提交
794

795
		} else if ( object.isPoints ) {
796 797

			renderer.setMode( _gl.POINTS );
798

799 800 801 802
		} else if ( object.isSprite ) {

			renderer.setMode( _gl.TRIANGLES );

803
		}
804

T
Takahiro 已提交
805
		if ( geometry && geometry.isInstancedBufferGeometry ) {
M
Mr.doob 已提交
806 807 808

			if ( geometry.maxInstancedCount > 0 ) {

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

J
jfranc 已提交
811
			}
812 813 814

		} else {

M
Mr.doob 已提交
815
			renderer.render( drawStart, drawCount );
816

M
Mr.doob 已提交
817 818 819 820
		}

	};

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

T
Takahiro 已提交
823
		if ( geometry && geometry.isInstancedBufferGeometry & ! capabilities.isWebGL2 ) {
B
Ben Adams 已提交
824

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

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

M
Mr.doob 已提交
830 831 832
			}

		}
B
Ben Adams 已提交
833

834 835
		state.initAttributes();

836
		var geometryAttributes = geometry.attributes;
837

838
		var programAttributes = program.getAttributes();
839

840
		var materialDefaultAttributeValues = material.defaultAttributeValues;
841

842
		for ( var name in programAttributes ) {
843

844
			var programAttribute = programAttributes[ name ];
M
Mr.doob 已提交
845

M
Mr.doob 已提交
846
			if ( programAttribute >= 0 ) {
M
Mr.doob 已提交
847

848
				var geometryAttribute = geometryAttributes[ name ];
849

M
Mr.doob 已提交
850
				if ( geometryAttribute !== undefined ) {
M
Mr.doob 已提交
851

852
					var normalized = geometryAttribute.normalized;
853
					var size = geometryAttribute.itemSize;
854

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

857 858 859 860
					// TODO Attribute may not be available on context restore

					if ( attribute === undefined ) continue;

M
Mr.doob 已提交
861 862 863
					var buffer = attribute.buffer;
					var type = attribute.type;
					var bytesPerElement = attribute.bytesPerElement;
864

A
aardgoose 已提交
865
					if ( geometryAttribute.isInterleavedBufferAttribute ) {
866

M
Mr.doob 已提交
867 868 869 870
						var data = geometryAttribute.data;
						var stride = data.stride;
						var offset = geometryAttribute.offset;

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

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

M
Mr.doob 已提交
875
							if ( geometry.maxInstancedCount === undefined ) {
876

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

M
Mr.doob 已提交
879
							}
B
Ben Adams 已提交
880

M
Mr.doob 已提交
881
						} else {
B
Ben Adams 已提交
882

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

M
Mr.doob 已提交
885
						}
B
Ben Adams 已提交
886

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

M
Mr.doob 已提交
890
					} else {
B
Ben Adams 已提交
891

A
aardgoose 已提交
892
						if ( geometryAttribute.isInstancedBufferAttribute ) {
B
Ben Adams 已提交
893

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

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

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

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

M
Mr.doob 已提交
902 903 904 905
						} else {

							state.enableAttribute( programAttribute );

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

M
Mr.doob 已提交
908
						_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
909
						_gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, 0 );
M
Mr.doob 已提交
910

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

913 914
				} else if ( materialDefaultAttributeValues !== undefined ) {

T
tschw 已提交
915
					var value = materialDefaultAttributeValues[ name ];
916

917
					if ( value !== undefined ) {
M
Mr.doob 已提交
918

919
						switch ( value.length ) {
M
Mr.doob 已提交
920

921 922 923
							case 2:
								_gl.vertexAttrib2fv( programAttribute, value );
								break;
M
Mr.doob 已提交
924

925 926 927
							case 3:
								_gl.vertexAttrib3fv( programAttribute, value );
								break;
M
Mr.doob 已提交
928

929 930 931
							case 4:
								_gl.vertexAttrib4fv( programAttribute, value );
								break;
932

933 934
							default:
								_gl.vertexAttrib1fv( programAttribute, value );
935 936

						}
M
Mr.doob 已提交
937 938 939 940 941 942 943 944

					}

				}

			}

		}
945

946
		state.disableUnusedAttributes();
947

M
Mr.doob 已提交
948 949
	}

M
Mr.doob 已提交
950
	// Compile
M
Mr.doob 已提交
951

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

M
Mr.doob 已提交
954
		currentRenderState = renderStates.get( scene, camera );
955
		currentRenderState.init();
956

M
Mr.doob 已提交
957
		scene.traverse( function ( object ) {
G
gero3 已提交
958 959

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

961
				currentRenderState.pushLight( object );
962 963 964

				if ( object.castShadow ) {

965
					currentRenderState.pushShadow( object );
966 967

				}
M
Mr.doob 已提交
968

G
gero3 已提交
969
			}
M
Mr.doob 已提交
970 971 972

		} );

973
		currentRenderState.setupLights( camera );
M
Mr.doob 已提交
974 975 976 977 978

		scene.traverse( function ( object ) {

			if ( object.material ) {

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

G
gero3 已提交
981
					for ( var i = 0; i < object.material.length; i ++ ) {
M
Mr.doob 已提交
982 983 984

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

G
gero3 已提交
985
					}
M
Mr.doob 已提交
986

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

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

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

G
gero3 已提交
993
			}
M
Mr.doob 已提交
994 995

		} );
G
gero3 已提交
996 997

	};
998

999
	// Animation Loop
M
Mr.doob 已提交
1000

M
Mr.doob 已提交
1001
	var onAnimationFrameCallback = null;
1002

1003
	function onAnimationFrame( time ) {
1004

M
Mr.doob 已提交
1005
		if ( vr.isPresenting() ) return;
1006
		if ( onAnimationFrameCallback ) onAnimationFrameCallback( time );
1007

1008
	}
1009

M
Mr.doob 已提交
1010 1011
	var animation = new WebGLAnimation();
	animation.setAnimationLoop( onAnimationFrame );
1012 1013

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

1015
	this.setAnimationLoop = function ( callback ) {
1016

M
Mr.doob 已提交
1017 1018
		onAnimationFrameCallback = callback;
		vr.setAnimationLoop( callback );
1019

1020 1021
		animation.start();

1022 1023
	};

M
Mr.doob 已提交
1024 1025 1026
	// Rendering

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

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

1030
			console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );
M
Mr.doob 已提交
1031 1032 1033 1034
			return;

		}

1035 1036
		if ( _isContextLost ) return;

M
Mr.doob 已提交
1037 1038
		// reset caching for this frame

1039 1040 1041
		_currentGeometryProgram.geometryID = null;
		_currentGeometryProgram.programID = null;
		_currentGeometryProgram.wireframe = false;
1042
		_currentMaterialId = - 1;
1043
		_currentCamera = null;
M
Mr.doob 已提交
1044 1045 1046

		// update scene graph

1047
		if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
M
Mr.doob 已提交
1048 1049 1050

		// update camera matrices and frustum

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

1053 1054 1055 1056 1057 1058
		if ( vr.enabled ) {

			camera = vr.getCamera( camera );

		}

1059 1060
		//

1061 1062
		currentRenderState = renderStates.get( scene, camera );
		currentRenderState.init();
1063

1064 1065
		scene.onBeforeRender( _this, scene, camera, renderTarget );

M
Mr.doob 已提交
1066 1067 1068
		_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
		_frustum.setFromMatrix( _projScreenMatrix );

T
tschw 已提交
1069
		_localClippingEnabled = this.localClippingEnabled;
M
Mr.doob 已提交
1070
		_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );
T
tschw 已提交
1071

1072 1073 1074
		currentRenderList = renderLists.get( scene, camera );
		currentRenderList.init();

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

M
Mr.doob 已提交
1077
		if ( _this.sortObjects === true ) {
1078

1079
			currentRenderList.sort();
M
Mr.doob 已提交
1080

1081 1082
		}

M
Mr.doob 已提交
1083
		//
M
Mr.doob 已提交
1084

T
tschw 已提交
1085
		if ( _clippingEnabled ) _clipping.beginShadows();
T
tschw 已提交
1086

1087
		var shadowsArray = currentRenderState.state.shadowsArray;
1088

1089
		shadowMap.render( shadowsArray, scene, camera );
1090

1091
		currentRenderState.setupLights( camera );
1092

T
tschw 已提交
1093
		if ( _clippingEnabled ) _clipping.endShadows();
T
tschw 已提交
1094

M
Mr.doob 已提交
1095 1096
		//

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

1099 1100 1101 1102 1103 1104
		if ( renderTarget === undefined ) {

			renderTarget = null;

		}

M
Mr.doob 已提交
1105 1106
		this.setRenderTarget( renderTarget );

M
Mr.doob 已提交
1107 1108
		//

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

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

1113 1114 1115
		var opaqueObjects = currentRenderList.opaque;
		var transparentObjects = currentRenderList.transparent;

M
Mr.doob 已提交
1116 1117
		if ( scene.overrideMaterial ) {

1118
			var overrideMaterial = scene.overrideMaterial;
M
Mr.doob 已提交
1119

M
Mr.doob 已提交
1120 1121
			if ( opaqueObjects.length ) renderObjects( opaqueObjects, scene, camera, overrideMaterial );
			if ( transparentObjects.length ) renderObjects( transparentObjects, scene, camera, overrideMaterial );
1122

M
Mr.doob 已提交
1123 1124 1125 1126
		} else {

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

M
Mr.doob 已提交
1127
			if ( opaqueObjects.length ) renderObjects( opaqueObjects, scene, camera );
M
Mr.doob 已提交
1128 1129 1130

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

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

1133
		}
M
Mr.doob 已提交
1134 1135 1136

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

M
Mr.doob 已提交
1137 1138
		if ( renderTarget ) {

1139
			textures.updateRenderTargetMipmap( renderTarget );
M
Mr.doob 已提交
1140 1141 1142

		}

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

1145 1146 1147
		state.buffers.depth.setTest( true );
		state.buffers.depth.setMask( true );
		state.buffers.color.setMask( true );
M
Mr.doob 已提交
1148

1149
		state.setPolygonOffset( false );
1150

1151
		scene.onAfterRender( _this, scene, camera );
1152

M
Mr.doob 已提交
1153
		if ( vr.enabled ) {
1154

M
Mr.doob 已提交
1155
			vr.submitFrame();
1156

M
Mr.doob 已提交
1157
		}
M
Mr.doob 已提交
1158

M
Mr.doob 已提交
1159 1160
		// _gl.finish();

1161
		currentRenderList = null;
1162
		currentRenderState = null;
1163

M
Mr.doob 已提交
1164
	};
M
Mr.doob 已提交
1165

1166
	/*
M
Mr.doob 已提交
1167 1168
	// TODO Duplicated code (Frustum)

1169 1170
	var _sphere = new Sphere();

T
tschw 已提交
1171 1172 1173 1174 1175 1176 1177
	function isObjectViewable( object ) {

		var geometry = object.geometry;

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

M
Mr.doob 已提交
1178
		_sphere.copy( geometry.boundingSphere ).
1179
		applyMatrix4( object.matrixWorld );
M
Mr.doob 已提交
1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195

		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 已提交
1196 1197

		if ( ! _frustum.intersectsSphere( sphere ) ) return false;
T
tschw 已提交
1198 1199 1200 1201

		var numPlanes = _clipping.numPlanes;

		if ( numPlanes === 0 ) return true;
T
tschw 已提交
1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213

		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 已提交
1214
		} while ( ++ i !== numPlanes );
T
tschw 已提交
1215 1216 1217 1218

		return true;

	}
1219
	*/
T
tschw 已提交
1220

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

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

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

1227
		if ( visible ) {
1228

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

1231
				currentRenderState.pushLight( object );
1232 1233 1234

				if ( object.castShadow ) {

1235
					currentRenderState.pushShadow( object );
1236 1237

				}
M
Mr.doob 已提交
1238

1239
			} else if ( object.isSprite ) {
M
Mr.doob 已提交
1240

1241
				if ( ! object.frustumCulled || _frustum.intersectsSprite( object ) ) {
1242

1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253
					if ( sortObjects ) {

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

					}

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

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

1255
				}
M
Mr.doob 已提交
1256

1257
			} else if ( object.isImmediateRenderObject ) {
M
Mr.doob 已提交
1258

1259
				if ( sortObjects ) {
M
Mr.doob 已提交
1260

1261 1262
					_vector3.setFromMatrixPosition( object.matrixWorld )
						.applyMatrix4( _projScreenMatrix );
M
Mr.doob 已提交
1263

1264
				}
M
Mr.doob 已提交
1265

1266
				currentRenderList.push( object, null, object.material, _vector3.z, null );
1267

1268
			} else if ( object.isMesh || object.isLine || object.isPoints ) {
1269

1270
				if ( object.isSkinnedMesh ) {
1271

1272
					object.skeleton.update();
1273

1274
				}
1275

1276
				if ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) {
1277

1278 1279 1280 1281 1282 1283
					if ( sortObjects ) {

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

					}
1284

1285 1286
					var geometry = objects.update( object );
					var material = object.material;
1287

1288
					if ( Array.isArray( material ) ) {
1289

1290
						var groups = geometry.groups;
1291

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

1294 1295
							var group = groups[ i ];
							var groupMaterial = material[ group.materialIndex ];
1296

1297
							if ( groupMaterial && groupMaterial.visible ) {
1298

1299 1300 1301
								currentRenderList.push( object, geometry, groupMaterial, _vector3.z, group );

							}
M
Mr.doob 已提交
1302

M
Mr.doob 已提交
1303
						}
M
Mr.doob 已提交
1304

1305
					} else if ( material.visible ) {
1306

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

1309
					}
M
Mr.doob 已提交
1310

1311
				}
M
Mr.doob 已提交
1312

1313
			}
M
Mr.doob 已提交
1314

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

M
Mr.doob 已提交
1317
		var children = object.children;
M
Mr.doob 已提交
1318

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

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

1323
		}
1324

1325
	}
M
Mr.doob 已提交
1326

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

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

1331
			var renderItem = renderList[ i ];
M
Mr.doob 已提交
1332

1333
			var object = renderItem.object;
M
Mr.doob 已提交
1334 1335 1336
			var geometry = renderItem.geometry;
			var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;
			var group = renderItem.group;
M
Mr.doob 已提交
1337

M
Mr.doob 已提交
1338
			if ( camera.isArrayCamera ) {
M
Mr.doob 已提交
1339

1340 1341
				_currentArrayCamera = camera;

M
Mr.doob 已提交
1342
				var cameras = camera.cameras;
M
Mr.doob 已提交
1343

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

M
Mr.doob 已提交
1346
					var camera2 = cameras[ j ];
M
Mr.doob 已提交
1347

1348
					if ( object.layers.test( camera2.layers ) ) {
1349

M
Mr.doob 已提交
1350 1351 1352 1353 1354 1355 1356
						if ( 'viewport' in camera2 ) { // XR

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

						} else {

							var bounds = camera2.bounds;
1357

M
Mr.doob 已提交
1358 1359 1360 1361
							var x = bounds.x * _width;
							var y = bounds.y * _height;
							var width = bounds.z * _width;
							var height = bounds.w * _height;
M
Mr.doob 已提交
1362

M
Mr.doob 已提交
1363 1364 1365
							state.viewport( _currentViewport.set( x, y, width, height ).multiplyScalar( _pixelRatio ) );

						}
1366 1367 1368 1369

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

					}
M
Mr.doob 已提交
1370

M
Mr.doob 已提交
1371
				}
1372

M
Mr.doob 已提交
1373
			} else {
M
Mr.doob 已提交
1374

1375 1376
				_currentArrayCamera = null;

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

M
Mr.doob 已提交
1379
			}
M
Mr.doob 已提交
1380

1381
		}
M
Mr.doob 已提交
1382

1383
	}
G
gero3 已提交
1384

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

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

M
Mr.doob 已提交
1390 1391 1392 1393 1394
		object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
		object.normalMatrix.getNormalMatrix( object.modelViewMatrix );

		if ( object.isImmediateRenderObject ) {

1395
			state.setMaterial( material );
M
Mr.doob 已提交
1396 1397 1398

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

1399 1400 1401
			_currentGeometryProgram.geometryID = null;
			_currentGeometryProgram.programID = null;
			_currentGeometryProgram.wireframe = false;
M
Mr.doob 已提交
1402

M
Mr.doob 已提交
1403
			renderObjectImmediate( object, program );
M
Mr.doob 已提交
1404 1405 1406

		} else {

M
Mugen87 已提交
1407
			_this.renderBufferDirect( camera, scene.fog, geometry, material, object, group );
M
Mr.doob 已提交
1408 1409 1410

		}

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

M
Mr.doob 已提交
1414 1415
	}

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

1418
		var materialProperties = properties.get( material );
G
gero3 已提交
1419

1420 1421
		var lights = currentRenderState.state.lights;
		var shadowsArray = currentRenderState.state.shadowsArray;
1422

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

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

1428
		var program = materialProperties.program;
T
tschw 已提交
1429
		var programChange = true;
1430

1431
		if ( program === undefined ) {
B
Ben Adams 已提交
1432

M
Mr.doob 已提交
1433 1434
			// new material
			material.addEventListener( 'dispose', onMaterialDispose );
B
Ben Adams 已提交
1435

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

M
Mr.doob 已提交
1438
			// changed glsl or parameters
1439
			releaseMaterialProgramReference( material );
B
Ben Adams 已提交
1440

1441 1442 1443 1444 1445
		} else if ( materialProperties.lightsHash !== lights.state.hash ) {

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

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

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

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

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

		}

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

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

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

1464
				materialProperties.shader = {
1465
					name: material.type,
1466
					uniforms: UniformsUtils.clone( shader.uniforms ),
1467
					vertexShader: shader.vertexShader,
1468
					fragmentShader: shader.fragmentShader
1469
				};
B
Ben Adams 已提交
1470

1471
			} else {
B
Ben Adams 已提交
1472

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

1480
			}
G
gero3 已提交
1481

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

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

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

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

		}

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

		if ( material.morphTargets ) {

			material.numSupportedMorphTargets = 0;

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

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

					material.numSupportedMorphTargets ++;

				}

			}

		}

		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

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

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

					material.numSupportedMorphNormals ++;

				}

			}

		}

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

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

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

		}

1540
		materialProperties.fog = fog;
1541

1542
		// store the light setup it was created for
1543

1544
		materialProperties.lightsHash = lights.state.hash;
1545

M
Mr.doob 已提交
1546
		if ( material.lights ) {
1547 1548 1549

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

1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562
			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;
1563
			// TODO (abelnation): add area lights shadow info to uniforms
1564

1565 1566
		}

T
tschw 已提交
1567 1568
		var progUniforms = materialProperties.program.getUniforms(),
			uniformsList =
1569
				WebGLUniforms.seqWithValue( progUniforms.seq, uniforms );
A
arose 已提交
1570

T
tschw 已提交
1571
		materialProperties.uniformsList = uniformsList;
A
arose 已提交
1572

M
Mr.doob 已提交
1573
	}
M
Mr.doob 已提交
1574

1575
	function setProgram( camera, fog, material, object ) {
M
Mr.doob 已提交
1576 1577 1578

		_usedTextureUnits = 0;

1579
		var materialProperties = properties.get( material );
1580
		var lights = currentRenderState.state.lights;
1581

T
tschw 已提交
1582 1583 1584 1585 1586
		if ( _clippingEnabled ) {

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

				var useCache =
1587 1588
					camera === _currentCamera &&
					material.id === _currentMaterialId;
T
tschw 已提交
1589 1590 1591 1592

				// we might want to call this function with some ClippingGroup
				// object instead of the material, once it becomes feasible
				// (#8465, #8379)
T
tschw 已提交
1593
				_clipping.setState(
1594 1595
					material.clippingPlanes, material.clipIntersection, material.clipShadows,
					camera, materialProperties, useCache );
T
tschw 已提交
1596 1597 1598 1599 1600

			}

		}

1601
		if ( material.needsUpdate === false ) {
1602

1603
			if ( materialProperties.program === undefined ) {
1604

1605
				material.needsUpdate = true;
1606

1607
			} else if ( material.fog && materialProperties.fog !== fog ) {
1608

M
Mr.doob 已提交
1609
				material.needsUpdate = true;
1610

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

1613
				material.needsUpdate = true;
1614

1615
			} else if ( materialProperties.numClippingPlanes !== undefined &&
1616
				( materialProperties.numClippingPlanes !== _clipping.numPlanes ||
M
Mr.doob 已提交
1617
				materialProperties.numIntersection !== _clipping.numIntersection ) ) {
1618 1619 1620

				material.needsUpdate = true;

1621
			}
1622 1623 1624 1625

		}

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

1627
			initMaterial( material, fog, object );
M
Mr.doob 已提交
1628 1629 1630 1631
			material.needsUpdate = false;

		}

1632
		var refreshProgram = false;
M
Mr.doob 已提交
1633
		var refreshMaterial = false;
1634
		var refreshLights = false;
M
Mr.doob 已提交
1635

1636
		var program = materialProperties.program,
1637
			p_uniforms = program.getUniforms(),
1638
			m_uniforms = materialProperties.shader.uniforms;
M
Mr.doob 已提交
1639

1640
		if ( state.useProgram( program.program ) ) {
M
Mr.doob 已提交
1641

1642
			refreshProgram = true;
M
Mr.doob 已提交
1643
			refreshMaterial = true;
1644
			refreshLights = true;
M
Mr.doob 已提交
1645 1646 1647 1648 1649 1650

		}

		if ( material.id !== _currentMaterialId ) {

			_currentMaterialId = material.id;
1651

M
Mr.doob 已提交
1652 1653 1654 1655
			refreshMaterial = true;

		}

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

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

G
gero3 已提交
1660
			if ( capabilities.logarithmicDepthBuffer ) {
1661

T
tschw 已提交
1662
				p_uniforms.setValue( _gl, 'logDepthBufFC',
1663
					2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
1664 1665 1666

			}

1667
			// Avoid unneeded uniform updates per ArrayCamera's sub-camera
1668

1669
			if ( _currentCamera !== ( _currentArrayCamera || camera ) ) {
1670

1671
				_currentCamera = ( _currentArrayCamera || camera );
1672 1673 1674 1675 1676 1677

				// 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 已提交
1678
				refreshLights = true;		// remains set until update done
1679 1680

			}
M
Mr.doob 已提交
1681

1682 1683 1684
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)

1685
			if ( material.isShaderMaterial ||
1686 1687 1688
				material.isMeshPhongMaterial ||
				material.isMeshStandardMaterial ||
				material.envMap ) {
1689

T
tschw 已提交
1690 1691 1692
				var uCamPos = p_uniforms.map.cameraPosition;

				if ( uCamPos !== undefined ) {
1693

T
tschw 已提交
1694
					uCamPos.setValue( _gl,
1695
						_vector3.setFromMatrixPosition( camera.matrixWorld ) );
1696 1697 1698 1699 1700

				}

			}

1701
			if ( material.isMeshPhongMaterial ||
1702 1703 1704 1705
				material.isMeshLambertMaterial ||
				material.isMeshBasicMaterial ||
				material.isMeshStandardMaterial ||
				material.isShaderMaterial ||
1706
				material.skinning ) {
1707

T
tschw 已提交
1708
				p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );
1709 1710 1711

			}

M
Mr.doob 已提交
1712 1713 1714 1715 1716 1717
		}

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

1718
		if ( material.skinning ) {
M
Mr.doob 已提交
1719

T
tschw 已提交
1720 1721
			p_uniforms.setOptional( _gl, object, 'bindMatrix' );
			p_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );
1722

T
tschw 已提交
1723
			var skeleton = object.skeleton;
1724

T
tschw 已提交
1725
			if ( skeleton ) {
1726

1727 1728
				var bones = skeleton.bones;

1729
				if ( capabilities.floatVertexTextures ) {
M
Mr.doob 已提交
1730

1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741
					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
1742
						size = _Math.ceilPowerOfTwo( size );
1743 1744 1745 1746 1747 1748
						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 );
1749
						boneTexture.needsUpdate = true;
1750 1751 1752 1753 1754 1755 1756

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

					}

M
Mr.doob 已提交
1757 1758
					p_uniforms.setValue( _gl, 'boneTexture', skeleton.boneTexture );
					p_uniforms.setValue( _gl, 'boneTextureSize', skeleton.boneTextureSize );
M
Mr.doob 已提交
1759

T
tschw 已提交
1760
				} else {
M
Mr.doob 已提交
1761

T
tschw 已提交
1762
					p_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );
M
Mr.doob 已提交
1763 1764 1765 1766 1767 1768 1769 1770 1771

				}

			}

		}

		if ( refreshMaterial ) {

1772 1773 1774
			p_uniforms.setValue( _gl, 'toneMappingExposure', _this.toneMappingExposure );
			p_uniforms.setValue( _gl, 'toneMappingWhitePoint', _this.toneMappingWhitePoint );

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

1777
				// the current material requires lighting info
M
Mr.doob 已提交
1778

T
tschw 已提交
1779 1780 1781 1782 1783 1784
				// 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 已提交
1785

T
tschw 已提交
1786
				markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
G
gero3 已提交
1787

T
tschw 已提交
1788
			}
G
gero3 已提交
1789

T
tschw 已提交
1790
			// refresh uniforms common to several materials
G
gero3 已提交
1791

T
tschw 已提交
1792
			if ( fog && material.fog ) {
G
gero3 已提交
1793

T
tschw 已提交
1794
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
1795 1796 1797

			}

1798
			if ( material.isMeshBasicMaterial ) {
M
Mr.doob 已提交
1799 1800 1801

				refreshUniformsCommon( m_uniforms, material );

1802
			} else if ( material.isMeshLambertMaterial ) {
M
Mr.doob 已提交
1803

1804 1805
				refreshUniformsCommon( m_uniforms, material );
				refreshUniformsLambert( m_uniforms, material );
M
Mr.doob 已提交
1806

1807
			} else if ( material.isMeshPhongMaterial ) {
M
Mr.doob 已提交
1808

1809
				refreshUniformsCommon( m_uniforms, material );
M
Mr.doob 已提交
1810

1811
				if ( material.isMeshToonMaterial ) {
M
Mr.doob 已提交
1812

1813
					refreshUniformsToon( m_uniforms, material );
M
Mr.doob 已提交
1814

1815
				} else {
1816

1817
					refreshUniformsPhong( m_uniforms, material );
1818

1819
				}
T
Takahiro 已提交
1820

1821
			} else if ( material.isMeshStandardMaterial ) {
T
Takahiro 已提交
1822

1823
				refreshUniformsCommon( m_uniforms, material );
1824

1825
				if ( material.isMeshPhysicalMaterial ) {
1826

1827
					refreshUniformsPhysical( m_uniforms, material );
W
WestLangley 已提交
1828

1829
				} else {
W
WestLangley 已提交
1830

1831
					refreshUniformsStandard( m_uniforms, material );
W
WestLangley 已提交
1832

1833
				}
W
WestLangley 已提交
1834

1835
			} else if ( material.isMeshDepthMaterial ) {
M
Mr.doob 已提交
1836

1837
				refreshUniformsCommon( m_uniforms, material );
W
WestLangley 已提交
1838
				refreshUniformsDepth( m_uniforms, material );
1839

W
WestLangley 已提交
1840
			} else if ( material.isMeshDistanceMaterial ) {
1841

1842
				refreshUniformsCommon( m_uniforms, material );
W
WestLangley 已提交
1843
				refreshUniformsDistance( m_uniforms, material );
1844

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

1847
				refreshUniformsCommon( m_uniforms, material );
1848
				refreshUniformsNormal( m_uniforms, material );
M
Mr.doob 已提交
1849

1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863
			} else if ( material.isLineBasicMaterial ) {

				refreshUniformsLine( m_uniforms, material );

				if ( material.isLineDashedMaterial ) {

					refreshUniformsDash( m_uniforms, material );

				}

			} else if ( material.isPointsMaterial ) {

				refreshUniformsPoints( m_uniforms, material );

1864 1865 1866 1867
			} else if ( material.isSpriteMaterial ) {

				refreshUniformsSprites( m_uniforms, material );

1868 1869 1870 1871 1872
			} else if ( material.isShadowMaterial ) {

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

M
Mr.doob 已提交
1873 1874
			}

M
Mr.doob 已提交
1875 1876 1877
			// RectAreaLight Texture
			// TODO (mrdoob): Find a nicer implementation

1878 1879
			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 已提交
1880

1881
			WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, _this );
A
arose 已提交
1882 1883 1884

		}

1885 1886 1887 1888 1889 1890
		if ( material.isShaderMaterial && material.uniformsNeedUpdate === true ) {

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

		}
M
Mr.doob 已提交
1891

1892 1893 1894 1895 1896 1897
		if ( material.isSpriteMaterial ) {

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

		}

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

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

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

	}

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

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

		uniforms.opacity.value = material.opacity;

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

			uniforms.diffuse.value = material.color;

		}
M
Mr.doob 已提交
1919

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

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

		}

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

			uniforms.map.value = material.map;

		}

		if ( material.alphaMap ) {

			uniforms.alphaMap.value = material.alphaMap;

		}

		if ( material.specularMap ) {

			uniforms.specularMap.value = material.specularMap;

		}

		if ( material.envMap ) {

			uniforms.envMap.value = material.envMap;

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

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

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

1959
		}
M
Mr.doob 已提交
1960

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

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

		}

1968
		if ( material.aoMap ) {
1969

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

		}

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

		var uvScaleMap;

		if ( material.map ) {

			uvScaleMap = material.map;

		} else if ( material.specularMap ) {

			uvScaleMap = material.specularMap;

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

			uvScaleMap = material.displacementMap;

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

			uvScaleMap = material.normalMap;

		} else if ( material.bumpMap ) {

			uvScaleMap = material.bumpMap;

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

			uvScaleMap = material.roughnessMap;

		} else if ( material.metalnessMap ) {

			uvScaleMap = material.metalnessMap;

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

			uvScaleMap = material.alphaMap;

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

			uvScaleMap = material.emissiveMap;

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

		if ( uvScaleMap !== undefined ) {

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

				uvScaleMap = uvScaleMap.texture;

			}

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

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

W
WestLangley 已提交
2036
			}
2037

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

		}

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

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

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

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

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

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

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

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

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

		uniforms.map.value = material.map;

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

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

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

			}
2075

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

		}

2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100
	}

	function refreshUniformsSprites( uniforms, material ) {

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

		if ( material.map !== null ) {

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

				material.map.updateMatrix();

			}

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

		}

M
Mr.doob 已提交
2101
	}
M
Mr.doob 已提交
2102

M
Mr.doob 已提交
2103
	function refreshUniformsFog( uniforms, fog ) {
M
Mr.doob 已提交
2104 2105 2106

		uniforms.fogColor.value = fog.color;

2107
		if ( fog.isFog ) {
M
Mr.doob 已提交
2108 2109 2110 2111

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

2112
		} else if ( fog.isFogExp2 ) {
M
Mr.doob 已提交
2113 2114 2115 2116 2117

			uniforms.fogDensity.value = fog.density;

		}

M
Mr.doob 已提交
2118
	}
M
Mr.doob 已提交
2119

M
Mr.doob 已提交
2120
	function refreshUniformsLambert( uniforms, material ) {
2121 2122 2123 2124 2125 2126 2127 2128 2129

		if ( material.emissiveMap ) {

			uniforms.emissiveMap.value = material.emissiveMap;

		}

	}

M
Mr.doob 已提交
2130
	function refreshUniformsPhong( uniforms, material ) {
M
Mr.doob 已提交
2131

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

2135
		if ( material.emissiveMap ) {
2136

2137
			uniforms.emissiveMap.value = material.emissiveMap;
2138

2139
		}
M
Mr.doob 已提交
2140

2141 2142 2143 2144
		if ( material.bumpMap ) {

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

2147
		}
M
Mr.doob 已提交
2148

2149 2150 2151 2152
		if ( material.normalMap ) {

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

		}
M
Mr.doob 已提交
2156

2157 2158 2159 2160 2161
		if ( material.displacementMap ) {

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

2163
		}
2164

T
Takahiro 已提交
2165 2166 2167 2168 2169 2170
	}

	function refreshUniformsToon( uniforms, material ) {

		refreshUniformsPhong( uniforms, material );

T
Takahiro 已提交
2171
		if ( material.gradientMap ) {
T
Takahiro 已提交
2172

T
Takahiro 已提交
2173
			uniforms.gradientMap.value = material.gradientMap;
T
Takahiro 已提交
2174 2175 2176

		}

2177 2178
	}

M
Mr.doob 已提交
2179
	function refreshUniformsStandard( uniforms, material ) {
W
WestLangley 已提交
2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205

		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;
2206
			if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1;
W
WestLangley 已提交
2207 2208 2209 2210 2211 2212 2213

		}

		if ( material.normalMap ) {

			uniforms.normalMap.value = material.normalMap;
			uniforms.normalScale.value.copy( material.normalScale );
2214
			if ( material.side === BackSide ) uniforms.normalScale.value.negate();
W
WestLangley 已提交
2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234

		}

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

2237 2238 2239 2240
		refreshUniformsStandard( uniforms, material );

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

2241 2242 2243
		uniforms.clearCoat.value = material.clearCoat;
		uniforms.clearCoatRoughness.value = material.clearCoatRoughness;

W
WestLangley 已提交
2244 2245
	}

W
WestLangley 已提交
2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273
	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;

	}

2274 2275 2276 2277 2278 2279
	function refreshUniformsNormal( uniforms, material ) {

		if ( material.bumpMap ) {

			uniforms.bumpMap.value = material.bumpMap;
			uniforms.bumpScale.value = material.bumpScale;
2280
			if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1;
2281 2282 2283 2284 2285 2286 2287

		}

		if ( material.normalMap ) {

			uniforms.normalMap.value = material.normalMap;
			uniforms.normalScale.value.copy( material.normalScale );
2288
			if ( material.side === BackSide ) uniforms.normalScale.value.negate();
2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301

		}

		if ( material.displacementMap ) {

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

		}

	}

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

M
Mr.doob 已提交
2304
	function markUniformsLightsNeedsUpdate( uniforms, value ) {
2305

M
Mr.doob 已提交
2306
		uniforms.ambientLightColor.needsUpdate = value;
2307

B
Ben Houston 已提交
2308 2309 2310
		uniforms.directionalLights.needsUpdate = value;
		uniforms.pointLights.needsUpdate = value;
		uniforms.spotLights.needsUpdate = value;
2311
		uniforms.rectAreaLights.needsUpdate = value;
B
Ben Houston 已提交
2312
		uniforms.hemisphereLights.needsUpdate = value;
2313

M
Mr.doob 已提交
2314
	}
2315

M
Mr.doob 已提交
2316 2317
	// Textures

T
tschw 已提交
2318 2319 2320 2321 2322 2323
	function allocTextureUnit() {

		var textureUnit = _usedTextureUnits;

		if ( textureUnit >= capabilities.maxTextures ) {

M
Mugen87 已提交
2324
			console.warn( 'THREE.WebGLRenderer: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );
T
tschw 已提交
2325 2326 2327 2328 2329 2330 2331 2332 2333

		}

		_usedTextureUnits += 1;

		return textureUnit;

	}

2334
	this.allocTextureUnit = allocTextureUnit;
T
tschw 已提交
2335

2336
	// this.setTexture2D = setTexture2D;
M
Mr.doob 已提交
2337
	this.setTexture2D = ( function () {
T
tschw 已提交
2338

2339
		var warned = false;
T
tschw 已提交
2340

2341
		// backwards compatibility: peel texture.texture
W
WestLangley 已提交
2342
		return function setTexture2D( texture, slot ) {
T
tschw 已提交
2343

T
Takahiro 已提交
2344
			if ( texture && texture.isWebGLRenderTarget ) {
T
tschw 已提交
2345

2346
				if ( ! warned ) {
T
tschw 已提交
2347

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

2351
				}
T
tschw 已提交
2352

2353
				texture = texture.texture;
T
tschw 已提交
2354

2355
			}
T
tschw 已提交
2356

2357
			textures.setTexture2D( texture, slot );
T
tschw 已提交
2358

2359
		};
T
tschw 已提交
2360

2361
	}() );
T
tschw 已提交
2362

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

		var warned = false;

W
WestLangley 已提交
2367
		return function setTexture( texture, slot ) {
2368 2369 2370 2371 2372 2373 2374 2375

			if ( ! warned ) {

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

			}

2376
			textures.setTexture2D( texture, slot );
2377 2378 2379 2380 2381

		};

	}() );

M
Mr.doob 已提交
2382
	this.setTextureCube = ( function () {
2383 2384 2385

		var warned = false;

W
WestLangley 已提交
2386
		return function setTextureCube( texture, slot ) {
2387 2388

			// backwards compatibility: peel texture.texture
T
Takahiro 已提交
2389
			if ( texture && texture.isWebGLRenderTargetCube ) {
2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403

				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 已提交
2404
			if ( ( texture && texture.isCubeTexture ) ||
2405
				( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {
2406 2407 2408 2409

				// CompressedTexture can have Array in image :/

				// this function alone should take care of cube textures
2410
				textures.setTextureCube( texture, slot );
2411 2412 2413 2414 2415

			} else {

				// assumed: texture property of THREE.WebGLRenderTargetCube

2416
				textures.setTextureCubeDynamic( texture, slot );
2417 2418 2419 2420 2421 2422

			}

		};

	}() );
T
tschw 已提交
2423

2424 2425 2426 2427 2428 2429 2430 2431
	//

	this.setFramebuffer = function ( value ) {

		_framebuffer = value;

	};

2432
	this.getRenderTarget = function () {
2433 2434 2435

		return _currentRenderTarget;

M
Michael Herzog 已提交
2436
	};
2437

2438
	this.setRenderTarget = function ( renderTarget ) {
M
Mr.doob 已提交
2439

2440 2441
		_currentRenderTarget = renderTarget;

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

2444
			textures.setupRenderTarget( renderTarget );
M
Mr.doob 已提交
2445 2446 2447

		}

2448
		var framebuffer = _framebuffer;
M
Mr.doob 已提交
2449
		var isCube = false;
M
Mr.doob 已提交
2450 2451 2452

		if ( renderTarget ) {

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

M
Mr.doob 已提交
2455
			if ( renderTarget.isWebGLRenderTargetCube ) {
M
Mr.doob 已提交
2456

M
Mr.doob 已提交
2457
				framebuffer = __webglFramebuffer[ renderTarget.activeCubeFace ];
M
Mr.doob 已提交
2458
				isCube = true;
M
Mr.doob 已提交
2459 2460 2461

			} else {

M
Mr.doob 已提交
2462
				framebuffer = __webglFramebuffer;
M
Mr.doob 已提交
2463 2464 2465

			}

M
Mr.doob 已提交
2466
			_currentViewport.copy( renderTarget.viewport );
2467 2468
			_currentScissor.copy( renderTarget.scissor );
			_currentScissorTest = renderTarget.scissorTest;
2469

M
Mr.doob 已提交
2470 2471
		} else {

M
Mr.doob 已提交
2472
			_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );
2473
			_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );
2474
			_currentScissorTest = _scissorTest;
2475

M
Mr.doob 已提交
2476 2477
		}

M
Mr.doob 已提交
2478
		if ( _currentFramebuffer !== framebuffer ) {
M
Mr.doob 已提交
2479 2480 2481 2482 2483 2484

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

		}

M
Mr.doob 已提交
2485
		state.viewport( _currentViewport );
2486 2487
		state.scissor( _currentScissor );
		state.setScissorTest( _currentScissorTest );
2488

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

			var textureProperties = properties.get( renderTarget.texture );
2492
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );
M
Mr.doob 已提交
2493 2494 2495

		}

M
Mr.doob 已提交
2496 2497
	};

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

0
06wj 已提交
2500
		if ( ! ( renderTarget && renderTarget.isWebGLRenderTarget ) ) {
2501

2502
			console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
G
gero3 已提交
2503
			return;
2504

G
gero3 已提交
2505
		}
2506

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

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

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

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

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

G
gero3 已提交
2517
				restore = true;
2518

G
gero3 已提交
2519
			}
2520

M
Mr.doob 已提交
2521
			try {
2522

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

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

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

M
Mr.doob 已提交
2532
				}
2533

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

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

M
Mr.doob 已提交
2541
				}
2542

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

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

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

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

					}
2552

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

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

				}
M
Mr.doob 已提交
2558

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

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

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

M
Mr.doob 已提交
2565 2566 2567
				}

			}
M
Mr.doob 已提交
2568 2569 2570

		}

M
Mr.doob 已提交
2571 2572
	};

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

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

		this.setTexture2D( texture, 0 );

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

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

		}
2603 2604 2605

	};

M
Mr.doob 已提交
2606
}
R
Rich Harris 已提交
2607

T
Tristan VALCKE 已提交
2608

2609
export { WebGLRenderer };