WebGLRenderer.js 61.9 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 70
		_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false,
		_powerPreference = parameters.powerPreference !== undefined ? parameters.powerPreference : 'default';
M
Mr.doob 已提交
71

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

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

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

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

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

102 103
	// physical lights

104
	this.physicallyCorrectLights = false;
105

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

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

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

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

	// internal properties

	var _this = this,

121 122
		_isContextLost = false,

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

125 126
		_framebuffer = null,

127 128 129
		_currentRenderTarget = null,
		_currentFramebuffer = null,
		_currentMaterialId = - 1,
130 131 132 133

		// geometry and program caching

		_currentGeometryProgram = {
M
Mr.doob 已提交
134 135
			geometry: null,
			program: null,
136 137
			wireframe: false
		},
138

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

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

146
		//
147

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

150
		//
M
Mr.doob 已提交
151

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

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

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

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

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

165
		// clipping
T
tschw 已提交
166

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

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

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

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

177 178 179 180 181
	function getTargetPixelRatio() {

		return _currentRenderTarget === null ? _pixelRatio : 1;

	}
182

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

	var _gl;

M
Mr.doob 已提交
187 188
	try {

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

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

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

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

		if ( _gl === null ) {

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

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

			} else {

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

			}
M
Mr.doob 已提交
217 218 219

		}

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

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

	}

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

242
	var background, morphtargets, bufferRenderer, indexedBufferRenderer;
243

244
	var utils;
245

246
	function initGLContext() {
247

248
		extensions = new WebGLExtensions( _gl );
249

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

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

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

		}

264
		extensions.get( 'OES_texture_float_linear' );
265

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

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

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

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

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

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

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

298
	}
M
Mr.doob 已提交
299

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

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

304 305 306 307 308 309 310
	var vr = null;

	if ( typeof navigator !== 'undefined' ) {

		vr = ( 'xr' in navigator ) ? new WebXRManager( _this ) : new WebVRManager( _this );

	}
M
Mr.doob 已提交
311

312
	this.vr = vr;
M
Mr.doob 已提交
313 314

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

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

318
	this.shadowMap = shadowMap;
M
Mr.doob 已提交
319

M
Mr.doob 已提交
320 321 322 323 324 325 326 327
	// API

	this.getContext = function () {

		return _gl;

	};

328 329 330 331 332 333
	this.getContextAttributes = function () {

		return _gl.getContextAttributes();

	};

334 335
	this.forceContextLoss = function () {

M
Michael Bond 已提交
336 337
		var extension = extensions.get( 'WEBGL_lose_context' );
		if ( extension ) extension.loseContext();
338 339 340

	};

341
	this.forceContextRestore = function () {
M
Mr.doob 已提交
342

343 344
		var extension = extensions.get( 'WEBGL_lose_context' );
		if ( extension ) extension.restoreContext();
M
Mr.doob 已提交
345 346 347

	};

348 349
	this.getPixelRatio = function () {

350
		return _pixelRatio;
351 352 353 354 355

	};

	this.setPixelRatio = function ( value ) {

356 357 358 359
		if ( value === undefined ) return;

		_pixelRatio = value;

M
Mr.doob 已提交
360
		this.setSize( _width, _height, false );
361 362 363

	};

364
	this.getSize = function ( target ) {
365

366 367 368 369 370 371 372 373 374
		if ( target === undefined ) {

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

			target = new Vector2();

		}

		return target.set( _width, _height );
375 376 377

	};

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

M
Mr.doob 已提交
380
		if ( vr.isPresenting() ) {
381 382 383 384 385 386

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

		}

387 388 389
		_width = width;
		_height = height;

390 391
		_canvas.width = width * _pixelRatio;
		_canvas.height = height * _pixelRatio;
392

393
		if ( updateStyle !== false ) {
394

G
gero3 已提交
395 396
			_canvas.style.width = width + 'px';
			_canvas.style.height = height + 'px';
397

G
gero3 已提交
398
		}
M
Mr.doob 已提交
399

400
		this.setViewport( 0, 0, width, height );
M
Mr.doob 已提交
401 402 403

	};

404
	this.getDrawingBufferSize = function ( target ) {
M
Mr.doob 已提交
405

406 407 408 409 410 411 412 413 414
		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 已提交
415 416 417

	};

418 419 420 421 422 423 424 425 426 427 428 429 430 431
	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 );

	};

432
	this.getCurrentViewport = function () {
M
Mugen87 已提交
433

434
		return _currentViewport;
M
Mugen87 已提交
435 436 437

	};

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

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

M
Mr.doob 已提交
443 444
	};

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

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

M
Mr.doob 已提交
450 451
	};

452 453
	this.setScissorTest = function ( boolean ) {

454
		state.setScissorTest( _scissorTest = boolean );
M
Mr.doob 已提交
455 456 457 458 459

	};

	// Clearing

M
Mr.doob 已提交
460
	this.getClearColor = function () {
M
Mr.doob 已提交
461

462
		return background.getClearColor();
M
Mr.doob 已提交
463 464 465

	};

466
	this.setClearColor = function () {
467

468
		background.setClearColor.apply( background, arguments );
M
Mr.doob 已提交
469 470 471

	};

M
Mr.doob 已提交
472
	this.getClearAlpha = function () {
M
Mr.doob 已提交
473

474
		return background.getClearAlpha();
M
Mr.doob 已提交
475 476 477

	};

M
Mugen87 已提交
478
	this.setClearAlpha = function () {
M
Mr.doob 已提交
479

480
		background.setClearAlpha.apply( background, arguments );
M
Mr.doob 已提交
481 482 483 484 485 486 487 488 489 490 491 492

	};

	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 );
493 494 495 496 497

	};

	this.clearColor = function () {

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

	};

	this.clearDepth = function () {

M
Mr.doob 已提交
504
		this.clear( false, true, false );
505 506 507 508 509

	};

	this.clearStencil = function () {

M
Mr.doob 已提交
510
		this.clear( false, false, true );
M
Mr.doob 已提交
511 512 513

	};

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

M
Mr.doob 已提交
516
	this.dispose = function () {
D
dubejf 已提交
517 518

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

521
		renderLists.dispose();
522
		renderStates.dispose();
M
Mugen87 已提交
523 524
		properties.dispose();
		objects.dispose();
525

526
		vr.dispose();
527

528
		animation.stop();
B
brunnerh 已提交
529

D
dubejf 已提交
530 531
	};

M
Mr.doob 已提交
532
	// Events
M
Mr.doob 已提交
533

D
dubejf 已提交
534 535 536 537
	function onContextLost( event ) {

		event.preventDefault();

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

540 541 542 543
		_isContextLost = true;

	}

M
Mugen87 已提交
544
	function onContextRestore( /* event */ ) {
D
dubejf 已提交
545

546
		console.log( 'THREE.WebGLRenderer: Context Restored.' );
547 548

		_isContextLost = false;
D
dubejf 已提交
549

550
		initGLContext();
D
dubejf 已提交
551

M
Mr.doob 已提交
552
	}
D
dubejf 已提交
553

554
	function onMaterialDispose( event ) {
M
Mr.doob 已提交
555 556 557 558 559 560 561

		var material = event.target;

		material.removeEventListener( 'dispose', onMaterialDispose );

		deallocateMaterial( material );

562
	}
M
Mr.doob 已提交
563 564 565

	// Buffer deallocation

566
	function deallocateMaterial( material ) {
M
Mr.doob 已提交
567

568 569
		releaseMaterialProgramReference( material );

570
		properties.remove( material );
571

572
	}
573 574


575
	function releaseMaterialProgramReference( material ) {
576

577
		var programInfo = properties.get( material ).program;
M
Mr.doob 已提交
578 579 580

		material.program = undefined;

581
		if ( programInfo !== undefined ) {
M
Mr.doob 已提交
582

583
			programCache.releaseProgram( programInfo );
M
Mr.doob 已提交
584

M
Mr.doob 已提交
585 586
		}

587
	}
M
Mr.doob 已提交
588 589 590

	// Buffer rendering

M
Mr.doob 已提交
591
	function renderObjectImmediate( object, program ) {
M
Mr.doob 已提交
592 593 594

		object.render( function ( object ) {

M
Mr.doob 已提交
595
			_this.renderBufferImmediate( object, program );
M
Mr.doob 已提交
596 597 598 599 600

		} );

	}

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

603
		state.initAttributes();
604

605
		var buffers = properties.get( object );
606

607 608 609 610
		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 已提交
611

612
		var programAttributes = program.getAttributes();
613

M
Mr.doob 已提交
614 615
		if ( object.hasPositions ) {

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

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

		}

		if ( object.hasNormals ) {

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

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

		}

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

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

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

		}

644
		if ( object.hasColors ) {
M
Mr.doob 已提交
645

646
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );
M
Mr.doob 已提交
647
			_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );
648

649 650
			state.enableAttribute( programAttributes.color );
			_gl.vertexAttribPointer( programAttributes.color, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
651 652 653

		}

654
		state.disableUnusedAttributes();
655

M
Mr.doob 已提交
656 657 658 659 660 661
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );

		object.count = 0;

	};

662
	this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {
663

664
		var frontFaceCW = ( object.isMesh && object.normalMatrix.determinant() < 0 );
665 666

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

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

M
Mr.doob 已提交
670
		var updateBuffers = false;
M
Mr.doob 已提交
671

672 673 674
		if ( _currentGeometryProgram.geometry !== geometry.id ||
			_currentGeometryProgram.program !== program.id ||
			_currentGeometryProgram.wireframe !== ( material.wireframe === true ) ) {
M
Mr.doob 已提交
675

M
Mr.doob 已提交
676 677
			_currentGeometryProgram.geometry = geometry.id;
			_currentGeometryProgram.program = program.id;
678
			_currentGeometryProgram.wireframe = material.wireframe === true;
M
Mr.doob 已提交
679 680 681 682
			updateBuffers = true;

		}

683
		if ( object.morphTargetInfluences ) {
684

685
			morphtargets.update( object, geometry, material, program );
M
Mr.doob 已提交
686 687 688 689 690

			updateBuffers = true;

		}

691 692
		//

693
		var index = geometry.index;
694
		var position = geometry.attributes.position;
695
		var rangeFactor = 1;
696

697 698
		if ( material.wireframe === true ) {

699
			index = geometries.getWireframeAttribute( geometry );
700
			rangeFactor = 2;
701 702 703

		}

M
Mr.doob 已提交
704
		var attribute;
M
Mr.doob 已提交
705
		var renderer = bufferRenderer;
706

707
		if ( index !== null ) {
708

M
Mr.doob 已提交
709
			attribute = attributes.get( index );
710

711
			renderer = indexedBufferRenderer;
M
Mr.doob 已提交
712
			renderer.setIndex( attribute );
713

714
		}
M
Mr.doob 已提交
715

716
		if ( updateBuffers ) {
M
Mr.doob 已提交
717

718
			setupVertexAttributes( material, program, geometry );
M
Mr.doob 已提交
719

720
			if ( index !== null ) {
721

M
Mr.doob 已提交
722
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, attribute.buffer );
723 724 725

			}

726
		}
727

728 729
		//

730
		var dataCount = Infinity;
731

M
Mr.doob 已提交
732
		if ( index !== null ) {
733

M
Mr.doob 已提交
734
			dataCount = index.count;
735

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

M
Mr.doob 已提交
738
			dataCount = position.count;
739

M
Mr.doob 已提交
740
		}
741

M
Mr.doob 已提交
742 743
		var rangeStart = geometry.drawRange.start * rangeFactor;
		var rangeCount = geometry.drawRange.count * rangeFactor;
744

M
Mr.doob 已提交
745 746
		var groupStart = group !== null ? group.start * rangeFactor : 0;
		var groupCount = group !== null ? group.count * rangeFactor : Infinity;
747

M
Mr.doob 已提交
748
		var drawStart = Math.max( rangeStart, groupStart );
749
		var drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1;
M
Mr.doob 已提交
750 751 752

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

753 754
		if ( drawCount === 0 ) return;

M
Mr.doob 已提交
755
		//
756

757
		if ( object.isMesh ) {
758

759
			if ( material.wireframe === true ) {
760

761
				state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );
762
				renderer.setMode( _gl.LINES );
763

764
			} else {
M
Mr.doob 已提交
765 766

				switch ( object.drawMode ) {
767

R
Rich Harris 已提交
768
					case TrianglesDrawMode:
B
Ben Adams 已提交
769 770 771
						renderer.setMode( _gl.TRIANGLES );
						break;

R
Rich Harris 已提交
772
					case TriangleStripDrawMode:
B
Ben Adams 已提交
773 774 775
						renderer.setMode( _gl.TRIANGLE_STRIP );
						break;

R
Rich Harris 已提交
776
					case TriangleFanDrawMode:
B
Ben Adams 已提交
777 778 779 780
						renderer.setMode( _gl.TRIANGLE_FAN );
						break;

				}
781

782
			}
783

784

785
		} else if ( object.isLine ) {
786

787
			var lineWidth = material.linewidth;
788

789
			if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material
790

791
			state.setLineWidth( lineWidth * getTargetPixelRatio() );
792

793
			if ( object.isLineSegments ) {
794

795
				renderer.setMode( _gl.LINES );
796

797 798 799 800
			} else if ( object.isLineLoop ) {

				renderer.setMode( _gl.LINE_LOOP );

801
			} else {
802

803
				renderer.setMode( _gl.LINE_STRIP );
804 805

			}
M
Mr.doob 已提交
806

807
		} else if ( object.isPoints ) {
808 809

			renderer.setMode( _gl.POINTS );
810

811 812 813 814
		} else if ( object.isSprite ) {

			renderer.setMode( _gl.TRIANGLES );

815
		}
816

T
Takahiro 已提交
817
		if ( geometry && geometry.isInstancedBufferGeometry ) {
M
Mr.doob 已提交
818 819 820

			if ( geometry.maxInstancedCount > 0 ) {

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

J
jfranc 已提交
823
			}
824 825 826

		} else {

M
Mr.doob 已提交
827
			renderer.render( drawStart, drawCount );
828

M
Mr.doob 已提交
829 830 831 832
		}

	};

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

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

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

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

M
Mr.doob 已提交
842 843 844
			}

		}
B
Ben Adams 已提交
845

846 847
		state.initAttributes();

848
		var geometryAttributes = geometry.attributes;
849

850
		var programAttributes = program.getAttributes();
851

852
		var materialDefaultAttributeValues = material.defaultAttributeValues;
853

854
		for ( var name in programAttributes ) {
855

856
			var programAttribute = programAttributes[ name ];
M
Mr.doob 已提交
857

M
Mr.doob 已提交
858
			if ( programAttribute >= 0 ) {
M
Mr.doob 已提交
859

860
				var geometryAttribute = geometryAttributes[ name ];
861

M
Mr.doob 已提交
862
				if ( geometryAttribute !== undefined ) {
M
Mr.doob 已提交
863

864
					var normalized = geometryAttribute.normalized;
865
					var size = geometryAttribute.itemSize;
866

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

869 870 871 872
					// TODO Attribute may not be available on context restore

					if ( attribute === undefined ) continue;

M
Mr.doob 已提交
873 874 875
					var buffer = attribute.buffer;
					var type = attribute.type;
					var bytesPerElement = attribute.bytesPerElement;
876

A
aardgoose 已提交
877
					if ( geometryAttribute.isInterleavedBufferAttribute ) {
878

M
Mr.doob 已提交
879 880 881 882
						var data = geometryAttribute.data;
						var stride = data.stride;
						var offset = geometryAttribute.offset;

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

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

M
Mr.doob 已提交
887
							if ( geometry.maxInstancedCount === undefined ) {
888

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

M
Mr.doob 已提交
891
							}
B
Ben Adams 已提交
892

M
Mr.doob 已提交
893
						} else {
B
Ben Adams 已提交
894

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

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

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

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

A
aardgoose 已提交
904
						if ( geometryAttribute.isInstancedBufferAttribute ) {
B
Ben Adams 已提交
905

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

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

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

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

M
Mr.doob 已提交
914 915 916 917
						} else {

							state.enableAttribute( programAttribute );

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

M
Mr.doob 已提交
920
						_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
921
						_gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, 0 );
M
Mr.doob 已提交
922

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

925 926
				} else if ( materialDefaultAttributeValues !== undefined ) {

T
tschw 已提交
927
					var value = materialDefaultAttributeValues[ name ];
928

929
					if ( value !== undefined ) {
M
Mr.doob 已提交
930

931
						switch ( value.length ) {
M
Mr.doob 已提交
932

933 934 935
							case 2:
								_gl.vertexAttrib2fv( programAttribute, value );
								break;
M
Mr.doob 已提交
936

937 938 939
							case 3:
								_gl.vertexAttrib3fv( programAttribute, value );
								break;
M
Mr.doob 已提交
940

941 942 943
							case 4:
								_gl.vertexAttrib4fv( programAttribute, value );
								break;
944

945 946
							default:
								_gl.vertexAttrib1fv( programAttribute, value );
947 948

						}
M
Mr.doob 已提交
949 950 951 952 953 954 955 956

					}

				}

			}

		}
957

958
		state.disableUnusedAttributes();
959

M
Mr.doob 已提交
960 961
	}

M
Mr.doob 已提交
962
	// Compile
M
Mr.doob 已提交
963

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

M
Mr.doob 已提交
966
		currentRenderState = renderStates.get( scene, camera );
967
		currentRenderState.init();
968

M
Mr.doob 已提交
969
		scene.traverse( function ( object ) {
G
gero3 已提交
970 971

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

973
				currentRenderState.pushLight( object );
974 975 976

				if ( object.castShadow ) {

977
					currentRenderState.pushShadow( object );
978 979

				}
M
Mr.doob 已提交
980

G
gero3 已提交
981
			}
M
Mr.doob 已提交
982 983 984

		} );

985
		currentRenderState.setupLights( camera );
M
Mr.doob 已提交
986 987 988 989 990

		scene.traverse( function ( object ) {

			if ( object.material ) {

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

G
gero3 已提交
993
					for ( var i = 0; i < object.material.length; i ++ ) {
M
Mr.doob 已提交
994 995 996

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

G
gero3 已提交
997
					}
M
Mr.doob 已提交
998

G
gero3 已提交
999
				} else {
M
Mr.doob 已提交
1000 1001 1002

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

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

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

		} );
G
gero3 已提交
1008 1009

	};
1010

1011
	// Animation Loop
M
Mr.doob 已提交
1012

M
Mr.doob 已提交
1013
	var onAnimationFrameCallback = null;
1014

1015
	function onAnimationFrame( time ) {
1016

M
Mr.doob 已提交
1017
		if ( vr.isPresenting() ) return;
1018
		if ( onAnimationFrameCallback ) onAnimationFrameCallback( time );
1019

1020
	}
1021

M
Mr.doob 已提交
1022 1023
	var animation = new WebGLAnimation();
	animation.setAnimationLoop( onAnimationFrame );
1024 1025

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

1027
	this.setAnimationLoop = function ( callback ) {
1028

M
Mr.doob 已提交
1029 1030
		onAnimationFrameCallback = callback;
		vr.setAnimationLoop( callback );
1031

1032 1033
		animation.start();

1034 1035
	};

M
Mr.doob 已提交
1036 1037 1038
	// Rendering

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

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

1042
			console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );
M
Mr.doob 已提交
1043 1044 1045 1046
			return;

		}

1047 1048
		if ( _isContextLost ) return;

M
Mr.doob 已提交
1049 1050
		// reset caching for this frame

M
Mr.doob 已提交
1051 1052
		_currentGeometryProgram.geometry = null;
		_currentGeometryProgram.program = null;
1053
		_currentGeometryProgram.wireframe = false;
1054
		_currentMaterialId = - 1;
1055
		_currentCamera = null;
M
Mr.doob 已提交
1056 1057 1058

		// update scene graph

1059
		if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
M
Mr.doob 已提交
1060 1061 1062

		// update camera matrices and frustum

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

1065 1066 1067 1068 1069 1070
		if ( vr.enabled ) {

			camera = vr.getCamera( camera );

		}

1071 1072
		//

1073 1074
		currentRenderState = renderStates.get( scene, camera );
		currentRenderState.init();
1075

1076 1077
		scene.onBeforeRender( _this, scene, camera, renderTarget );

M
Mr.doob 已提交
1078 1079 1080
		_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
		_frustum.setFromMatrix( _projScreenMatrix );

T
tschw 已提交
1081
		_localClippingEnabled = this.localClippingEnabled;
M
Mr.doob 已提交
1082
		_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );
T
tschw 已提交
1083

1084 1085 1086
		currentRenderList = renderLists.get( scene, camera );
		currentRenderList.init();

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

M
Mr.doob 已提交
1089
		if ( _this.sortObjects === true ) {
1090

1091
			currentRenderList.sort();
M
Mr.doob 已提交
1092

1093 1094
		}

M
Mr.doob 已提交
1095
		//
M
Mr.doob 已提交
1096

T
tschw 已提交
1097
		if ( _clippingEnabled ) _clipping.beginShadows();
T
tschw 已提交
1098

1099
		var shadowsArray = currentRenderState.state.shadowsArray;
1100

1101
		shadowMap.render( shadowsArray, scene, camera );
1102

1103
		currentRenderState.setupLights( camera );
1104

T
tschw 已提交
1105
		if ( _clippingEnabled ) _clipping.endShadows();
T
tschw 已提交
1106

M
Mr.doob 已提交
1107 1108
		//

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

1111 1112 1113 1114 1115 1116
		if ( renderTarget === undefined ) {

			renderTarget = null;

		}

M
Mr.doob 已提交
1117 1118
		this.setRenderTarget( renderTarget );

M
Mr.doob 已提交
1119 1120
		//

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

1123
		// render scene
M
Mr.doob 已提交
1124

1125 1126 1127
		var opaqueObjects = currentRenderList.opaque;
		var transparentObjects = currentRenderList.transparent;

M
Mr.doob 已提交
1128 1129
		if ( scene.overrideMaterial ) {

1130
			var overrideMaterial = scene.overrideMaterial;
M
Mr.doob 已提交
1131

M
Mr.doob 已提交
1132 1133
			if ( opaqueObjects.length ) renderObjects( opaqueObjects, scene, camera, overrideMaterial );
			if ( transparentObjects.length ) renderObjects( transparentObjects, scene, camera, overrideMaterial );
1134

M
Mr.doob 已提交
1135 1136
		} else {

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

M
Mr.doob 已提交
1139
			if ( opaqueObjects.length ) renderObjects( opaqueObjects, scene, camera );
1140 1141 1142

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

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

1145
		}
M
Mr.doob 已提交
1146

1147
		//
M
Mr.doob 已提交
1148

M
Mr.doob 已提交
1149 1150
		if ( renderTarget ) {

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

1153
			textures.updateRenderTargetMipmap( renderTarget );
M
Mr.doob 已提交
1154

M
Mugen87 已提交
1155
			// resolve multisample renderbuffers to a single-sample texture if necessary
1156 1157 1158

			textures.updateMultisampleRenderTarget( renderTarget );

M
Mr.doob 已提交
1159 1160
		}

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

1163 1164 1165
		state.buffers.depth.setTest( true );
		state.buffers.depth.setMask( true );
		state.buffers.color.setMask( true );
M
Mr.doob 已提交
1166

1167
		state.setPolygonOffset( false );
1168

1169
		scene.onAfterRender( _this, scene, camera );
1170

M
Mr.doob 已提交
1171
		if ( vr.enabled ) {
1172

1173
			vr.submitFrame();
1174

M
Mr.doob 已提交
1175
		}
M
Mr.doob 已提交
1176

M
Mr.doob 已提交
1177 1178
		// _gl.finish();

1179
		currentRenderList = null;
1180
		currentRenderState = null;
1181

M
Mr.doob 已提交
1182
	};
M
Mr.doob 已提交
1183

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

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

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

1190
		if ( visible ) {
1191

1192 1193 1194 1195 1196
			if ( object.isGroup ) {

				groupOrder = object.renderOrder;

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

1198
				currentRenderState.pushLight( object );
1199 1200 1201

				if ( object.castShadow ) {

1202
					currentRenderState.pushShadow( object );
1203 1204

				}
M
Mr.doob 已提交
1205

1206
			} else if ( object.isSprite ) {
M
Mr.doob 已提交
1207

1208
				if ( ! object.frustumCulled || _frustum.intersectsSprite( object ) ) {
1209

1210 1211 1212 1213 1214 1215 1216 1217 1218 1219
					if ( sortObjects ) {

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

					}

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

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

1222
				}
M
Mr.doob 已提交
1223

1224
			} else if ( object.isImmediateRenderObject ) {
M
Mr.doob 已提交
1225

1226
				if ( sortObjects ) {
M
Mr.doob 已提交
1227

1228 1229
					_vector3.setFromMatrixPosition( object.matrixWorld )
						.applyMatrix4( _projScreenMatrix );
M
Mr.doob 已提交
1230

1231
				}
M
Mr.doob 已提交
1232

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

1235
			} else if ( object.isMesh || object.isLine || object.isPoints ) {
1236

1237
				if ( object.isSkinnedMesh ) {
1238

1239
					object.skeleton.update();
1240

1241
				}
1242

1243
				if ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) {
1244

1245 1246 1247 1248 1249 1250
					if ( sortObjects ) {

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

					}
1251

1252 1253
					var geometry = objects.update( object );
					var material = object.material;
1254

1255
					if ( Array.isArray( material ) ) {
1256

1257
						var groups = geometry.groups;
1258

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

1261 1262
							var group = groups[ i ];
							var groupMaterial = material[ group.materialIndex ];
1263

1264
							if ( groupMaterial && groupMaterial.visible ) {
1265

1266
								currentRenderList.push( object, geometry, groupMaterial, groupOrder, _vector3.z, group );
1267 1268

							}
M
Mr.doob 已提交
1269

M
Mr.doob 已提交
1270
						}
M
Mr.doob 已提交
1271

1272
					} else if ( material.visible ) {
1273

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

1276
					}
M
Mr.doob 已提交
1277

1278
				}
M
Mr.doob 已提交
1279

1280
			}
M
Mr.doob 已提交
1281

M
Mr.doob 已提交
1282
		}
M
Mr.doob 已提交
1283

M
Mr.doob 已提交
1284
		var children = object.children;
M
Mr.doob 已提交
1285

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

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

1290
		}
1291

1292
	}
M
Mr.doob 已提交
1293

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

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

1298
			var renderItem = renderList[ i ];
M
Mr.doob 已提交
1299

1300
			var object = renderItem.object;
M
Mr.doob 已提交
1301 1302 1303
			var geometry = renderItem.geometry;
			var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;
			var group = renderItem.group;
M
Mr.doob 已提交
1304

M
Mr.doob 已提交
1305
			if ( camera.isArrayCamera ) {
M
Mr.doob 已提交
1306

1307 1308
				_currentArrayCamera = camera;

M
Mr.doob 已提交
1309
				var cameras = camera.cameras;
M
Mr.doob 已提交
1310

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

M
Mr.doob 已提交
1313
					var camera2 = cameras[ j ];
M
Mr.doob 已提交
1314

1315
					if ( object.layers.test( camera2.layers ) ) {
1316

M
Mr.doob 已提交
1317 1318 1319 1320 1321 1322 1323
						if ( 'viewport' in camera2 ) { // XR

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

						} else {

							var bounds = camera2.bounds;
1324

M
Mr.doob 已提交
1325 1326 1327 1328
							var x = bounds.x * _width;
							var y = bounds.y * _height;
							var width = bounds.z * _width;
							var height = bounds.w * _height;
M
Mr.doob 已提交
1329

M
Mr.doob 已提交
1330 1331 1332
							state.viewport( _currentViewport.set( x, y, width, height ).multiplyScalar( _pixelRatio ) );

						}
1333

1334 1335
						currentRenderState.setupLights( camera2 );

1336 1337 1338
						renderObject( object, scene, camera2, geometry, material, group );

					}
M
Mr.doob 已提交
1339

M
Mr.doob 已提交
1340
				}
1341

M
Mr.doob 已提交
1342
			} else {
M
Mr.doob 已提交
1343

1344 1345
				_currentArrayCamera = null;

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

M
Mr.doob 已提交
1348
			}
M
Mr.doob 已提交
1349

1350
		}
M
Mr.doob 已提交
1351

1352
	}
G
gero3 已提交
1353

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

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

M
Mr.doob 已提交
1359 1360 1361 1362 1363
		object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
		object.normalMatrix.getNormalMatrix( object.modelViewMatrix );

		if ( object.isImmediateRenderObject ) {

1364
			state.setMaterial( material );
M
Mr.doob 已提交
1365 1366 1367

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

M
Mr.doob 已提交
1368 1369
			_currentGeometryProgram.geometry = null;
			_currentGeometryProgram.program = null;
1370
			_currentGeometryProgram.wireframe = false;
M
Mr.doob 已提交
1371

M
Mr.doob 已提交
1372
			renderObjectImmediate( object, program );
M
Mr.doob 已提交
1373 1374 1375

		} else {

M
Mugen87 已提交
1376
			_this.renderBufferDirect( camera, scene.fog, geometry, material, object, group );
M
Mr.doob 已提交
1377 1378 1379

		}

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

M
Mr.doob 已提交
1383 1384
	}

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

1387
		var materialProperties = properties.get( material );
G
gero3 已提交
1388

1389 1390
		var lights = currentRenderState.state.lights;
		var shadowsArray = currentRenderState.state.shadowsArray;
1391

M
Mr.doob 已提交
1392 1393 1394
		var lightsHash = materialProperties.lightsHash;
		var lightsStateHash = lights.state.hash;

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

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

1400
		var program = materialProperties.program;
T
tschw 已提交
1401
		var programChange = true;
1402

1403
		if ( program === undefined ) {
B
Ben Adams 已提交
1404

M
Mr.doob 已提交
1405 1406
			// new material
			material.addEventListener( 'dispose', onMaterialDispose );
B
Ben Adams 已提交
1407

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

M
Mr.doob 已提交
1410
			// changed glsl or parameters
1411
			releaseMaterialProgramReference( material );
B
Ben Adams 已提交
1412

M
Mr.doob 已提交
1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427
		} 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;
1428 1429 1430

			programChange = false;

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

T
tschw 已提交
1433
			// same glsl and uniform list
T
tschw 已提交
1434 1435
			return;

T
tschw 已提交
1436
		} else {
B
Ben Adams 已提交
1437

T
tschw 已提交
1438 1439
			// only rebuild uniform list
			programChange = false;
B
Ben Adams 已提交
1440 1441 1442

		}

1443
		if ( programChange ) {
B
Ben Adams 已提交
1444

1445
			if ( parameters.shaderID ) {
B
Ben Adams 已提交
1446

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

1449
				materialProperties.shader = {
1450
					name: material.type,
M
Mr.doob 已提交
1451
					uniforms: cloneUniforms( shader.uniforms ),
1452
					vertexShader: shader.vertexShader,
1453
					fragmentShader: shader.fragmentShader
1454
				};
B
Ben Adams 已提交
1455

1456
			} else {
B
Ben Adams 已提交
1457

1458
				materialProperties.shader = {
1459 1460 1461
					name: material.type,
					uniforms: material.uniforms,
					vertexShader: material.vertexShader,
1462
					fragmentShader: material.fragmentShader
1463
				};
G
gero3 已提交
1464

1465
			}
G
gero3 已提交
1466

1467
			material.onBeforeCompile( materialProperties.shader, _this );
G
gero3 已提交
1468

1469
			// Computing code again as onBeforeCompile may have changed the shaders
1470 1471
			code = programCache.getProgramCode( material, parameters );

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

1474 1475
			materialProperties.program = program;
			material.program = program;
1476 1477 1478

		}

1479
		var programAttributes = program.getAttributes();
M
Mr.doob 已提交
1480 1481 1482 1483 1484

		if ( material.morphTargets ) {

			material.numSupportedMorphTargets = 0;

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

1487
				if ( programAttributes[ 'morphTarget' + i ] >= 0 ) {
M
Mr.doob 已提交
1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500

					material.numSupportedMorphTargets ++;

				}

			}

		}

		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

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

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

					material.numSupportedMorphNormals ++;

				}

			}

		}

1513
		var uniforms = materialProperties.shader.uniforms;
T
tschw 已提交
1514

1515
		if ( ! material.isShaderMaterial &&
1516 1517
			! material.isRawShaderMaterial ||
			material.clipping === true ) {
T
tschw 已提交
1518

T
tschw 已提交
1519
			materialProperties.numClippingPlanes = _clipping.numPlanes;
1520
			materialProperties.numIntersection = _clipping.numIntersection;
T
tschw 已提交
1521
			uniforms.clippingPlanes = _clipping.uniform;
T
tschw 已提交
1522 1523 1524

		}

1525
		materialProperties.fog = fog;
1526

1527
		// store the light setup it was created for
M
Mr.doob 已提交
1528
		if ( lightsHash === undefined ) {
1529

M
Mr.doob 已提交
1530
			materialProperties.lightsHash = lightsHash = {};
1531 1532 1533

		}

M
Mr.doob 已提交
1534 1535 1536 1537 1538 1539 1540
		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;
1541

M
Mr.doob 已提交
1542
		if ( material.lights ) {
1543 1544 1545

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

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

1561 1562
		}

T
tschw 已提交
1563 1564
		var progUniforms = materialProperties.program.getUniforms(),
			uniformsList =
1565
				WebGLUniforms.seqWithValue( progUniforms.seq, uniforms );
A
arose 已提交
1566

T
tschw 已提交
1567
		materialProperties.uniformsList = uniformsList;
A
arose 已提交
1568

M
Mr.doob 已提交
1569
	}
M
Mr.doob 已提交
1570

1571
	function setProgram( camera, fog, material, object ) {
M
Mr.doob 已提交
1572 1573 1574

		_usedTextureUnits = 0;

1575
		var materialProperties = properties.get( material );
1576
		var lights = currentRenderState.state.lights;
1577

M
Mr.doob 已提交
1578 1579 1580
		var lightsHash = materialProperties.lightsHash;
		var lightsStateHash = lights.state.hash;

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

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

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

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

			}

		}

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

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

1604
				material.needsUpdate = true;
1605

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

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

M
Mr.doob 已提交
1610 1611 1612 1613 1614 1615 1616
			} 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 ) ) {
1617

1618
				material.needsUpdate = true;
1619

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

				material.needsUpdate = true;

1626
			}
1627 1628 1629 1630

		}

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

1632
			initMaterial( material, fog, object );
M
Mr.doob 已提交
1633 1634 1635 1636
			material.needsUpdate = false;

		}

1637
		var refreshProgram = false;
M
Mr.doob 已提交
1638
		var refreshMaterial = false;
1639
		var refreshLights = false;
M
Mr.doob 已提交
1640

1641
		var program = materialProperties.program,
1642
			p_uniforms = program.getUniforms(),
1643
			m_uniforms = materialProperties.shader.uniforms;
M
Mr.doob 已提交
1644

1645
		if ( state.useProgram( program.program ) ) {
M
Mr.doob 已提交
1646

1647
			refreshProgram = true;
M
Mr.doob 已提交
1648
			refreshMaterial = true;
1649
			refreshLights = true;
M
Mr.doob 已提交
1650 1651 1652 1653 1654 1655

		}

		if ( material.id !== _currentMaterialId ) {

			_currentMaterialId = material.id;
1656

M
Mr.doob 已提交
1657 1658 1659 1660
			refreshMaterial = true;

		}

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

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

G
gero3 已提交
1665
			if ( capabilities.logarithmicDepthBuffer ) {
1666

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

			}

1672
			if ( _currentCamera !== camera ) {
1673

1674
				_currentCamera = camera;
1675 1676 1677 1678 1679 1680

				// 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 已提交
1681
				refreshLights = true;		// remains set until update done
1682 1683

			}
M
Mr.doob 已提交
1684

1685 1686 1687
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)

1688
			if ( material.isShaderMaterial ||
1689 1690 1691
				material.isMeshPhongMaterial ||
				material.isMeshStandardMaterial ||
				material.envMap ) {
1692

T
tschw 已提交
1693 1694 1695
				var uCamPos = p_uniforms.map.cameraPosition;

				if ( uCamPos !== undefined ) {
1696

T
tschw 已提交
1697
					uCamPos.setValue( _gl,
1698
						_vector3.setFromMatrixPosition( camera.matrixWorld ) );
1699 1700 1701 1702 1703

				}

			}

1704
			if ( material.isMeshPhongMaterial ||
1705 1706 1707 1708
				material.isMeshLambertMaterial ||
				material.isMeshBasicMaterial ||
				material.isMeshStandardMaterial ||
				material.isShaderMaterial ||
1709
				material.skinning ) {
1710

T
tschw 已提交
1711
				p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );
1712 1713 1714

			}

M
Mr.doob 已提交
1715 1716 1717 1718 1719 1720
		}

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

1721
		if ( material.skinning ) {
M
Mr.doob 已提交
1722

T
tschw 已提交
1723 1724
			p_uniforms.setOptional( _gl, object, 'bindMatrix' );
			p_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );
1725

T
tschw 已提交
1726
			var skeleton = object.skeleton;
1727

T
tschw 已提交
1728
			if ( skeleton ) {
1729

1730 1731
				var bones = skeleton.bones;

1732
				if ( capabilities.floatVertexTextures ) {
M
Mr.doob 已提交
1733

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

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

					}

M
Mr.doob 已提交
1760 1761
					p_uniforms.setValue( _gl, 'boneTexture', skeleton.boneTexture );
					p_uniforms.setValue( _gl, 'boneTextureSize', skeleton.boneTextureSize );
M
Mr.doob 已提交
1762

T
tschw 已提交
1763
				} else {
M
Mr.doob 已提交
1764

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

				}

			}

		}

		if ( refreshMaterial ) {

1775 1776 1777
			p_uniforms.setValue( _gl, 'toneMappingExposure', _this.toneMappingExposure );
			p_uniforms.setValue( _gl, 'toneMappingWhitePoint', _this.toneMappingWhitePoint );

M
Mr.doob 已提交
1778
			if ( material.lights ) {
M
Mr.doob 已提交
1779

1780
				// the current material requires lighting info
M
Mr.doob 已提交
1781

T
tschw 已提交
1782 1783 1784 1785 1786 1787
				// 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 已提交
1788

T
tschw 已提交
1789
				markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
G
gero3 已提交
1790

T
tschw 已提交
1791
			}
G
gero3 已提交
1792

T
tschw 已提交
1793
			// refresh uniforms common to several materials
G
gero3 已提交
1794

T
tschw 已提交
1795
			if ( fog && material.fog ) {
G
gero3 已提交
1796

T
tschw 已提交
1797
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
1798 1799 1800

			}

1801
			if ( material.isMeshBasicMaterial ) {
M
Mr.doob 已提交
1802 1803 1804

				refreshUniformsCommon( m_uniforms, material );

1805
			} else if ( material.isMeshLambertMaterial ) {
M
Mr.doob 已提交
1806

1807 1808
				refreshUniformsCommon( m_uniforms, material );
				refreshUniformsLambert( m_uniforms, material );
M
Mr.doob 已提交
1809

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

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

1814
				if ( material.isMeshToonMaterial ) {
M
Mr.doob 已提交
1815

1816
					refreshUniformsToon( m_uniforms, material );
M
Mr.doob 已提交
1817

1818
				} else {
1819

1820
					refreshUniformsPhong( m_uniforms, material );
1821

1822
				}
T
Takahiro 已提交
1823

1824
			} else if ( material.isMeshStandardMaterial ) {
T
Takahiro 已提交
1825

1826
				refreshUniformsCommon( m_uniforms, material );
1827

1828
				if ( material.isMeshPhysicalMaterial ) {
1829

1830
					refreshUniformsPhysical( m_uniforms, material );
W
WestLangley 已提交
1831

1832
				} else {
W
WestLangley 已提交
1833

1834
					refreshUniformsStandard( m_uniforms, material );
W
WestLangley 已提交
1835

1836
				}
W
WestLangley 已提交
1837

W
WestLangley 已提交
1838 1839 1840 1841 1842 1843
			} else if ( material.isMeshMatcapMaterial ) {

				refreshUniformsCommon( m_uniforms, material );

				refreshUniformsMatcap( m_uniforms, material );

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

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

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

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

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

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

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

				refreshUniformsLine( m_uniforms, material );

				if ( material.isLineDashedMaterial ) {

					refreshUniformsDash( m_uniforms, material );

				}

			} else if ( material.isPointsMaterial ) {

				refreshUniformsPoints( m_uniforms, material );

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

				refreshUniformsSprites( m_uniforms, material );

1877 1878 1879 1880 1881
			} else if ( material.isShadowMaterial ) {

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

M
Mr.doob 已提交
1882 1883
			}

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

1887 1888
			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 已提交
1889

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

		}

1894 1895 1896 1897 1898 1899
		if ( material.isShaderMaterial && material.uniformsNeedUpdate === true ) {

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

		}
M
Mr.doob 已提交
1900

1901 1902 1903 1904 1905 1906
		if ( material.isSpriteMaterial ) {

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

		}

T
tschw 已提交
1907
		// common matrices
M
Mr.doob 已提交
1908

M
Mr.doob 已提交
1909 1910
		p_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix );
		p_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix );
T
tschw 已提交
1911
		p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );
A
arose 已提交
1912

T
tschw 已提交
1913
		return program;
A
arose 已提交
1914 1915 1916

	}

M
Mr.doob 已提交
1917 1918
	// Uniforms (refresh uniforms objects)

M
Mr.doob 已提交
1919
	function refreshUniformsCommon( uniforms, material ) {
M
Mr.doob 已提交
1920 1921 1922

		uniforms.opacity.value = material.opacity;

1923 1924 1925 1926 1927
		if ( material.color ) {

			uniforms.diffuse.value = material.color;

		}
M
Mr.doob 已提交
1928

1929
		if ( material.emissive ) {
M
Mr.doob 已提交
1930

1931
			uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );
M
Mr.doob 已提交
1932 1933 1934

		}

1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960
		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 已提交
1961
			uniforms.flipEnvMap.value = material.envMap.isCubeTexture ? - 1 : 1;
1962 1963 1964 1965

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

1966
			uniforms.maxMipLevel.value = properties.get( material.envMap ).__maxMipLevel;
1967

1968
		}
M
Mr.doob 已提交
1969

1970 1971 1972 1973 1974 1975 1976
		if ( material.lightMap ) {

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

		}

1977
		if ( material.aoMap ) {
1978

1979 1980
			uniforms.aoMap.value = material.aoMap;
			uniforms.aoMapIntensity.value = material.aoMapIntensity;
1981 1982 1983

		}

M
Mr.doob 已提交
1984
		// uv repeat and offset setting priorities
M
Mr.doob 已提交
1985 1986 1987 1988 1989
		// 1. color map
		// 2. specular map
		// 3. normal map
		// 4. bump map
		// 5. alpha map
1990
		// 6. emissive map
M
Mr.doob 已提交
1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001

		var uvScaleMap;

		if ( material.map ) {

			uvScaleMap = material.map;

		} else if ( material.specularMap ) {

			uvScaleMap = material.specularMap;

2002 2003 2004 2005
		} else if ( material.displacementMap ) {

			uvScaleMap = material.displacementMap;

M
Mr.doob 已提交
2006 2007 2008 2009 2010 2011 2012 2013
		} else if ( material.normalMap ) {

			uvScaleMap = material.normalMap;

		} else if ( material.bumpMap ) {

			uvScaleMap = material.bumpMap;

2014 2015 2016 2017 2018 2019 2020 2021
		} else if ( material.roughnessMap ) {

			uvScaleMap = material.roughnessMap;

		} else if ( material.metalnessMap ) {

			uvScaleMap = material.metalnessMap;

2022 2023 2024 2025
		} else if ( material.alphaMap ) {

			uvScaleMap = material.alphaMap;

2026 2027 2028 2029
		} else if ( material.emissiveMap ) {

			uvScaleMap = material.emissiveMap;

M
Mr.doob 已提交
2030 2031 2032 2033
		}

		if ( uvScaleMap !== undefined ) {

2034
			// backwards compatibility
2035
			if ( uvScaleMap.isWebGLRenderTarget ) {
M
Mr.doob 已提交
2036 2037 2038 2039 2040

				uvScaleMap = uvScaleMap.texture;

			}

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

W
WestLangley 已提交
2043
				uvScaleMap.updateMatrix();
M
Mr.doob 已提交
2044

W
WestLangley 已提交
2045
			}
2046

2047
			uniforms.uvTransform.value.copy( uvScaleMap.matrix );
M
Mr.doob 已提交
2048 2049 2050

		}

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

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

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

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

M
Mr.doob 已提交
2060
	function refreshUniformsDash( uniforms, material ) {
M
Mr.doob 已提交
2061 2062 2063 2064 2065

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

M
Mr.doob 已提交
2066
	}
M
Mr.doob 已提交
2067

M
Mr.doob 已提交
2068
	function refreshUniformsPoints( uniforms, material ) {
M
Mr.doob 已提交
2069

2070
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
2071
		uniforms.opacity.value = material.opacity;
2072
		uniforms.size.value = material.size * _pixelRatio;
2073
		uniforms.scale.value = _height * 0.5;
M
Mr.doob 已提交
2074 2075 2076

		uniforms.map.value = material.map;

2077 2078
		if ( material.map !== null ) {

W
WestLangley 已提交
2079
			if ( material.map.matrixAutoUpdate === true ) {
2080

W
WestLangley 已提交
2081
				material.map.updateMatrix();
W
WestLangley 已提交
2082 2083

			}
2084

2085
			uniforms.uvTransform.value.copy( material.map.matrix );
2086 2087 2088

		}

2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109
	}

	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 已提交
2110
	}
M
Mr.doob 已提交
2111

M
Mr.doob 已提交
2112
	function refreshUniformsFog( uniforms, fog ) {
M
Mr.doob 已提交
2113 2114 2115

		uniforms.fogColor.value = fog.color;

2116
		if ( fog.isFog ) {
M
Mr.doob 已提交
2117 2118 2119 2120

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

2121
		} else if ( fog.isFogExp2 ) {
M
Mr.doob 已提交
2122 2123 2124 2125 2126

			uniforms.fogDensity.value = fog.density;

		}

M
Mr.doob 已提交
2127
	}
M
Mr.doob 已提交
2128

M
Mr.doob 已提交
2129
	function refreshUniformsLambert( uniforms, material ) {
2130 2131 2132 2133 2134 2135 2136 2137 2138

		if ( material.emissiveMap ) {

			uniforms.emissiveMap.value = material.emissiveMap;

		}

	}

M
Mr.doob 已提交
2139
	function refreshUniformsPhong( uniforms, material ) {
M
Mr.doob 已提交
2140

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

2144
		if ( material.emissiveMap ) {
2145

2146
			uniforms.emissiveMap.value = material.emissiveMap;
2147

2148
		}
M
Mr.doob 已提交
2149

2150 2151 2152 2153
		if ( material.bumpMap ) {

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

2156
		}
M
Mr.doob 已提交
2157

2158 2159 2160 2161
		if ( material.normalMap ) {

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

		}
M
Mr.doob 已提交
2165

2166 2167 2168 2169 2170
		if ( material.displacementMap ) {

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

2172
		}
2173

T
Takahiro 已提交
2174 2175 2176 2177 2178 2179
	}

	function refreshUniformsToon( uniforms, material ) {

		refreshUniformsPhong( uniforms, material );

T
Takahiro 已提交
2180
		if ( material.gradientMap ) {
T
Takahiro 已提交
2181

T
Takahiro 已提交
2182
			uniforms.gradientMap.value = material.gradientMap;
T
Takahiro 已提交
2183 2184 2185

		}

2186 2187
	}

M
Mr.doob 已提交
2188
	function refreshUniformsStandard( uniforms, material ) {
W
WestLangley 已提交
2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214

		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;
2215
			if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1;
W
WestLangley 已提交
2216 2217 2218 2219 2220 2221 2222

		}

		if ( material.normalMap ) {

			uniforms.normalMap.value = material.normalMap;
			uniforms.normalScale.value.copy( material.normalScale );
2223
			if ( material.side === BackSide ) uniforms.normalScale.value.negate();
W
WestLangley 已提交
2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243

		}

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

2246 2247 2248 2249
		refreshUniformsStandard( uniforms, material );

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

2250 2251 2252
		uniforms.clearCoat.value = material.clearCoat;
		uniforms.clearCoatRoughness.value = material.clearCoatRoughness;

W
WestLangley 已提交
2253 2254
	}

W
WestLangley 已提交
2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288
	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 已提交
2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316
	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;

	}

2317 2318 2319 2320 2321 2322
	function refreshUniformsNormal( uniforms, material ) {

		if ( material.bumpMap ) {

			uniforms.bumpMap.value = material.bumpMap;
			uniforms.bumpScale.value = material.bumpScale;
2323
			if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1;
2324 2325 2326 2327 2328 2329 2330

		}

		if ( material.normalMap ) {

			uniforms.normalMap.value = material.normalMap;
			uniforms.normalScale.value.copy( material.normalScale );
2331
			if ( material.side === BackSide ) uniforms.normalScale.value.negate();
2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344

		}

		if ( material.displacementMap ) {

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

		}

	}

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

M
Mr.doob 已提交
2347
	function markUniformsLightsNeedsUpdate( uniforms, value ) {
2348

M
Mr.doob 已提交
2349
		uniforms.ambientLightColor.needsUpdate = value;
2350

B
Ben Houston 已提交
2351 2352 2353
		uniforms.directionalLights.needsUpdate = value;
		uniforms.pointLights.needsUpdate = value;
		uniforms.spotLights.needsUpdate = value;
2354
		uniforms.rectAreaLights.needsUpdate = value;
B
Ben Houston 已提交
2355
		uniforms.hemisphereLights.needsUpdate = value;
2356

M
Mr.doob 已提交
2357
	}
2358

M
Mr.doob 已提交
2359 2360
	// Textures

T
tschw 已提交
2361 2362 2363 2364 2365 2366
	function allocTextureUnit() {

		var textureUnit = _usedTextureUnits;

		if ( textureUnit >= capabilities.maxTextures ) {

M
Mugen87 已提交
2367
			console.warn( 'THREE.WebGLRenderer: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );
T
tschw 已提交
2368 2369 2370 2371 2372 2373 2374 2375 2376

		}

		_usedTextureUnits += 1;

		return textureUnit;

	}

2377
	this.allocTextureUnit = allocTextureUnit;
T
tschw 已提交
2378

2379
	// this.setTexture2D = setTexture2D;
M
Mr.doob 已提交
2380
	this.setTexture2D = ( function () {
T
tschw 已提交
2381

2382
		var warned = false;
T
tschw 已提交
2383

2384
		// backwards compatibility: peel texture.texture
W
WestLangley 已提交
2385
		return function setTexture2D( texture, slot ) {
T
tschw 已提交
2386

T
Takahiro 已提交
2387
			if ( texture && texture.isWebGLRenderTarget ) {
T
tschw 已提交
2388

2389
				if ( ! warned ) {
T
tschw 已提交
2390

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

2394
				}
T
tschw 已提交
2395

2396
				texture = texture.texture;
T
tschw 已提交
2397

2398
			}
T
tschw 已提交
2399

2400
			textures.setTexture2D( texture, slot );
T
tschw 已提交
2401

2402
		};
T
tschw 已提交
2403

2404
	}() );
T
tschw 已提交
2405

A
artur.trzesiok 已提交
2406
	this.setTexture3D = ( function () {
A
artur.trzesiok 已提交
2407

A
artur.trzesiok 已提交
2408 2409
		// backwards compatibility: peel texture.texture
		return function setTexture3D( texture, slot ) {
A
artur.trzesiok 已提交
2410

A
artur.trzesiok 已提交
2411 2412 2413 2414 2415
			textures.setTexture3D( texture, slot );

		};

	}() );
A
artur.trzesiok 已提交
2416

M
Mr.doob 已提交
2417
	this.setTexture = ( function () {
2418 2419 2420

		var warned = false;

W
WestLangley 已提交
2421
		return function setTexture( texture, slot ) {
2422 2423 2424 2425 2426 2427 2428 2429

			if ( ! warned ) {

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

			}

2430
			textures.setTexture2D( texture, slot );
2431 2432 2433 2434 2435

		};

	}() );

M
Mr.doob 已提交
2436
	this.setTextureCube = ( function () {
2437 2438 2439

		var warned = false;

W
WestLangley 已提交
2440
		return function setTextureCube( texture, slot ) {
2441 2442

			// backwards compatibility: peel texture.texture
T
Takahiro 已提交
2443
			if ( texture && texture.isWebGLRenderTargetCube ) {
2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457

				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 已提交
2458
			if ( ( texture && texture.isCubeTexture ) ||
2459
				( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {
2460 2461 2462 2463

				// CompressedTexture can have Array in image :/

				// this function alone should take care of cube textures
2464
				textures.setTextureCube( texture, slot );
2465 2466 2467 2468 2469

			} else {

				// assumed: texture property of THREE.WebGLRenderTargetCube

2470
				textures.setTextureCubeDynamic( texture, slot );
2471 2472 2473 2474 2475 2476

			}

		};

	}() );
T
tschw 已提交
2477

2478 2479 2480 2481 2482 2483 2484 2485
	//

	this.setFramebuffer = function ( value ) {

		_framebuffer = value;

	};

2486
	this.getRenderTarget = function () {
2487 2488 2489

		return _currentRenderTarget;

M
Michael Herzog 已提交
2490
	};
2491

2492
	this.setRenderTarget = function ( renderTarget ) {
M
Mr.doob 已提交
2493

2494 2495
		_currentRenderTarget = renderTarget;

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

2498
			textures.setupRenderTarget( renderTarget );
M
Mr.doob 已提交
2499 2500 2501

		}

2502
		var framebuffer = _framebuffer;
M
Mr.doob 已提交
2503
		var isCube = false;
M
Mr.doob 已提交
2504 2505 2506

		if ( renderTarget ) {

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

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

M
Mr.doob 已提交
2511
				framebuffer = __webglFramebuffer[ renderTarget.activeCubeFace ];
M
Mr.doob 已提交
2512
				isCube = true;
M
Mr.doob 已提交
2513

2514 2515 2516 2517
			} else if ( renderTarget.isWebGLMultisampleRenderTarget ) {

				framebuffer = properties.get( renderTarget ).__webglMultisampledFramebuffer;

M
Mr.doob 已提交
2518 2519
			} else {

M
Mr.doob 已提交
2520
				framebuffer = __webglFramebuffer;
M
Mr.doob 已提交
2521 2522 2523

			}

M
Mr.doob 已提交
2524
			_currentViewport.copy( renderTarget.viewport );
2525 2526
			_currentScissor.copy( renderTarget.scissor );
			_currentScissorTest = renderTarget.scissorTest;
2527

M
Mr.doob 已提交
2528 2529
		} else {

M
Mr.doob 已提交
2530
			_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );
2531
			_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );
2532
			_currentScissorTest = _scissorTest;
2533

M
Mr.doob 已提交
2534 2535
		}

M
Mr.doob 已提交
2536
		if ( _currentFramebuffer !== framebuffer ) {
M
Mr.doob 已提交
2537 2538 2539 2540 2541 2542

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

		}

M
Mr.doob 已提交
2543
		state.viewport( _currentViewport );
2544 2545
		state.scissor( _currentScissor );
		state.setScissorTest( _currentScissorTest );
2546

M
Mr.doob 已提交
2547 2548 2549
		if ( isCube ) {

			var textureProperties = properties.get( renderTarget.texture );
2550
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );
M
Mr.doob 已提交
2551 2552 2553

		}

M
Mr.doob 已提交
2554 2555
	};

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

0
06wj 已提交
2558
		if ( ! ( renderTarget && renderTarget.isWebGLRenderTarget ) ) {
2559

2560
			console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
G
gero3 已提交
2561
			return;
2562

G
gero3 已提交
2563
		}
2564

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

M
Mr.doob 已提交
2567
		if ( framebuffer ) {
2568

G
gero3 已提交
2569
			var restore = false;
2570

M
Mr.doob 已提交
2571
			if ( framebuffer !== _currentFramebuffer ) {
2572

M
Mr.doob 已提交
2573
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
2574

G
gero3 已提交
2575
				restore = true;
2576

G
gero3 已提交
2577
			}
2578

M
Mr.doob 已提交
2579
			try {
2580

M
Mr.doob 已提交
2581
				var texture = renderTarget.texture;
M
Mr.doob 已提交
2582 2583
				var textureFormat = texture.format;
				var textureType = texture.type;
2584

2585
				if ( textureFormat !== RGBAFormat && utils.convert( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {
2586

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

M
Mr.doob 已提交
2590
				}
2591

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

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

M
Mr.doob 已提交
2599
				}
2600

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

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

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

2607
						_gl.readPixels( x, y, width, height, utils.convert( textureFormat ), utils.convert( textureType ), buffer );
2608 2609

					}
2610

M
Mr.doob 已提交
2611
				} else {
M
Mr.doob 已提交
2612

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

				}
M
Mr.doob 已提交
2616

M
Mr.doob 已提交
2617
			} finally {
M
Mr.doob 已提交
2618

M
Mr.doob 已提交
2619 2620 2621
				if ( restore ) {

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

M
Mr.doob 已提交
2623 2624 2625
				}

			}
M
Mr.doob 已提交
2626 2627 2628

		}

M
Mr.doob 已提交
2629 2630
	};

2631
	this.copyFramebufferToTexture = function ( position, texture, level ) {
2632 2633 2634

		var width = texture.image.width;
		var height = texture.image.height;
2635
		var glFormat = utils.convert( texture.format );
2636 2637 2638

		this.setTexture2D( texture, 0 );

2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651
		_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 );

2652 2653 2654 2655 2656 2657 2658 2659 2660
		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 );

		}
2661 2662 2663

	};

M
Mr.doob 已提交
2664
}
R
Rich Harris 已提交
2665

T
Tristan VALCKE 已提交
2666

2667
export { WebGLRenderer };