WebGLRenderer.js 62.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
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 ( target ) {
M
Mugen87 已提交
433

434 435 436 437 438 439 440 441 442
		if ( target === undefined ) {

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

			target = new Vector4();

		}

		return target.copy( _currentViewport );
M
Mugen87 已提交
443 444 445

	};

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

448
		_viewport.set( x, y, width, height );
449
		state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );
450

M
Mr.doob 已提交
451 452
	};

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

455
		_scissor.set( x, y, width, height );
456
		state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );
457

M
Mr.doob 已提交
458 459
	};

460 461
	this.setScissorTest = function ( boolean ) {

462
		state.setScissorTest( _scissorTest = boolean );
M
Mr.doob 已提交
463 464 465 466 467

	};

	// Clearing

M
Mr.doob 已提交
468
	this.getClearColor = function () {
M
Mr.doob 已提交
469

470
		return background.getClearColor();
M
Mr.doob 已提交
471 472 473

	};

474
	this.setClearColor = function () {
475

476
		background.setClearColor.apply( background, arguments );
M
Mr.doob 已提交
477 478 479

	};

M
Mr.doob 已提交
480
	this.getClearAlpha = function () {
M
Mr.doob 已提交
481

482
		return background.getClearAlpha();
M
Mr.doob 已提交
483 484 485

	};

M
Mugen87 已提交
486
	this.setClearAlpha = function () {
M
Mr.doob 已提交
487

488
		background.setClearAlpha.apply( background, arguments );
M
Mr.doob 已提交
489 490 491 492 493 494 495 496 497 498 499 500

	};

	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 );
501 502 503 504 505

	};

	this.clearColor = function () {

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

	};

	this.clearDepth = function () {

M
Mr.doob 已提交
512
		this.clear( false, true, false );
513 514 515 516 517

	};

	this.clearStencil = function () {

M
Mr.doob 已提交
518
		this.clear( false, false, true );
M
Mr.doob 已提交
519 520 521

	};

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

M
Mr.doob 已提交
524
	this.dispose = function () {
D
dubejf 已提交
525 526

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

529
		renderLists.dispose();
530
		renderStates.dispose();
M
Mugen87 已提交
531 532
		properties.dispose();
		objects.dispose();
533

534
		vr.dispose();
535

536
		animation.stop();
B
brunnerh 已提交
537

D
dubejf 已提交
538 539
	};

M
Mr.doob 已提交
540
	// Events
M
Mr.doob 已提交
541

D
dubejf 已提交
542 543 544 545
	function onContextLost( event ) {

		event.preventDefault();

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

548 549 550 551
		_isContextLost = true;

	}

M
Mugen87 已提交
552
	function onContextRestore( /* event */ ) {
D
dubejf 已提交
553

554
		console.log( 'THREE.WebGLRenderer: Context Restored.' );
555 556

		_isContextLost = false;
D
dubejf 已提交
557

558
		initGLContext();
D
dubejf 已提交
559

M
Mr.doob 已提交
560
	}
D
dubejf 已提交
561

562
	function onMaterialDispose( event ) {
M
Mr.doob 已提交
563 564 565 566 567 568 569

		var material = event.target;

		material.removeEventListener( 'dispose', onMaterialDispose );

		deallocateMaterial( material );

570
	}
M
Mr.doob 已提交
571 572 573

	// Buffer deallocation

574
	function deallocateMaterial( material ) {
M
Mr.doob 已提交
575

576 577
		releaseMaterialProgramReference( material );

578
		properties.remove( material );
579

580
	}
581 582


583
	function releaseMaterialProgramReference( material ) {
584

585
		var programInfo = properties.get( material ).program;
M
Mr.doob 已提交
586 587 588

		material.program = undefined;

589
		if ( programInfo !== undefined ) {
M
Mr.doob 已提交
590

591
			programCache.releaseProgram( programInfo );
M
Mr.doob 已提交
592

M
Mr.doob 已提交
593 594
		}

595
	}
M
Mr.doob 已提交
596 597 598

	// Buffer rendering

M
Mr.doob 已提交
599
	function renderObjectImmediate( object, program ) {
M
Mr.doob 已提交
600 601 602

		object.render( function ( object ) {

M
Mr.doob 已提交
603
			_this.renderBufferImmediate( object, program );
M
Mr.doob 已提交
604 605 606 607 608

		} );

	}

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

611
		state.initAttributes();
612

613
		var buffers = properties.get( object );
614

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

620
		var programAttributes = program.getAttributes();
621

M
Mr.doob 已提交
622 623
		if ( object.hasPositions ) {

624
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );
M
Mr.doob 已提交
625
			_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );
626

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

		}

		if ( object.hasNormals ) {

634
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.normal );
M
Mr.doob 已提交
635
			_gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );
636

637 638
			state.enableAttribute( programAttributes.normal );
			_gl.vertexAttribPointer( programAttributes.normal, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
639 640 641

		}

642
		if ( object.hasUvs ) {
M
Mr.doob 已提交
643

644
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );
M
Mr.doob 已提交
645
			_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );
646

647
			state.enableAttribute( programAttributes.uv );
648
			_gl.vertexAttribPointer( programAttributes.uv, 2, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
649 650 651

		}

652
		if ( object.hasColors ) {
M
Mr.doob 已提交
653

654
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );
M
Mr.doob 已提交
655
			_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );
656

657 658
			state.enableAttribute( programAttributes.color );
			_gl.vertexAttribPointer( programAttributes.color, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
659 660 661

		}

662
		state.disableUnusedAttributes();
663

M
Mr.doob 已提交
664 665 666 667 668 669
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );

		object.count = 0;

	};

670
	this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {
671

672
		var frontFaceCW = ( object.isMesh && object.normalMatrix.determinant() < 0 );
673 674

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

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

M
Mr.doob 已提交
678
		var updateBuffers = false;
M
Mr.doob 已提交
679

680 681 682
		if ( _currentGeometryProgram.geometry !== geometry.id ||
			_currentGeometryProgram.program !== program.id ||
			_currentGeometryProgram.wireframe !== ( material.wireframe === true ) ) {
M
Mr.doob 已提交
683

M
Mr.doob 已提交
684 685
			_currentGeometryProgram.geometry = geometry.id;
			_currentGeometryProgram.program = program.id;
686
			_currentGeometryProgram.wireframe = material.wireframe === true;
M
Mr.doob 已提交
687 688 689 690
			updateBuffers = true;

		}

691
		if ( object.morphTargetInfluences ) {
692

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

			updateBuffers = true;

		}

699 700
		//

701
		var index = geometry.index;
702
		var position = geometry.attributes.position;
703
		var rangeFactor = 1;
704

705 706
		if ( material.wireframe === true ) {

707
			index = geometries.getWireframeAttribute( geometry );
708
			rangeFactor = 2;
709 710 711

		}

M
Mr.doob 已提交
712
		var attribute;
M
Mr.doob 已提交
713
		var renderer = bufferRenderer;
714

715
		if ( index !== null ) {
716

M
Mr.doob 已提交
717
			attribute = attributes.get( index );
718

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

722
		}
M
Mr.doob 已提交
723

724
		if ( updateBuffers ) {
M
Mr.doob 已提交
725

726
			setupVertexAttributes( material, program, geometry );
M
Mr.doob 已提交
727

728
			if ( index !== null ) {
729

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

			}

734
		}
735

736 737
		//

738
		var dataCount = Infinity;
739

M
Mr.doob 已提交
740
		if ( index !== null ) {
741

M
Mr.doob 已提交
742
			dataCount = index.count;
743

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

M
Mr.doob 已提交
746
			dataCount = position.count;
747

M
Mr.doob 已提交
748
		}
749

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

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

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

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

761 762
		if ( drawCount === 0 ) return;

M
Mr.doob 已提交
763
		//
764

765
		if ( object.isMesh ) {
766

767
			if ( material.wireframe === true ) {
768

769
				state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );
770
				renderer.setMode( _gl.LINES );
771

772
			} else {
M
Mr.doob 已提交
773 774

				switch ( object.drawMode ) {
775

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

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

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

				}
789

790
			}
791

792

793
		} else if ( object.isLine ) {
794

795
			var lineWidth = material.linewidth;
796

797
			if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material
798

799
			state.setLineWidth( lineWidth * getTargetPixelRatio() );
800

801
			if ( object.isLineSegments ) {
802

803
				renderer.setMode( _gl.LINES );
804

805 806 807 808
			} else if ( object.isLineLoop ) {

				renderer.setMode( _gl.LINE_LOOP );

809
			} else {
810

811
				renderer.setMode( _gl.LINE_STRIP );
812 813

			}
M
Mr.doob 已提交
814

815
		} else if ( object.isPoints ) {
816 817

			renderer.setMode( _gl.POINTS );
818

819 820 821 822
		} else if ( object.isSprite ) {

			renderer.setMode( _gl.TRIANGLES );

823
		}
824

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

			if ( geometry.maxInstancedCount > 0 ) {

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

J
jfranc 已提交
831
			}
832 833 834

		} else {

M
Mr.doob 已提交
835
			renderer.render( drawStart, drawCount );
836

M
Mr.doob 已提交
837 838 839 840
		}

	};

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

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

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

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

M
Mr.doob 已提交
850 851 852
			}

		}
B
Ben Adams 已提交
853

854 855
		state.initAttributes();

856
		var geometryAttributes = geometry.attributes;
857

858
		var programAttributes = program.getAttributes();
859

860
		var materialDefaultAttributeValues = material.defaultAttributeValues;
861

862
		for ( var name in programAttributes ) {
863

864
			var programAttribute = programAttributes[ name ];
M
Mr.doob 已提交
865

M
Mr.doob 已提交
866
			if ( programAttribute >= 0 ) {
M
Mr.doob 已提交
867

868
				var geometryAttribute = geometryAttributes[ name ];
869

M
Mr.doob 已提交
870
				if ( geometryAttribute !== undefined ) {
M
Mr.doob 已提交
871

872
					var normalized = geometryAttribute.normalized;
873
					var size = geometryAttribute.itemSize;
874

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

877 878 879 880
					// TODO Attribute may not be available on context restore

					if ( attribute === undefined ) continue;

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

A
aardgoose 已提交
885
					if ( geometryAttribute.isInterleavedBufferAttribute ) {
886

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

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

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

M
Mr.doob 已提交
895
							if ( geometry.maxInstancedCount === undefined ) {
896

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

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

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

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

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

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

M
Mr.doob 已提交
910
					} else {
B
Ben Adams 已提交
911

A
aardgoose 已提交
912
						if ( geometryAttribute.isInstancedBufferAttribute ) {
B
Ben Adams 已提交
913

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

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

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

M
Mr.doob 已提交
920
							}
B
Ben Adams 已提交
921

M
Mr.doob 已提交
922 923 924 925
						} else {

							state.enableAttribute( programAttribute );

M
Mr.doob 已提交
926
						}
B
Ben Adams 已提交
927

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

B
Ben Adams 已提交
931
					}
M
Mr.doob 已提交
932

933 934
				} else if ( materialDefaultAttributeValues !== undefined ) {

T
tschw 已提交
935
					var value = materialDefaultAttributeValues[ name ];
936

937
					if ( value !== undefined ) {
M
Mr.doob 已提交
938

939
						switch ( value.length ) {
M
Mr.doob 已提交
940

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

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

949 950 951
							case 4:
								_gl.vertexAttrib4fv( programAttribute, value );
								break;
952

953 954
							default:
								_gl.vertexAttrib1fv( programAttribute, value );
955 956

						}
M
Mr.doob 已提交
957 958 959 960 961 962 963 964

					}

				}

			}

		}
965

966
		state.disableUnusedAttributes();
967

M
Mr.doob 已提交
968 969
	}

M
Mr.doob 已提交
970
	// Compile
M
Mr.doob 已提交
971

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

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

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

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

981
				currentRenderState.pushLight( object );
982 983 984

				if ( object.castShadow ) {

985
					currentRenderState.pushShadow( object );
986 987

				}
M
Mr.doob 已提交
988

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

		} );

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

		scene.traverse( function ( object ) {

			if ( object.material ) {

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

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

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

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

G
gero3 已提交
1007
				} else {
M
Mr.doob 已提交
1008 1009 1010

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

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

G
gero3 已提交
1013
			}
M
Mr.doob 已提交
1014 1015

		} );
G
gero3 已提交
1016 1017

	};
1018

1019
	// Animation Loop
M
Mr.doob 已提交
1020

M
Mr.doob 已提交
1021
	var onAnimationFrameCallback = null;
1022

1023
	function onAnimationFrame( time ) {
1024

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

1028
	}
1029

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

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

1035
	this.setAnimationLoop = function ( callback ) {
1036

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

1040 1041
		animation.start();

1042 1043
	};

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

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

M
Mr.doob 已提交
1048
		var renderTarget, forceClear;
1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062

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

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

		}

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

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

		}
1063

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

1066
			console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );
M
Mr.doob 已提交
1067 1068 1069 1070
			return;

		}

1071 1072
		if ( _isContextLost ) return;

M
Mr.doob 已提交
1073 1074
		// reset caching for this frame

M
Mr.doob 已提交
1075 1076
		_currentGeometryProgram.geometry = null;
		_currentGeometryProgram.program = null;
1077
		_currentGeometryProgram.wireframe = false;
1078
		_currentMaterialId = - 1;
1079
		_currentCamera = null;
M
Mr.doob 已提交
1080 1081 1082

		// update scene graph

1083
		if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
M
Mr.doob 已提交
1084 1085 1086

		// update camera matrices and frustum

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

1089 1090 1091 1092 1093 1094
		if ( vr.enabled ) {

			camera = vr.getCamera( camera );

		}

1095 1096
		//

1097 1098
		currentRenderState = renderStates.get( scene, camera );
		currentRenderState.init();
1099

1100 1101
		scene.onBeforeRender( _this, scene, camera, renderTarget );

M
Mr.doob 已提交
1102 1103 1104
		_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
		_frustum.setFromMatrix( _projScreenMatrix );

T
tschw 已提交
1105
		_localClippingEnabled = this.localClippingEnabled;
M
Mr.doob 已提交
1106
		_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );
T
tschw 已提交
1107

1108 1109 1110
		currentRenderList = renderLists.get( scene, camera );
		currentRenderList.init();

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

M
Mr.doob 已提交
1113
		if ( _this.sortObjects === true ) {
1114

1115
			currentRenderList.sort();
M
Mr.doob 已提交
1116

1117 1118
		}

M
Mr.doob 已提交
1119
		//
M
Mr.doob 已提交
1120

T
tschw 已提交
1121
		if ( _clippingEnabled ) _clipping.beginShadows();
T
tschw 已提交
1122

1123
		var shadowsArray = currentRenderState.state.shadowsArray;
1124

1125
		shadowMap.render( shadowsArray, scene, camera );
1126

1127
		currentRenderState.setupLights( camera );
1128

T
tschw 已提交
1129
		if ( _clippingEnabled ) _clipping.endShadows();
T
tschw 已提交
1130

M
Mr.doob 已提交
1131 1132
		//

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

1135
		if ( renderTarget !== undefined ) {
1136

1137
			this.setRenderTarget( renderTarget );
1138 1139 1140

		}

M
Mr.doob 已提交
1141 1142
		//

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

1145
		// render scene
M
Mr.doob 已提交
1146

1147 1148 1149
		var opaqueObjects = currentRenderList.opaque;
		var transparentObjects = currentRenderList.transparent;

M
Mr.doob 已提交
1150 1151
		if ( scene.overrideMaterial ) {

1152
			var overrideMaterial = scene.overrideMaterial;
M
Mr.doob 已提交
1153

M
Mr.doob 已提交
1154 1155
			if ( opaqueObjects.length ) renderObjects( opaqueObjects, scene, camera, overrideMaterial );
			if ( transparentObjects.length ) renderObjects( transparentObjects, scene, camera, overrideMaterial );
1156

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

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

M
Mr.doob 已提交
1161
			if ( opaqueObjects.length ) renderObjects( opaqueObjects, scene, camera );
1162 1163 1164

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

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

1167
		}
M
Mr.doob 已提交
1168

1169
		//
M
Mr.doob 已提交
1170

M
Mr.doob 已提交
1171
		if ( renderTarget !== undefined ) {
M
Mr.doob 已提交
1172

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

1175
			textures.updateRenderTargetMipmap( renderTarget );
M
Mr.doob 已提交
1176

M
Mugen87 已提交
1177
			// resolve multisample renderbuffers to a single-sample texture if necessary
1178 1179 1180

			textures.updateMultisampleRenderTarget( renderTarget );

M
Mr.doob 已提交
1181 1182
		}

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

1185 1186 1187
		state.buffers.depth.setTest( true );
		state.buffers.depth.setMask( true );
		state.buffers.color.setMask( true );
M
Mr.doob 已提交
1188

1189
		state.setPolygonOffset( false );
1190

1191
		scene.onAfterRender( _this, scene, camera );
1192

M
Mr.doob 已提交
1193
		if ( vr.enabled ) {
1194

1195
			vr.submitFrame();
1196

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

M
Mr.doob 已提交
1199 1200
		// _gl.finish();

1201
		currentRenderList = null;
1202
		currentRenderState = null;
1203

M
Mr.doob 已提交
1204
	};
M
Mr.doob 已提交
1205

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

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

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

1212
		if ( visible ) {
1213

1214 1215 1216 1217 1218
			if ( object.isGroup ) {

				groupOrder = object.renderOrder;

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

1220
				currentRenderState.pushLight( object );
1221 1222 1223

				if ( object.castShadow ) {

1224
					currentRenderState.pushShadow( object );
1225 1226

				}
M
Mr.doob 已提交
1227

1228
			} else if ( object.isSprite ) {
M
Mr.doob 已提交
1229

1230
				if ( ! object.frustumCulled || _frustum.intersectsSprite( object ) ) {
1231

1232 1233 1234 1235 1236 1237 1238 1239 1240 1241
					if ( sortObjects ) {

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

					}

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

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

1244
				}
M
Mr.doob 已提交
1245

1246
			} else if ( object.isImmediateRenderObject ) {
M
Mr.doob 已提交
1247

1248
				if ( sortObjects ) {
M
Mr.doob 已提交
1249

1250 1251
					_vector3.setFromMatrixPosition( object.matrixWorld )
						.applyMatrix4( _projScreenMatrix );
M
Mr.doob 已提交
1252

1253
				}
M
Mr.doob 已提交
1254

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

1257
			} else if ( object.isMesh || object.isLine || object.isPoints ) {
1258

1259
				if ( object.isSkinnedMesh ) {
1260

1261
					object.skeleton.update();
1262

1263
				}
1264

1265
				if ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) {
1266

1267 1268 1269 1270 1271 1272
					if ( sortObjects ) {

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

					}
1273

1274 1275
					var geometry = objects.update( object );
					var material = object.material;
1276

1277
					if ( Array.isArray( material ) ) {
1278

1279
						var groups = geometry.groups;
1280

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

1283 1284
							var group = groups[ i ];
							var groupMaterial = material[ group.materialIndex ];
1285

1286
							if ( groupMaterial && groupMaterial.visible ) {
1287

1288
								currentRenderList.push( object, geometry, groupMaterial, groupOrder, _vector3.z, group );
1289 1290

							}
M
Mr.doob 已提交
1291

M
Mr.doob 已提交
1292
						}
M
Mr.doob 已提交
1293

1294
					} else if ( material.visible ) {
1295

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

1298
					}
M
Mr.doob 已提交
1299

1300
				}
M
Mr.doob 已提交
1301

1302
			}
M
Mr.doob 已提交
1303

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

M
Mr.doob 已提交
1306
		var children = object.children;
M
Mr.doob 已提交
1307

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

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

1312
		}
1313

1314
	}
M
Mr.doob 已提交
1315

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

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

1320
			var renderItem = renderList[ i ];
M
Mr.doob 已提交
1321

1322
			var object = renderItem.object;
M
Mr.doob 已提交
1323 1324 1325
			var geometry = renderItem.geometry;
			var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;
			var group = renderItem.group;
M
Mr.doob 已提交
1326

M
Mr.doob 已提交
1327
			if ( camera.isArrayCamera ) {
M
Mr.doob 已提交
1328

1329 1330
				_currentArrayCamera = camera;

M
Mr.doob 已提交
1331
				var cameras = camera.cameras;
M
Mr.doob 已提交
1332

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

M
Mr.doob 已提交
1335
					var camera2 = cameras[ j ];
M
Mr.doob 已提交
1336

1337
					if ( object.layers.test( camera2.layers ) ) {
1338

M
Mr.doob 已提交
1339 1340 1341 1342 1343 1344 1345
						if ( 'viewport' in camera2 ) { // XR

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

						} else {

							var bounds = camera2.bounds;
1346

M
Mr.doob 已提交
1347 1348 1349 1350
							var x = bounds.x * _width;
							var y = bounds.y * _height;
							var width = bounds.z * _width;
							var height = bounds.w * _height;
M
Mr.doob 已提交
1351

M
Mr.doob 已提交
1352 1353 1354
							state.viewport( _currentViewport.set( x, y, width, height ).multiplyScalar( _pixelRatio ) );

						}
1355

1356 1357
						currentRenderState.setupLights( camera2 );

1358 1359 1360
						renderObject( object, scene, camera2, geometry, material, group );

					}
M
Mr.doob 已提交
1361

M
Mr.doob 已提交
1362
				}
1363

M
Mr.doob 已提交
1364
			} else {
M
Mr.doob 已提交
1365

1366 1367
				_currentArrayCamera = null;

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

M
Mr.doob 已提交
1370
			}
M
Mr.doob 已提交
1371

1372
		}
M
Mr.doob 已提交
1373

1374
	}
G
gero3 已提交
1375

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

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

M
Mr.doob 已提交
1381 1382 1383 1384 1385
		object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
		object.normalMatrix.getNormalMatrix( object.modelViewMatrix );

		if ( object.isImmediateRenderObject ) {

1386
			state.setMaterial( material );
M
Mr.doob 已提交
1387 1388 1389

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

M
Mr.doob 已提交
1390 1391
			_currentGeometryProgram.geometry = null;
			_currentGeometryProgram.program = null;
1392
			_currentGeometryProgram.wireframe = false;
M
Mr.doob 已提交
1393

M
Mr.doob 已提交
1394
			renderObjectImmediate( object, program );
M
Mr.doob 已提交
1395 1396 1397

		} else {

M
Mugen87 已提交
1398
			_this.renderBufferDirect( camera, scene.fog, geometry, material, object, group );
M
Mr.doob 已提交
1399 1400 1401

		}

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

M
Mr.doob 已提交
1405 1406
	}

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

1409
		var materialProperties = properties.get( material );
G
gero3 已提交
1410

1411 1412
		var lights = currentRenderState.state.lights;
		var shadowsArray = currentRenderState.state.shadowsArray;
1413

M
Mr.doob 已提交
1414 1415 1416
		var lightsHash = materialProperties.lightsHash;
		var lightsStateHash = lights.state.hash;

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

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

1422
		var program = materialProperties.program;
T
tschw 已提交
1423
		var programChange = true;
1424

1425
		if ( program === undefined ) {
B
Ben Adams 已提交
1426

M
Mr.doob 已提交
1427 1428
			// new material
			material.addEventListener( 'dispose', onMaterialDispose );
B
Ben Adams 已提交
1429

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

M
Mr.doob 已提交
1432
			// changed glsl or parameters
1433
			releaseMaterialProgramReference( material );
B
Ben Adams 已提交
1434

M
Mr.doob 已提交
1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449
		} 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;
1450 1451 1452

			programChange = false;

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

T
tschw 已提交
1455
			// same glsl and uniform list
T
tschw 已提交
1456 1457
			return;

T
tschw 已提交
1458
		} else {
B
Ben Adams 已提交
1459

T
tschw 已提交
1460 1461
			// only rebuild uniform list
			programChange = false;
B
Ben Adams 已提交
1462 1463 1464

		}

1465
		if ( programChange ) {
B
Ben Adams 已提交
1466

1467
			if ( parameters.shaderID ) {
B
Ben Adams 已提交
1468

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

1471
				materialProperties.shader = {
1472
					name: material.type,
M
Mr.doob 已提交
1473
					uniforms: cloneUniforms( shader.uniforms ),
1474
					vertexShader: shader.vertexShader,
1475
					fragmentShader: shader.fragmentShader
1476
				};
B
Ben Adams 已提交
1477

1478
			} else {
B
Ben Adams 已提交
1479

1480
				materialProperties.shader = {
1481 1482 1483
					name: material.type,
					uniforms: material.uniforms,
					vertexShader: material.vertexShader,
1484
					fragmentShader: material.fragmentShader
1485
				};
G
gero3 已提交
1486

1487
			}
G
gero3 已提交
1488

1489
			material.onBeforeCompile( materialProperties.shader, _this );
G
gero3 已提交
1490

1491
			// Computing code again as onBeforeCompile may have changed the shaders
1492 1493
			code = programCache.getProgramCode( material, parameters );

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

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

		}

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

		if ( material.morphTargets ) {

			material.numSupportedMorphTargets = 0;

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

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

					material.numSupportedMorphTargets ++;

				}

			}

		}

		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

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

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

					material.numSupportedMorphNormals ++;

				}

			}

		}

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

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

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

		}

1547
		materialProperties.fog = fog;
1548

1549
		// store the light setup it was created for
M
Mr.doob 已提交
1550
		if ( lightsHash === undefined ) {
1551

M
Mr.doob 已提交
1552
			materialProperties.lightsHash = lightsHash = {};
1553 1554 1555

		}

M
Mr.doob 已提交
1556 1557 1558 1559 1560 1561 1562
		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;
1563

M
Mr.doob 已提交
1564
		if ( material.lights ) {
1565 1566 1567

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

1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580
			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;
1581
			// TODO (abelnation): add area lights shadow info to uniforms
1582

1583 1584
		}

T
tschw 已提交
1585 1586
		var progUniforms = materialProperties.program.getUniforms(),
			uniformsList =
1587
				WebGLUniforms.seqWithValue( progUniforms.seq, uniforms );
A
arose 已提交
1588

T
tschw 已提交
1589
		materialProperties.uniformsList = uniformsList;
A
arose 已提交
1590

M
Mr.doob 已提交
1591
	}
M
Mr.doob 已提交
1592

1593
	function setProgram( camera, fog, material, object ) {
M
Mr.doob 已提交
1594 1595 1596

		_usedTextureUnits = 0;

1597
		var materialProperties = properties.get( material );
1598
		var lights = currentRenderState.state.lights;
1599

M
Mr.doob 已提交
1600 1601 1602
		var lightsHash = materialProperties.lightsHash;
		var lightsStateHash = lights.state.hash;

T
tschw 已提交
1603 1604 1605 1606 1607
		if ( _clippingEnabled ) {

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

				var useCache =
1608 1609
					camera === _currentCamera &&
					material.id === _currentMaterialId;
T
tschw 已提交
1610 1611 1612 1613

				// we might want to call this function with some ClippingGroup
				// object instead of the material, once it becomes feasible
				// (#8465, #8379)
T
tschw 已提交
1614
				_clipping.setState(
1615 1616
					material.clippingPlanes, material.clipIntersection, material.clipShadows,
					camera, materialProperties, useCache );
T
tschw 已提交
1617 1618 1619 1620 1621

			}

		}

1622
		if ( material.needsUpdate === false ) {
1623

1624
			if ( materialProperties.program === undefined ) {
1625

1626
				material.needsUpdate = true;
1627

1628
			} else if ( material.fog && materialProperties.fog !== fog ) {
1629

M
Mr.doob 已提交
1630
				material.needsUpdate = true;
1631

M
Mr.doob 已提交
1632 1633 1634 1635 1636 1637 1638
			} 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 ) ) {
1639

1640
				material.needsUpdate = true;
1641

1642
			} else if ( materialProperties.numClippingPlanes !== undefined &&
1643
				( materialProperties.numClippingPlanes !== _clipping.numPlanes ||
M
Mr.doob 已提交
1644
				materialProperties.numIntersection !== _clipping.numIntersection ) ) {
1645 1646 1647

				material.needsUpdate = true;

1648
			}
1649 1650 1651 1652

		}

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

1654
			initMaterial( material, fog, object );
M
Mr.doob 已提交
1655 1656 1657 1658
			material.needsUpdate = false;

		}

1659
		var refreshProgram = false;
M
Mr.doob 已提交
1660
		var refreshMaterial = false;
1661
		var refreshLights = false;
M
Mr.doob 已提交
1662

1663
		var program = materialProperties.program,
1664
			p_uniforms = program.getUniforms(),
1665
			m_uniforms = materialProperties.shader.uniforms;
M
Mr.doob 已提交
1666

1667
		if ( state.useProgram( program.program ) ) {
M
Mr.doob 已提交
1668

1669
			refreshProgram = true;
M
Mr.doob 已提交
1670
			refreshMaterial = true;
1671
			refreshLights = true;
M
Mr.doob 已提交
1672 1673 1674 1675 1676 1677

		}

		if ( material.id !== _currentMaterialId ) {

			_currentMaterialId = material.id;
1678

M
Mr.doob 已提交
1679 1680 1681 1682
			refreshMaterial = true;

		}

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

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

G
gero3 已提交
1687
			if ( capabilities.logarithmicDepthBuffer ) {
1688

T
tschw 已提交
1689
				p_uniforms.setValue( _gl, 'logDepthBufFC',
1690
					2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
1691 1692 1693

			}

1694
			if ( _currentCamera !== camera ) {
1695

1696
				_currentCamera = camera;
1697 1698 1699 1700 1701 1702

				// 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 已提交
1703
				refreshLights = true;		// remains set until update done
1704 1705

			}
M
Mr.doob 已提交
1706

1707 1708 1709
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)

1710
			if ( material.isShaderMaterial ||
1711 1712 1713
				material.isMeshPhongMaterial ||
				material.isMeshStandardMaterial ||
				material.envMap ) {
1714

T
tschw 已提交
1715 1716 1717
				var uCamPos = p_uniforms.map.cameraPosition;

				if ( uCamPos !== undefined ) {
1718

T
tschw 已提交
1719
					uCamPos.setValue( _gl,
1720
						_vector3.setFromMatrixPosition( camera.matrixWorld ) );
1721 1722 1723 1724 1725

				}

			}

1726
			if ( material.isMeshPhongMaterial ||
1727 1728 1729 1730
				material.isMeshLambertMaterial ||
				material.isMeshBasicMaterial ||
				material.isMeshStandardMaterial ||
				material.isShaderMaterial ||
1731
				material.skinning ) {
1732

T
tschw 已提交
1733
				p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );
1734 1735 1736

			}

M
Mr.doob 已提交
1737 1738 1739 1740 1741 1742
		}

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

1743
		if ( material.skinning ) {
M
Mr.doob 已提交
1744

T
tschw 已提交
1745 1746
			p_uniforms.setOptional( _gl, object, 'bindMatrix' );
			p_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );
1747

T
tschw 已提交
1748
			var skeleton = object.skeleton;
1749

T
tschw 已提交
1750
			if ( skeleton ) {
1751

1752 1753
				var bones = skeleton.bones;

1754
				if ( capabilities.floatVertexTextures ) {
M
Mr.doob 已提交
1755

1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766
					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
1767
						size = _Math.ceilPowerOfTwo( size );
1768 1769 1770 1771 1772 1773
						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 );
1774
						boneTexture.needsUpdate = true;
1775 1776 1777 1778 1779 1780 1781

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

					}

M
Mr.doob 已提交
1782 1783
					p_uniforms.setValue( _gl, 'boneTexture', skeleton.boneTexture );
					p_uniforms.setValue( _gl, 'boneTextureSize', skeleton.boneTextureSize );
M
Mr.doob 已提交
1784

T
tschw 已提交
1785
				} else {
M
Mr.doob 已提交
1786

T
tschw 已提交
1787
					p_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );
M
Mr.doob 已提交
1788 1789 1790 1791 1792 1793 1794 1795 1796

				}

			}

		}

		if ( refreshMaterial ) {

1797 1798 1799
			p_uniforms.setValue( _gl, 'toneMappingExposure', _this.toneMappingExposure );
			p_uniforms.setValue( _gl, 'toneMappingWhitePoint', _this.toneMappingWhitePoint );

M
Mr.doob 已提交
1800
			if ( material.lights ) {
M
Mr.doob 已提交
1801

1802
				// the current material requires lighting info
M
Mr.doob 已提交
1803

T
tschw 已提交
1804 1805 1806 1807 1808 1809
				// 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 已提交
1810

T
tschw 已提交
1811
				markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
G
gero3 已提交
1812

T
tschw 已提交
1813
			}
G
gero3 已提交
1814

T
tschw 已提交
1815
			// refresh uniforms common to several materials
G
gero3 已提交
1816

T
tschw 已提交
1817
			if ( fog && material.fog ) {
G
gero3 已提交
1818

T
tschw 已提交
1819
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
1820 1821 1822

			}

1823
			if ( material.isMeshBasicMaterial ) {
M
Mr.doob 已提交
1824 1825 1826

				refreshUniformsCommon( m_uniforms, material );

1827
			} else if ( material.isMeshLambertMaterial ) {
M
Mr.doob 已提交
1828

1829 1830
				refreshUniformsCommon( m_uniforms, material );
				refreshUniformsLambert( m_uniforms, material );
M
Mr.doob 已提交
1831

1832
			} else if ( material.isMeshPhongMaterial ) {
M
Mr.doob 已提交
1833

1834
				refreshUniformsCommon( m_uniforms, material );
M
Mr.doob 已提交
1835

1836
				if ( material.isMeshToonMaterial ) {
M
Mr.doob 已提交
1837

1838
					refreshUniformsToon( m_uniforms, material );
M
Mr.doob 已提交
1839

1840
				} else {
1841

1842
					refreshUniformsPhong( m_uniforms, material );
1843

1844
				}
T
Takahiro 已提交
1845

1846
			} else if ( material.isMeshStandardMaterial ) {
T
Takahiro 已提交
1847

1848
				refreshUniformsCommon( m_uniforms, material );
1849

1850
				if ( material.isMeshPhysicalMaterial ) {
1851

1852
					refreshUniformsPhysical( m_uniforms, material );
W
WestLangley 已提交
1853

1854
				} else {
W
WestLangley 已提交
1855

1856
					refreshUniformsStandard( m_uniforms, material );
W
WestLangley 已提交
1857

1858
				}
W
WestLangley 已提交
1859

W
WestLangley 已提交
1860 1861 1862 1863 1864 1865
			} else if ( material.isMeshMatcapMaterial ) {

				refreshUniformsCommon( m_uniforms, material );

				refreshUniformsMatcap( m_uniforms, material );

1866
			} else if ( material.isMeshDepthMaterial ) {
M
Mr.doob 已提交
1867

1868
				refreshUniformsCommon( m_uniforms, material );
W
WestLangley 已提交
1869
				refreshUniformsDepth( m_uniforms, material );
1870

W
WestLangley 已提交
1871
			} else if ( material.isMeshDistanceMaterial ) {
1872

1873
				refreshUniformsCommon( m_uniforms, material );
W
WestLangley 已提交
1874
				refreshUniformsDistance( m_uniforms, material );
1875

1876
			} else if ( material.isMeshNormalMaterial ) {
M
Mr.doob 已提交
1877

1878
				refreshUniformsCommon( m_uniforms, material );
1879
				refreshUniformsNormal( m_uniforms, material );
M
Mr.doob 已提交
1880

1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894
			} else if ( material.isLineBasicMaterial ) {

				refreshUniformsLine( m_uniforms, material );

				if ( material.isLineDashedMaterial ) {

					refreshUniformsDash( m_uniforms, material );

				}

			} else if ( material.isPointsMaterial ) {

				refreshUniformsPoints( m_uniforms, material );

1895 1896 1897 1898
			} else if ( material.isSpriteMaterial ) {

				refreshUniformsSprites( m_uniforms, material );

1899 1900 1901 1902 1903
			} else if ( material.isShadowMaterial ) {

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

M
Mr.doob 已提交
1904 1905
			}

M
Mr.doob 已提交
1906 1907 1908
			// RectAreaLight Texture
			// TODO (mrdoob): Find a nicer implementation

1909 1910
			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 已提交
1911

1912
			WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, _this );
A
arose 已提交
1913 1914 1915

		}

1916 1917 1918 1919 1920 1921
		if ( material.isShaderMaterial && material.uniformsNeedUpdate === true ) {

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

		}
M
Mr.doob 已提交
1922

1923 1924 1925 1926 1927 1928
		if ( material.isSpriteMaterial ) {

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

		}

T
tschw 已提交
1929
		// common matrices
M
Mr.doob 已提交
1930

M
Mr.doob 已提交
1931 1932
		p_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix );
		p_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix );
T
tschw 已提交
1933
		p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );
A
arose 已提交
1934

T
tschw 已提交
1935
		return program;
A
arose 已提交
1936 1937 1938

	}

M
Mr.doob 已提交
1939 1940
	// Uniforms (refresh uniforms objects)

M
Mr.doob 已提交
1941
	function refreshUniformsCommon( uniforms, material ) {
M
Mr.doob 已提交
1942 1943 1944

		uniforms.opacity.value = material.opacity;

1945 1946 1947 1948 1949
		if ( material.color ) {

			uniforms.diffuse.value = material.color;

		}
M
Mr.doob 已提交
1950

1951
		if ( material.emissive ) {
M
Mr.doob 已提交
1952

1953
			uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );
M
Mr.doob 已提交
1954 1955 1956

		}

1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982
		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 已提交
1983
			uniforms.flipEnvMap.value = material.envMap.isCubeTexture ? - 1 : 1;
1984 1985 1986 1987

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

1988
			uniforms.maxMipLevel.value = properties.get( material.envMap ).__maxMipLevel;
1989

1990
		}
M
Mr.doob 已提交
1991

1992 1993 1994 1995 1996 1997 1998
		if ( material.lightMap ) {

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

		}

1999
		if ( material.aoMap ) {
2000

2001 2002
			uniforms.aoMap.value = material.aoMap;
			uniforms.aoMapIntensity.value = material.aoMapIntensity;
2003 2004 2005

		}

M
Mr.doob 已提交
2006
		// uv repeat and offset setting priorities
M
Mr.doob 已提交
2007 2008 2009 2010 2011
		// 1. color map
		// 2. specular map
		// 3. normal map
		// 4. bump map
		// 5. alpha map
2012
		// 6. emissive map
M
Mr.doob 已提交
2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023

		var uvScaleMap;

		if ( material.map ) {

			uvScaleMap = material.map;

		} else if ( material.specularMap ) {

			uvScaleMap = material.specularMap;

2024 2025 2026 2027
		} else if ( material.displacementMap ) {

			uvScaleMap = material.displacementMap;

M
Mr.doob 已提交
2028 2029 2030 2031 2032 2033 2034 2035
		} else if ( material.normalMap ) {

			uvScaleMap = material.normalMap;

		} else if ( material.bumpMap ) {

			uvScaleMap = material.bumpMap;

2036 2037 2038 2039 2040 2041 2042 2043
		} else if ( material.roughnessMap ) {

			uvScaleMap = material.roughnessMap;

		} else if ( material.metalnessMap ) {

			uvScaleMap = material.metalnessMap;

2044 2045 2046 2047
		} else if ( material.alphaMap ) {

			uvScaleMap = material.alphaMap;

2048 2049 2050 2051
		} else if ( material.emissiveMap ) {

			uvScaleMap = material.emissiveMap;

M
Mr.doob 已提交
2052 2053 2054 2055
		}

		if ( uvScaleMap !== undefined ) {

2056
			// backwards compatibility
2057
			if ( uvScaleMap.isWebGLRenderTarget ) {
M
Mr.doob 已提交
2058 2059 2060 2061 2062

				uvScaleMap = uvScaleMap.texture;

			}

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

W
WestLangley 已提交
2065
				uvScaleMap.updateMatrix();
M
Mr.doob 已提交
2066

W
WestLangley 已提交
2067
			}
2068

2069
			uniforms.uvTransform.value.copy( uvScaleMap.matrix );
M
Mr.doob 已提交
2070 2071 2072

		}

M
Mr.doob 已提交
2073
	}
M
Mr.doob 已提交
2074

M
Mr.doob 已提交
2075
	function refreshUniformsLine( uniforms, material ) {
M
Mr.doob 已提交
2076 2077 2078 2079

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

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

M
Mr.doob 已提交
2082
	function refreshUniformsDash( uniforms, material ) {
M
Mr.doob 已提交
2083 2084 2085 2086 2087

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

M
Mr.doob 已提交
2088
	}
M
Mr.doob 已提交
2089

M
Mr.doob 已提交
2090
	function refreshUniformsPoints( uniforms, material ) {
M
Mr.doob 已提交
2091

2092
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
2093
		uniforms.opacity.value = material.opacity;
2094
		uniforms.size.value = material.size * _pixelRatio;
2095
		uniforms.scale.value = _height * 0.5;
M
Mr.doob 已提交
2096 2097 2098

		uniforms.map.value = material.map;

2099 2100
		if ( material.map !== null ) {

W
WestLangley 已提交
2101
			if ( material.map.matrixAutoUpdate === true ) {
2102

W
WestLangley 已提交
2103
				material.map.updateMatrix();
W
WestLangley 已提交
2104 2105

			}
2106

2107
			uniforms.uvTransform.value.copy( material.map.matrix );
2108 2109 2110

		}

2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131
	}

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

M
Mr.doob 已提交
2134
	function refreshUniformsFog( uniforms, fog ) {
M
Mr.doob 已提交
2135 2136 2137

		uniforms.fogColor.value = fog.color;

2138
		if ( fog.isFog ) {
M
Mr.doob 已提交
2139 2140 2141 2142

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

2143
		} else if ( fog.isFogExp2 ) {
M
Mr.doob 已提交
2144 2145 2146 2147 2148

			uniforms.fogDensity.value = fog.density;

		}

M
Mr.doob 已提交
2149
	}
M
Mr.doob 已提交
2150

M
Mr.doob 已提交
2151
	function refreshUniformsLambert( uniforms, material ) {
2152 2153 2154 2155 2156 2157 2158 2159 2160

		if ( material.emissiveMap ) {

			uniforms.emissiveMap.value = material.emissiveMap;

		}

	}

M
Mr.doob 已提交
2161
	function refreshUniformsPhong( uniforms, material ) {
M
Mr.doob 已提交
2162

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

2166
		if ( material.emissiveMap ) {
2167

2168
			uniforms.emissiveMap.value = material.emissiveMap;
2169

2170
		}
M
Mr.doob 已提交
2171

2172 2173 2174 2175
		if ( material.bumpMap ) {

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

2178
		}
M
Mr.doob 已提交
2179

2180 2181 2182 2183
		if ( material.normalMap ) {

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

		}
M
Mr.doob 已提交
2187

2188 2189 2190 2191 2192
		if ( material.displacementMap ) {

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

2194
		}
2195

T
Takahiro 已提交
2196 2197 2198 2199 2200 2201
	}

	function refreshUniformsToon( uniforms, material ) {

		refreshUniformsPhong( uniforms, material );

T
Takahiro 已提交
2202
		if ( material.gradientMap ) {
T
Takahiro 已提交
2203

T
Takahiro 已提交
2204
			uniforms.gradientMap.value = material.gradientMap;
T
Takahiro 已提交
2205 2206 2207

		}

2208 2209
	}

M
Mr.doob 已提交
2210
	function refreshUniformsStandard( uniforms, material ) {
W
WestLangley 已提交
2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236

		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;
2237
			if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1;
W
WestLangley 已提交
2238 2239 2240 2241 2242 2243 2244

		}

		if ( material.normalMap ) {

			uniforms.normalMap.value = material.normalMap;
			uniforms.normalScale.value.copy( material.normalScale );
2245
			if ( material.side === BackSide ) uniforms.normalScale.value.negate();
W
WestLangley 已提交
2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265

		}

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

2268 2269 2270 2271
		refreshUniformsStandard( uniforms, material );

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

2272 2273 2274
		uniforms.clearCoat.value = material.clearCoat;
		uniforms.clearCoatRoughness.value = material.clearCoatRoughness;

W
WestLangley 已提交
2275 2276
	}

W
WestLangley 已提交
2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310
	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 已提交
2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338
	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;

	}

2339 2340 2341 2342 2343 2344
	function refreshUniformsNormal( uniforms, material ) {

		if ( material.bumpMap ) {

			uniforms.bumpMap.value = material.bumpMap;
			uniforms.bumpScale.value = material.bumpScale;
2345
			if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1;
2346 2347 2348 2349 2350 2351 2352

		}

		if ( material.normalMap ) {

			uniforms.normalMap.value = material.normalMap;
			uniforms.normalScale.value.copy( material.normalScale );
2353
			if ( material.side === BackSide ) uniforms.normalScale.value.negate();
2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366

		}

		if ( material.displacementMap ) {

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

		}

	}

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

M
Mr.doob 已提交
2369
	function markUniformsLightsNeedsUpdate( uniforms, value ) {
2370

M
Mr.doob 已提交
2371
		uniforms.ambientLightColor.needsUpdate = value;
2372

B
Ben Houston 已提交
2373 2374 2375
		uniforms.directionalLights.needsUpdate = value;
		uniforms.pointLights.needsUpdate = value;
		uniforms.spotLights.needsUpdate = value;
2376
		uniforms.rectAreaLights.needsUpdate = value;
B
Ben Houston 已提交
2377
		uniforms.hemisphereLights.needsUpdate = value;
2378

M
Mr.doob 已提交
2379
	}
2380

M
Mr.doob 已提交
2381 2382
	// Textures

T
tschw 已提交
2383 2384 2385 2386 2387 2388
	function allocTextureUnit() {

		var textureUnit = _usedTextureUnits;

		if ( textureUnit >= capabilities.maxTextures ) {

M
Mugen87 已提交
2389
			console.warn( 'THREE.WebGLRenderer: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );
T
tschw 已提交
2390 2391 2392 2393 2394 2395 2396 2397 2398

		}

		_usedTextureUnits += 1;

		return textureUnit;

	}

2399
	this.allocTextureUnit = allocTextureUnit;
T
tschw 已提交
2400

2401
	// this.setTexture2D = setTexture2D;
M
Mr.doob 已提交
2402
	this.setTexture2D = ( function () {
T
tschw 已提交
2403

2404
		var warned = false;
T
tschw 已提交
2405

2406
		// backwards compatibility: peel texture.texture
W
WestLangley 已提交
2407
		return function setTexture2D( texture, slot ) {
T
tschw 已提交
2408

T
Takahiro 已提交
2409
			if ( texture && texture.isWebGLRenderTarget ) {
T
tschw 已提交
2410

2411
				if ( ! warned ) {
T
tschw 已提交
2412

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

2416
				}
T
tschw 已提交
2417

2418
				texture = texture.texture;
T
tschw 已提交
2419

2420
			}
T
tschw 已提交
2421

2422
			textures.setTexture2D( texture, slot );
T
tschw 已提交
2423

2424
		};
T
tschw 已提交
2425

2426
	}() );
T
tschw 已提交
2427

A
artur.trzesiok 已提交
2428
	this.setTexture3D = ( function () {
A
artur.trzesiok 已提交
2429

A
artur.trzesiok 已提交
2430 2431
		// backwards compatibility: peel texture.texture
		return function setTexture3D( texture, slot ) {
A
artur.trzesiok 已提交
2432

A
artur.trzesiok 已提交
2433 2434 2435 2436 2437
			textures.setTexture3D( texture, slot );

		};

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

M
Mr.doob 已提交
2439
	this.setTexture = ( function () {
2440 2441 2442

		var warned = false;

W
WestLangley 已提交
2443
		return function setTexture( texture, slot ) {
2444 2445 2446 2447 2448 2449 2450 2451

			if ( ! warned ) {

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

			}

2452
			textures.setTexture2D( texture, slot );
2453 2454 2455 2456 2457

		};

	}() );

M
Mr.doob 已提交
2458
	this.setTextureCube = ( function () {
2459 2460 2461

		var warned = false;

W
WestLangley 已提交
2462
		return function setTextureCube( texture, slot ) {
2463 2464

			// backwards compatibility: peel texture.texture
T
Takahiro 已提交
2465
			if ( texture && texture.isWebGLRenderTargetCube ) {
2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479

				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 已提交
2480
			if ( ( texture && texture.isCubeTexture ) ||
2481
				( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {
2482 2483 2484 2485

				// CompressedTexture can have Array in image :/

				// this function alone should take care of cube textures
2486
				textures.setTextureCube( texture, slot );
2487 2488 2489 2490 2491

			} else {

				// assumed: texture property of THREE.WebGLRenderTargetCube

2492
				textures.setTextureCubeDynamic( texture, slot );
2493 2494 2495 2496 2497 2498

			}

		};

	}() );
T
tschw 已提交
2499

2500 2501 2502 2503 2504 2505 2506 2507
	//

	this.setFramebuffer = function ( value ) {

		_framebuffer = value;

	};

2508
	this.getRenderTarget = function () {
2509 2510 2511

		return _currentRenderTarget;

M
Michael Herzog 已提交
2512
	};
2513

2514
	this.setRenderTarget = function ( renderTarget ) {
M
Mr.doob 已提交
2515

2516 2517
		_currentRenderTarget = renderTarget;

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

2520
			textures.setupRenderTarget( renderTarget );
M
Mr.doob 已提交
2521 2522 2523

		}

2524
		var framebuffer = _framebuffer;
M
Mr.doob 已提交
2525
		var isCube = false;
M
Mr.doob 已提交
2526 2527 2528

		if ( renderTarget ) {

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

M
Mr.doob 已提交
2531
			if ( renderTarget.isWebGLRenderTargetCube ) {
M
Mr.doob 已提交
2532

M
Mr.doob 已提交
2533
				framebuffer = __webglFramebuffer[ renderTarget.activeCubeFace ];
M
Mr.doob 已提交
2534
				isCube = true;
M
Mr.doob 已提交
2535

2536 2537 2538 2539
			} else if ( renderTarget.isWebGLMultisampleRenderTarget ) {

				framebuffer = properties.get( renderTarget ).__webglMultisampledFramebuffer;

M
Mr.doob 已提交
2540 2541
			} else {

M
Mr.doob 已提交
2542
				framebuffer = __webglFramebuffer;
M
Mr.doob 已提交
2543 2544 2545

			}

M
Mr.doob 已提交
2546
			_currentViewport.copy( renderTarget.viewport );
2547 2548
			_currentScissor.copy( renderTarget.scissor );
			_currentScissorTest = renderTarget.scissorTest;
2549

M
Mr.doob 已提交
2550 2551
		} else {

M
Mr.doob 已提交
2552
			_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );
2553
			_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );
2554
			_currentScissorTest = _scissorTest;
2555

M
Mr.doob 已提交
2556 2557
		}

M
Mr.doob 已提交
2558
		if ( _currentFramebuffer !== framebuffer ) {
M
Mr.doob 已提交
2559 2560 2561 2562 2563 2564

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

		}

M
Mr.doob 已提交
2565
		state.viewport( _currentViewport );
2566 2567
		state.scissor( _currentScissor );
		state.setScissorTest( _currentScissorTest );
2568

M
Mr.doob 已提交
2569 2570 2571
		if ( isCube ) {

			var textureProperties = properties.get( renderTarget.texture );
2572
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );
M
Mr.doob 已提交
2573 2574 2575

		}

M
Mr.doob 已提交
2576 2577
	};

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

0
06wj 已提交
2580
		if ( ! ( renderTarget && renderTarget.isWebGLRenderTarget ) ) {
2581

2582
			console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
G
gero3 已提交
2583
			return;
2584

G
gero3 已提交
2585
		}
2586

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

M
Mr.doob 已提交
2589
		if ( framebuffer ) {
2590

G
gero3 已提交
2591
			var restore = false;
2592

M
Mr.doob 已提交
2593
			if ( framebuffer !== _currentFramebuffer ) {
2594

M
Mr.doob 已提交
2595
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
2596

G
gero3 已提交
2597
				restore = true;
2598

G
gero3 已提交
2599
			}
2600

M
Mr.doob 已提交
2601
			try {
2602

M
Mr.doob 已提交
2603
				var texture = renderTarget.texture;
M
Mr.doob 已提交
2604 2605
				var textureFormat = texture.format;
				var textureType = texture.type;
2606

2607
				if ( textureFormat !== RGBAFormat && utils.convert( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {
2608

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

M
Mr.doob 已提交
2612
				}
2613

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

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

M
Mr.doob 已提交
2621
				}
2622

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

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

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

2629
						_gl.readPixels( x, y, width, height, utils.convert( textureFormat ), utils.convert( textureType ), buffer );
2630 2631

					}
2632

M
Mr.doob 已提交
2633
				} else {
M
Mr.doob 已提交
2634

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

				}
M
Mr.doob 已提交
2638

M
Mr.doob 已提交
2639
			} finally {
M
Mr.doob 已提交
2640

M
Mr.doob 已提交
2641 2642 2643
				if ( restore ) {

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

M
Mr.doob 已提交
2645 2646 2647
				}

			}
M
Mr.doob 已提交
2648 2649 2650

		}

M
Mr.doob 已提交
2651 2652
	};

2653
	this.copyFramebufferToTexture = function ( position, texture, level ) {
2654 2655 2656

		var width = texture.image.width;
		var height = texture.image.height;
2657
		var glFormat = utils.convert( texture.format );
2658 2659 2660

		this.setTexture2D( texture, 0 );

2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673
		_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 );

2674 2675 2676 2677 2678 2679 2680 2681 2682
		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 );

		}
2683 2684 2685

	};

M
Mr.doob 已提交
2686
}
R
Rich Harris 已提交
2687

T
Tristan VALCKE 已提交
2688

2689
export { WebGLRenderer };