WebGLRenderer.js 58.7 KB
Newer Older
M
Mr.doob 已提交
1 2 3 4 5 6 7 8 9 10
import {
	REVISION,
	RGBAFormat,
	HalfFloatType,
	FloatType,
	UnsignedByteType,
	TriangleFanDrawMode,
	TriangleStripDrawMode,
	TrianglesDrawMode,
	NoColors,
11 12
	LinearToneMapping,
	BackSide
M
Mr.doob 已提交
13
} from '../constants.js';
B
bentok 已提交
14 15
import { _Math } from '../math/Math.js';
import { DataTexture } from '../textures/DataTexture.js';
M
Mr.doob 已提交
16 17 18
import { Frustum } from '../math/Frustum.js';
import { Matrix4 } from '../math/Matrix4.js';
import { ShaderLib } from './shaders/ShaderLib.js';
B
bentok 已提交
19 20
import { UniformsLib } from './shaders/UniformsLib.js';
import { UniformsUtils } from './shaders/UniformsUtils.js';
M
Mr.doob 已提交
21 22
import { Vector3 } from '../math/Vector3.js';
import { Vector4 } from '../math/Vector4.js';
B
bentok 已提交
23 24 25
import { WebGLAttributes } from './webgl/WebGLAttributes.js';
import { WebGLBackground } from './webgl/WebGLBackground.js';
import { WebGLBufferRenderer } from './webgl/WebGLBufferRenderer.js';
M
Mr.doob 已提交
26 27 28
import { WebGLCapabilities } from './webgl/WebGLCapabilities.js';
import { WebGLClipping } from './webgl/WebGLClipping.js';
import { WebGLExtensions } from './webgl/WebGLExtensions.js';
B
bentok 已提交
29
import { WebGLGeometries } from './webgl/WebGLGeometries.js';
M
Mr.doob 已提交
30 31 32
import { WebGLIndexedBufferRenderer } from './webgl/WebGLIndexedBufferRenderer.js';
import { WebGLInfo } from './webgl/WebGLInfo.js';
import { WebGLMorphtargets } from './webgl/WebGLMorphtargets.js';
B
bentok 已提交
33 34 35
import { WebGLObjects } from './webgl/WebGLObjects.js';
import { WebGLPrograms } from './webgl/WebGLPrograms.js';
import { WebGLProperties } from './webgl/WebGLProperties.js';
M
Mr.doob 已提交
36 37 38 39
import { WebGLRenderLists } from './webgl/WebGLRenderLists.js';
import { WebGLRenderStates } from './webgl/WebGLRenderStates.js';
import { WebGLShadowMap } from './webgl/WebGLShadowMap.js';
import { WebGLSpriteRenderer } from './webgl/WebGLSpriteRenderer.js';
B
bentok 已提交
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';
R
Rich Harris 已提交
45

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

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

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

	parameters = parameters || {};

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

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

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

M
Mr.doob 已提交
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
	// public properties

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

	// clearing

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

	// scene graph

	this.sortObjects = true;

T
tschw 已提交
90 91 92 93 94
	// user-defined clipping

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

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

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

101 102
	// physical lights

103
	this.physicallyCorrectLights = false;
104

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

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

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

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

	// internal properties

	var _this = this,

120 121
		_isContextLost = false,

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

124 125 126 127
		_currentRenderTarget = null,
		_currentFramebuffer = null,
		_currentMaterialId = - 1,
		_currentGeometryProgram = '',
128

129
		_currentCamera = null,
130
		_currentArrayCamera = null,
M
Mr.doob 已提交
131

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

136
		//
137

138
		_usedTextureUnits = 0,
M
Mr.doob 已提交
139

140
		//
M
Mr.doob 已提交
141

142 143
		_width = _canvas.width,
		_height = _canvas.height,
M
Mr.doob 已提交
144

145
		_pixelRatio = 1,
M
Mr.doob 已提交
146

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

151
		// frustum
M
Mr.doob 已提交
152

153
		_frustum = new Frustum(),
M
Mr.doob 已提交
154

155
		// clipping
T
tschw 已提交
156

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

161
		// camera matrices cache
M
Mr.doob 已提交
162

163
		_projScreenMatrix = new Matrix4(),
M
Mr.doob 已提交
164

M
Mugen87 已提交
165
		_vector3 = new Vector3();
A
Atrahasis 已提交
166

167 168 169 170 171
	function getTargetPixelRatio() {

		return _currentRenderTarget === null ? _pixelRatio : 1;

	}
172

M
Mr.doob 已提交
173 174 175 176
	// initialize

	var _gl;

M
Mr.doob 已提交
177 178
	try {

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

189 190
		// event listeners must be registered before WebGL context is created, see #12753

191
		_canvas.addEventListener( 'webglcontextlost', onContextLost, false );
192
		_canvas.addEventListener( 'webglcontextrestored', onContextRestore, false );
193

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

		if ( _gl === null ) {

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

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

			} else {

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

			}
M
Mr.doob 已提交
207 208 209

		}

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

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

	}

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

232
	var background, morphtargets, bufferRenderer, indexedBufferRenderer;
M
Mugen87 已提交
233
	var spriteRenderer;
234

235
	var utils;
236

237
	function initGLContext() {
238

239 240 241 242 243 244 245
		extensions = new WebGLExtensions( _gl );
		extensions.get( 'WEBGL_depth_texture' );
		extensions.get( 'OES_texture_float' );
		extensions.get( 'OES_texture_float_linear' );
		extensions.get( 'OES_texture_half_float' );
		extensions.get( 'OES_texture_half_float_linear' );
		extensions.get( 'OES_standard_derivatives' );
M
Mugen87 已提交
246
		extensions.get( 'OES_element_index_uint' );
247
		extensions.get( 'ANGLE_instanced_arrays' );
248

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

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

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

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

268
		background = new WebGLBackground( _this, state, objects, _premultipliedAlpha );
269

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

273
		spriteRenderer = new WebGLSpriteRenderer( _this, _gl, state, textures, capabilities );
274

M
Mugen87 已提交
275
		info.programs = programCache.programs;
276

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

285
	}
M
Mr.doob 已提交
286

287
	initGLContext();
M
Mr.doob 已提交
288

289
	// vr
M
Mr.doob 已提交
290

291
	var vr = new WebVRManager( _this );
M
Mr.doob 已提交
292

293
	this.vr = vr;
M
Mr.doob 已提交
294 295

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

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

299
	this.shadowMap = shadowMap;
M
Mr.doob 已提交
300

M
Mr.doob 已提交
301 302 303 304 305 306 307 308
	// API

	this.getContext = function () {

		return _gl;

	};

309 310 311 312 313 314
	this.getContextAttributes = function () {

		return _gl.getContextAttributes();

	};

315 316
	this.forceContextLoss = function () {

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

	};

322
	this.forceContextRestore = function () {
M
Mr.doob 已提交
323

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

	};

329 330
	this.getPixelRatio = function () {

331
		return _pixelRatio;
332 333 334 335 336

	};

	this.setPixelRatio = function ( value ) {

337 338 339 340
		if ( value === undefined ) return;

		_pixelRatio = value;

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

	};

345 346 347
	this.getSize = function () {

		return {
348 349
			width: _width,
			height: _height
350 351 352 353
		};

	};

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

356 357 358 359 360 361 362 363 364
		var device = vr.getDevice();

		if ( device && device.isPresenting ) {

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

		}

365 366 367
		_width = width;
		_height = height;

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

371
		if ( updateStyle !== false ) {
372

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

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

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

	};

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

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

	};

391 392 393 394 395 396 397 398 399 400 401 402 403 404
	this.setDrawingBufferSize = function ( width, height, pixelRatio ) {

		_width = width;
		_height = height;

		_pixelRatio = pixelRatio;

		_canvas.width = width * pixelRatio;
		_canvas.height = height * pixelRatio;

		this.setViewport( 0, 0, width, height );

	};

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

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

	};

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

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

M
Mr.doob 已提交
416 417
	};

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

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

M
Mr.doob 已提交
423 424
	};

425 426
	this.setScissorTest = function ( boolean ) {

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

	};

	// Clearing

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

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

	};

439
	this.setClearColor = function () {
440

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

	};

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

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

	};

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

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

	};

	this.clear = function ( color, depth, stencil ) {

		var bits = 0;

		if ( color === undefined || color ) bits |= _gl.COLOR_BUFFER_BIT;
		if ( depth === undefined || depth ) bits |= _gl.DEPTH_BUFFER_BIT;
		if ( stencil === undefined || stencil ) bits |= _gl.STENCIL_BUFFER_BIT;

		_gl.clear( bits );
466 467 468 469 470

	};

	this.clearColor = function () {

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

	};

	this.clearDepth = function () {

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

	};

	this.clearStencil = function () {

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

	};

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

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

	};

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

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

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

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

506
		vr.dispose();
507

B
Brunner 已提交
508
		stopAnimation();
B
brunnerh 已提交
509

D
dubejf 已提交
510 511
	};

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

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

		event.preventDefault();

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

520 521 522 523
		_isContextLost = true;

	}

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

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

		_isContextLost = false;
D
dubejf 已提交
529

530
		initGLContext();
D
dubejf 已提交
531

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

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

		var material = event.target;

		material.removeEventListener( 'dispose', onMaterialDispose );

		deallocateMaterial( material );

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

	// Buffer deallocation

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

548 549
		releaseMaterialProgramReference( material );

550
		properties.remove( material );
551

552
	}
553 554


555
	function releaseMaterialProgramReference( material ) {
556

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

		material.program = undefined;

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

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

M
Mr.doob 已提交
565 566
		}

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

	// Buffer rendering

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

		object.render( function ( object ) {

			_this.renderBufferImmediate( object, program, material );

		} );

	}

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

583
		state.initAttributes();
584

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

587 588 589 590
		if ( object.hasPositions && ! buffers.position ) buffers.position = _gl.createBuffer();
		if ( object.hasNormals && ! buffers.normal ) buffers.normal = _gl.createBuffer();
		if ( object.hasUvs && ! buffers.uv ) buffers.uv = _gl.createBuffer();
		if ( object.hasColors && ! buffers.color ) buffers.color = _gl.createBuffer();
M
Mr.doob 已提交
591

592
		var programAttributes = program.getAttributes();
593

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

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

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

		}

		if ( object.hasNormals ) {

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

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

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

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

617 618 619
					var nx = ( array[ i + 0 ] + array[ i + 3 ] + array[ i + 6 ] ) / 3;
					var ny = ( array[ i + 1 ] + array[ i + 4 ] + array[ i + 7 ] ) / 3;
					var nz = ( array[ i + 2 ] + array[ i + 5 ] + array[ i + 8 ] ) / 3;
M
Mr.doob 已提交
620

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

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

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

				}

			}

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

639
			state.enableAttribute( programAttributes.normal );
640

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

		}

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

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

650
			state.enableAttribute( programAttributes.uv );
651

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

		}

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

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

661
			state.enableAttribute( programAttributes.color );
662

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

		}

667
		state.disableUnusedAttributes();
668

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

		object.count = 0;

	};

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

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

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

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

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

		if ( geometryProgram !== _currentGeometryProgram ) {

			_currentGeometryProgram = geometryProgram;
			updateBuffers = true;

		}

693
		if ( object.morphTargetInfluences ) {
694

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

			updateBuffers = true;

		}

701 702
		//

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

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

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

		}

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

717
		if ( index !== null ) {
718

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

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

724
		}
M
Mr.doob 已提交
725

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

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

730
			if ( index !== null ) {
731

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

			}

736
		}
737

738 739
		//

740
		var dataCount = Infinity;
741

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

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

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

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

M
Mr.doob 已提交
750
		}
751

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

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

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

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

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

M
Mr.doob 已提交
765
		//
766

767
		if ( object.isMesh ) {
768

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

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

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

				switch ( object.drawMode ) {
777

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

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

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

				}
791

792
			}
793

794

795
		} else if ( object.isLine ) {
796

797
			var lineWidth = material.linewidth;
798

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

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

803
			if ( object.isLineSegments ) {
804

805
				renderer.setMode( _gl.LINES );
806

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

				renderer.setMode( _gl.LINE_LOOP );

811
			} else {
812

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

			}
M
Mr.doob 已提交
816

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

			renderer.setMode( _gl.POINTS );
820 821

		}
822

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

			if ( geometry.maxInstancedCount > 0 ) {

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

J
jfranc 已提交
829
			}
830 831 832

		} else {

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

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

	};

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

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

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

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

M
Mr.doob 已提交
848 849 850
			}

		}
B
Ben Adams 已提交
851

852 853
		state.initAttributes();

854
		var geometryAttributes = geometry.attributes;
855

856
		var programAttributes = program.getAttributes();
857

858
		var materialDefaultAttributeValues = material.defaultAttributeValues;
859

860
		for ( var name in programAttributes ) {
861

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

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

866
				var geometryAttribute = geometryAttributes[ name ];
867

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

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

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

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

					if ( attribute === undefined ) continue;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

							state.enableAttribute( programAttribute );

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

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

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

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

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

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

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

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

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

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

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

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

					}

				}

			}

		}
963

964
		state.disableUnusedAttributes();
965

M
Mr.doob 已提交
966 967
	}

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

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

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

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

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

979
				currentRenderState.pushLight( object );
980 981 982

				if ( object.castShadow ) {

983
					currentRenderState.pushShadow( object );
984 985

				}
M
Mr.doob 已提交
986

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

		} );

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

		scene.traverse( function ( object ) {

			if ( object.material ) {

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

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

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

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

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

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

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

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

		} );
G
gero3 已提交
1014 1015

	};
1016

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

1019 1020
	var isAnimating = false;
	var onAnimationFrame = null;
1021

B
Brunner 已提交
1022
	function startAnimation() {
1023

1024
		if ( isAnimating ) return;
1025

B
Brunner 已提交
1026
		requestAnimationLoopFrame();
M
Mugen87 已提交
1027

1028
		isAnimating = true;
1029

1030
	}
1031

B
Brunner 已提交
1032
	function stopAnimation() {
1033

1034
		isAnimating = false;
1035

1036
	}
1037

B
Brunner 已提交
1038
	function requestAnimationLoopFrame() {
1039 1040

		var device = vr.getDevice();
M
Mugen87 已提交
1041

1042
		if ( device && device.isPresenting ) {
1043

B
Brunner 已提交
1044
			device.requestAnimationFrame( animationLoop );
1045 1046 1047

		} else {

B
Brunner 已提交
1048
			window.requestAnimationFrame( animationLoop );
1049 1050

		}
1051

1052 1053
	}

B
Brunner 已提交
1054
	function animationLoop( time ) {
1055

B
Brunner 已提交
1056
		if ( isAnimating === false ) return;
1057

B
brunnerh 已提交
1058
		onAnimationFrame( time );
1059

B
Brunner 已提交
1060
		requestAnimationLoopFrame();
1061

1062 1063 1064
	}

	this.animate = function ( callback ) {
1065

1066
		onAnimationFrame = callback;
B
Brunner 已提交
1067
		onAnimationFrame !== null ? startAnimation() : stopAnimation();
1068 1069 1070

	};

M
Mr.doob 已提交
1071 1072 1073
	// Rendering

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

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

1077
			console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );
M
Mr.doob 已提交
1078 1079 1080 1081
			return;

		}

1082 1083
		if ( _isContextLost ) return;

M
Mr.doob 已提交
1084 1085
		// reset caching for this frame

1086
		_currentGeometryProgram = '';
1087
		_currentMaterialId = - 1;
1088
		_currentCamera = null;
M
Mr.doob 已提交
1089 1090 1091

		// update scene graph

1092
		if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
M
Mr.doob 已提交
1093 1094 1095

		// update camera matrices and frustum

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

1098 1099 1100 1101 1102 1103
		if ( vr.enabled ) {

			camera = vr.getCamera( camera );

		}

1104 1105
		//

1106 1107
		currentRenderState = renderStates.get( scene, camera );
		currentRenderState.init();
1108

1109 1110
		scene.onBeforeRender( _this, scene, camera, renderTarget );

M
Mr.doob 已提交
1111 1112 1113
		_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
		_frustum.setFromMatrix( _projScreenMatrix );

T
tschw 已提交
1114
		_localClippingEnabled = this.localClippingEnabled;
M
Mr.doob 已提交
1115
		_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );
T
tschw 已提交
1116

1117 1118 1119
		currentRenderList = renderLists.get( scene, camera );
		currentRenderList.init();

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

M
Mr.doob 已提交
1122
		if ( _this.sortObjects === true ) {
1123

1124
			currentRenderList.sort();
M
Mr.doob 已提交
1125

1126 1127
		}

M
Mr.doob 已提交
1128
		//
M
Mr.doob 已提交
1129

T
tschw 已提交
1130
		if ( _clippingEnabled ) _clipping.beginShadows();
T
tschw 已提交
1131

1132
		var shadowsArray = currentRenderState.state.shadowsArray;
1133

1134
		shadowMap.render( shadowsArray, scene, camera );
1135

1136
		currentRenderState.setupLights( camera );
1137

T
tschw 已提交
1138
		if ( _clippingEnabled ) _clipping.endShadows();
T
tschw 已提交
1139

M
Mr.doob 已提交
1140 1141
		//

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

1144 1145 1146 1147 1148 1149
		if ( renderTarget === undefined ) {

			renderTarget = null;

		}

M
Mr.doob 已提交
1150 1151
		this.setRenderTarget( renderTarget );

M
Mr.doob 已提交
1152 1153
		//

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

1156
		// render scene
M
Mr.doob 已提交
1157

1158 1159 1160
		var opaqueObjects = currentRenderList.opaque;
		var transparentObjects = currentRenderList.transparent;

M
Mr.doob 已提交
1161 1162
		if ( scene.overrideMaterial ) {

1163
			var overrideMaterial = scene.overrideMaterial;
M
Mr.doob 已提交
1164

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

M
Mr.doob 已提交
1168 1169 1170 1171
		} else {

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

M
Mr.doob 已提交
1172
			if ( opaqueObjects.length ) renderObjects( opaqueObjects, scene, camera );
M
Mr.doob 已提交
1173 1174 1175

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

M
Mr.doob 已提交
1176
			if ( transparentObjects.length ) renderObjects( transparentObjects, scene, camera );
M
Mr.doob 已提交
1177 1178 1179

		}

1180
		// custom renderers
M
Mr.doob 已提交
1181

1182
		var spritesArray = currentRenderState.state.spritesArray;
1183

1184
		spriteRenderer.render( spritesArray, scene, camera );
M
Mr.doob 已提交
1185 1186 1187

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

M
Mr.doob 已提交
1188 1189
		if ( renderTarget ) {

1190
			textures.updateRenderTargetMipmap( renderTarget );
M
Mr.doob 已提交
1191 1192 1193

		}

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

1196 1197 1198
		state.buffers.depth.setTest( true );
		state.buffers.depth.setMask( true );
		state.buffers.color.setMask( true );
M
Mr.doob 已提交
1199

1200
		state.setPolygonOffset( false );
1201

1202
		scene.onAfterRender( _this, scene, camera );
1203

M
Mr.doob 已提交
1204
		if ( vr.enabled ) {
1205

M
Mr.doob 已提交
1206
			vr.submitFrame();
1207

M
Mr.doob 已提交
1208
		}
M
Mr.doob 已提交
1209

M
Mr.doob 已提交
1210 1211
		// _gl.finish();

1212
		currentRenderList = null;
1213
		currentRenderState = null;
1214

M
Mr.doob 已提交
1215
	};
M
Mr.doob 已提交
1216

1217
	/*
M
Mr.doob 已提交
1218 1219
	// TODO Duplicated code (Frustum)

1220 1221
	var _sphere = new Sphere();

T
tschw 已提交
1222 1223 1224 1225 1226 1227 1228
	function isObjectViewable( object ) {

		var geometry = object.geometry;

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

M
Mr.doob 已提交
1229
		_sphere.copy( geometry.boundingSphere ).
1230
		applyMatrix4( object.matrixWorld );
M
Mr.doob 已提交
1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246

		return isSphereViewable( _sphere );

	}

	function isSpriteViewable( sprite ) {

		_sphere.center.set( 0, 0, 0 );
		_sphere.radius = 0.7071067811865476;
		_sphere.applyMatrix4( sprite.matrixWorld );

		return isSphereViewable( _sphere );

	}

	function isSphereViewable( sphere ) {
T
tschw 已提交
1247 1248

		if ( ! _frustum.intersectsSphere( sphere ) ) return false;
T
tschw 已提交
1249 1250 1251 1252

		var numPlanes = _clipping.numPlanes;

		if ( numPlanes === 0 ) return true;
T
tschw 已提交
1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264

		var planes = _this.clippingPlanes,

			center = sphere.center,
			negRad = - sphere.radius,
			i = 0;

		do {

			// out when deeper than radius in the negative halfspace
			if ( planes[ i ].distanceToPoint( center ) < negRad ) return false;

T
tschw 已提交
1265
		} while ( ++ i !== numPlanes );
T
tschw 已提交
1266 1267 1268 1269

		return true;

	}
1270
	*/
T
tschw 已提交
1271

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

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

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

1278
		if ( visible ) {
1279

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

1282
				currentRenderState.pushLight( object );
1283 1284 1285

				if ( object.castShadow ) {

1286
					currentRenderState.pushShadow( object );
1287 1288

				}
M
Mr.doob 已提交
1289

1290
			} else if ( object.isSprite ) {
M
Mr.doob 已提交
1291

1292
				if ( ! object.frustumCulled || _frustum.intersectsSprite( object ) ) {
1293

1294
					currentRenderState.pushSprite( object );
M
Mr.doob 已提交
1295

1296
				}
M
Mr.doob 已提交
1297

1298
			} else if ( object.isImmediateRenderObject ) {
M
Mr.doob 已提交
1299

1300
				if ( sortObjects ) {
M
Mr.doob 已提交
1301

1302 1303
					_vector3.setFromMatrixPosition( object.matrixWorld )
						.applyMatrix4( _projScreenMatrix );
M
Mr.doob 已提交
1304

1305
				}
M
Mr.doob 已提交
1306

1307
				currentRenderList.push( object, null, object.material, _vector3.z, null );
1308

1309
			} else if ( object.isMesh || object.isLine || object.isPoints ) {
1310

1311
				if ( object.isSkinnedMesh ) {
1312

1313
					object.skeleton.update();
1314

1315
				}
1316

1317
				if ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) {
1318

1319 1320 1321 1322 1323 1324
					if ( sortObjects ) {

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

					}
1325

1326 1327
					var geometry = objects.update( object );
					var material = object.material;
1328

1329
					if ( Array.isArray( material ) ) {
1330

1331
						var groups = geometry.groups;
1332

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

1335 1336
							var group = groups[ i ];
							var groupMaterial = material[ group.materialIndex ];
1337

1338
							if ( groupMaterial && groupMaterial.visible ) {
1339

1340 1341 1342
								currentRenderList.push( object, geometry, groupMaterial, _vector3.z, group );

							}
M
Mr.doob 已提交
1343

M
Mr.doob 已提交
1344
						}
M
Mr.doob 已提交
1345

1346
					} else if ( material.visible ) {
1347

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

1350
					}
M
Mr.doob 已提交
1351

1352
				}
M
Mr.doob 已提交
1353

1354
			}
M
Mr.doob 已提交
1355

M
Mr.doob 已提交
1356
		}
M
Mr.doob 已提交
1357

M
Mr.doob 已提交
1358
		var children = object.children;
M
Mr.doob 已提交
1359

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

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

1364
		}
1365

1366
	}
M
Mr.doob 已提交
1367

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

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

1372
			var renderItem = renderList[ i ];
M
Mr.doob 已提交
1373

1374
			var object = renderItem.object;
M
Mr.doob 已提交
1375 1376 1377
			var geometry = renderItem.geometry;
			var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;
			var group = renderItem.group;
M
Mr.doob 已提交
1378

M
Mr.doob 已提交
1379
			if ( camera.isArrayCamera ) {
M
Mr.doob 已提交
1380

1381 1382
				_currentArrayCamera = camera;

M
Mr.doob 已提交
1383
				var cameras = camera.cameras;
M
Mr.doob 已提交
1384

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

M
Mr.doob 已提交
1387
					var camera2 = cameras[ j ];
M
Mr.doob 已提交
1388

1389
					if ( object.layers.test( camera2.layers ) ) {
1390

1391
						var bounds = camera2.bounds;
1392

1393 1394 1395 1396
						var x = bounds.x * _width;
						var y = bounds.y * _height;
						var width = bounds.z * _width;
						var height = bounds.w * _height;
M
Mr.doob 已提交
1397

1398
						state.viewport( _currentViewport.set( x, y, width, height ).multiplyScalar( _pixelRatio ) );
1399 1400 1401 1402

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

					}
M
Mr.doob 已提交
1403

M
Mr.doob 已提交
1404
				}
1405

M
Mr.doob 已提交
1406
			} else {
M
Mr.doob 已提交
1407

1408 1409
				_currentArrayCamera = null;

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

M
Mr.doob 已提交
1412
			}
M
Mr.doob 已提交
1413

1414
		}
M
Mr.doob 已提交
1415

1416
	}
G
gero3 已提交
1417

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

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

M
Mr.doob 已提交
1423 1424 1425 1426 1427
		object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
		object.normalMatrix.getNormalMatrix( object.modelViewMatrix );

		if ( object.isImmediateRenderObject ) {

1428 1429 1430
			var frontFaceCW = ( object.isMesh && object.matrixWorld.determinant() < 0 );

			state.setMaterial( material, frontFaceCW );
M
Mr.doob 已提交
1431 1432 1433 1434 1435 1436 1437 1438 1439

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

			_currentGeometryProgram = '';

			renderObjectImmediate( object, program, material );

		} else {

M
Mugen87 已提交
1440
			_this.renderBufferDirect( camera, scene.fog, geometry, material, object, group );
M
Mr.doob 已提交
1441 1442 1443

		}

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

M
Mr.doob 已提交
1447 1448
	}

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

1451
		var materialProperties = properties.get( material );
G
gero3 已提交
1452

1453 1454
		var lights = currentRenderState.state.lights;
		var shadowsArray = currentRenderState.state.shadowsArray;
1455

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

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

1461
		var program = materialProperties.program;
T
tschw 已提交
1462
		var programChange = true;
1463

1464
		if ( program === undefined ) {
B
Ben Adams 已提交
1465

M
Mr.doob 已提交
1466 1467
			// new material
			material.addEventListener( 'dispose', onMaterialDispose );
B
Ben Adams 已提交
1468

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

M
Mr.doob 已提交
1471
			// changed glsl or parameters
1472
			releaseMaterialProgramReference( material );
B
Ben Adams 已提交
1473

1474 1475 1476 1477 1478
		} else if ( materialProperties.lightsHash !== lights.state.hash ) {

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

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

T
tschw 已提交
1481
			// same glsl and uniform list
T
tschw 已提交
1482 1483
			return;

T
tschw 已提交
1484
		} else {
B
Ben Adams 已提交
1485

T
tschw 已提交
1486 1487
			// only rebuild uniform list
			programChange = false;
B
Ben Adams 已提交
1488 1489 1490

		}

1491
		if ( programChange ) {
B
Ben Adams 已提交
1492

1493
			if ( parameters.shaderID ) {
B
Ben Adams 已提交
1494

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

1497
				materialProperties.shader = {
1498
					name: material.type,
1499
					uniforms: UniformsUtils.clone( shader.uniforms ),
1500
					vertexShader: shader.vertexShader,
1501
					fragmentShader: shader.fragmentShader
1502
				};
B
Ben Adams 已提交
1503

1504
			} else {
B
Ben Adams 已提交
1505

1506
				materialProperties.shader = {
1507 1508 1509
					name: material.type,
					uniforms: material.uniforms,
					vertexShader: material.vertexShader,
1510
					fragmentShader: material.fragmentShader
1511
				};
G
gero3 已提交
1512

1513
			}
G
gero3 已提交
1514

1515
			material.onBeforeCompile( materialProperties.shader, _this );
G
gero3 已提交
1516

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

1519 1520
			materialProperties.program = program;
			material.program = program;
1521 1522 1523

		}

1524
		var programAttributes = program.getAttributes();
M
Mr.doob 已提交
1525 1526 1527 1528 1529

		if ( material.morphTargets ) {

			material.numSupportedMorphTargets = 0;

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

1532
				if ( programAttributes[ 'morphTarget' + i ] >= 0 ) {
M
Mr.doob 已提交
1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545

					material.numSupportedMorphTargets ++;

				}

			}

		}

		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

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

1548
				if ( programAttributes[ 'morphNormal' + i ] >= 0 ) {
M
Mr.doob 已提交
1549 1550 1551 1552 1553 1554 1555 1556 1557

					material.numSupportedMorphNormals ++;

				}

			}

		}

1558
		var uniforms = materialProperties.shader.uniforms;
T
tschw 已提交
1559

1560
		if ( ! material.isShaderMaterial &&
1561 1562
			! material.isRawShaderMaterial ||
			material.clipping === true ) {
T
tschw 已提交
1563

T
tschw 已提交
1564
			materialProperties.numClippingPlanes = _clipping.numPlanes;
1565
			materialProperties.numIntersection = _clipping.numIntersection;
T
tschw 已提交
1566
			uniforms.clippingPlanes = _clipping.uniform;
T
tschw 已提交
1567 1568 1569

		}

1570
		materialProperties.fog = fog;
1571

1572
		// store the light setup it was created for
1573

1574
		materialProperties.lightsHash = lights.state.hash;
1575

M
Mr.doob 已提交
1576
		if ( material.lights ) {
1577 1578 1579

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

1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592
			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;
1593
			// TODO (abelnation): add area lights shadow info to uniforms
1594

1595 1596
		}

T
tschw 已提交
1597 1598
		var progUniforms = materialProperties.program.getUniforms(),
			uniformsList =
1599
				WebGLUniforms.seqWithValue( progUniforms.seq, uniforms );
A
arose 已提交
1600

T
tschw 已提交
1601
		materialProperties.uniformsList = uniformsList;
A
arose 已提交
1602

M
Mr.doob 已提交
1603
	}
M
Mr.doob 已提交
1604

1605
	function setProgram( camera, fog, material, object ) {
M
Mr.doob 已提交
1606 1607 1608

		_usedTextureUnits = 0;

1609
		var materialProperties = properties.get( material );
1610
		var lights = currentRenderState.state.lights;
1611

T
tschw 已提交
1612 1613 1614 1615 1616
		if ( _clippingEnabled ) {

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

				var useCache =
1617 1618
					camera === _currentCamera &&
					material.id === _currentMaterialId;
T
tschw 已提交
1619 1620 1621 1622

				// we might want to call this function with some ClippingGroup
				// object instead of the material, once it becomes feasible
				// (#8465, #8379)
T
tschw 已提交
1623
				_clipping.setState(
1624 1625
					material.clippingPlanes, material.clipIntersection, material.clipShadows,
					camera, materialProperties, useCache );
T
tschw 已提交
1626 1627 1628 1629 1630

			}

		}

1631
		if ( material.needsUpdate === false ) {
1632

1633
			if ( materialProperties.program === undefined ) {
1634

1635
				material.needsUpdate = true;
1636

1637
			} else if ( material.fog && materialProperties.fog !== fog ) {
1638

M
Mr.doob 已提交
1639
				material.needsUpdate = true;
1640

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

1643
				material.needsUpdate = true;
1644

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

				material.needsUpdate = true;

1651
			}
1652 1653 1654 1655

		}

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

1657
			initMaterial( material, fog, object );
M
Mr.doob 已提交
1658 1659 1660 1661
			material.needsUpdate = false;

		}

1662
		var refreshProgram = false;
M
Mr.doob 已提交
1663
		var refreshMaterial = false;
1664
		var refreshLights = false;
M
Mr.doob 已提交
1665

1666
		var program = materialProperties.program,
1667
			p_uniforms = program.getUniforms(),
1668
			m_uniforms = materialProperties.shader.uniforms;
M
Mr.doob 已提交
1669

1670
		if ( state.useProgram( program.program ) ) {
M
Mr.doob 已提交
1671

1672
			refreshProgram = true;
M
Mr.doob 已提交
1673
			refreshMaterial = true;
1674
			refreshLights = true;
M
Mr.doob 已提交
1675 1676 1677 1678 1679 1680

		}

		if ( material.id !== _currentMaterialId ) {

			_currentMaterialId = material.id;
1681

M
Mr.doob 已提交
1682 1683 1684 1685
			refreshMaterial = true;

		}

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

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

G
gero3 已提交
1690
			if ( capabilities.logarithmicDepthBuffer ) {
1691

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

			}

1697
			// Avoid unneeded uniform updates per ArrayCamera's sub-camera
1698

1699
			if ( _currentCamera !== ( _currentArrayCamera || camera ) ) {
1700

1701
				_currentCamera = ( _currentArrayCamera || camera );
1702 1703 1704 1705 1706 1707

				// 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 已提交
1708
				refreshLights = true;		// remains set until update done
1709 1710

			}
M
Mr.doob 已提交
1711

1712 1713 1714
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)

1715
			if ( material.isShaderMaterial ||
1716 1717 1718
				material.isMeshPhongMaterial ||
				material.isMeshStandardMaterial ||
				material.envMap ) {
1719

T
tschw 已提交
1720 1721 1722
				var uCamPos = p_uniforms.map.cameraPosition;

				if ( uCamPos !== undefined ) {
1723

T
tschw 已提交
1724
					uCamPos.setValue( _gl,
1725
						_vector3.setFromMatrixPosition( camera.matrixWorld ) );
1726 1727 1728 1729 1730

				}

			}

1731
			if ( material.isMeshPhongMaterial ||
1732 1733 1734 1735
				material.isMeshLambertMaterial ||
				material.isMeshBasicMaterial ||
				material.isMeshStandardMaterial ||
				material.isShaderMaterial ||
1736
				material.skinning ) {
1737

T
tschw 已提交
1738
				p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );
1739 1740 1741

			}

M
Mr.doob 已提交
1742 1743 1744 1745 1746 1747
		}

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

1748
		if ( material.skinning ) {
M
Mr.doob 已提交
1749

T
tschw 已提交
1750 1751
			p_uniforms.setOptional( _gl, object, 'bindMatrix' );
			p_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );
1752

T
tschw 已提交
1753
			var skeleton = object.skeleton;
1754

T
tschw 已提交
1755
			if ( skeleton ) {
1756

1757 1758
				var bones = skeleton.bones;

1759
				if ( capabilities.floatVertexTextures ) {
M
Mr.doob 已提交
1760

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

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

					}

M
Mr.doob 已提交
1787 1788
					p_uniforms.setValue( _gl, 'boneTexture', skeleton.boneTexture );
					p_uniforms.setValue( _gl, 'boneTextureSize', skeleton.boneTextureSize );
M
Mr.doob 已提交
1789

T
tschw 已提交
1790
				} else {
M
Mr.doob 已提交
1791

T
tschw 已提交
1792
					p_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );
M
Mr.doob 已提交
1793 1794 1795 1796 1797 1798 1799 1800 1801

				}

			}

		}

		if ( refreshMaterial ) {

1802 1803 1804
			p_uniforms.setValue( _gl, 'toneMappingExposure', _this.toneMappingExposure );
			p_uniforms.setValue( _gl, 'toneMappingWhitePoint', _this.toneMappingWhitePoint );

M
Mr.doob 已提交
1805
			if ( material.lights ) {
M
Mr.doob 已提交
1806

1807
				// the current material requires lighting info
M
Mr.doob 已提交
1808

T
tschw 已提交
1809 1810 1811 1812 1813 1814
				// 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 已提交
1815

T
tschw 已提交
1816
				markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
G
gero3 已提交
1817

T
tschw 已提交
1818
			}
G
gero3 已提交
1819

T
tschw 已提交
1820
			// refresh uniforms common to several materials
G
gero3 已提交
1821

T
tschw 已提交
1822
			if ( fog && material.fog ) {
G
gero3 已提交
1823

T
tschw 已提交
1824
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
1825 1826 1827

			}

1828
			if ( material.isMeshBasicMaterial ) {
M
Mr.doob 已提交
1829 1830 1831

				refreshUniformsCommon( m_uniforms, material );

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

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

1837
			} else if ( material.isMeshPhongMaterial ) {
M
Mr.doob 已提交
1838

1839
				refreshUniformsCommon( m_uniforms, material );
M
Mr.doob 已提交
1840

1841
				if ( material.isMeshToonMaterial ) {
M
Mr.doob 已提交
1842

1843
					refreshUniformsToon( m_uniforms, material );
M
Mr.doob 已提交
1844

1845
				} else {
1846

1847
					refreshUniformsPhong( m_uniforms, material );
1848

1849
				}
T
Takahiro 已提交
1850

1851
			} else if ( material.isMeshStandardMaterial ) {
T
Takahiro 已提交
1852

1853
				refreshUniformsCommon( m_uniforms, material );
1854

1855
				if ( material.isMeshPhysicalMaterial ) {
1856

1857
					refreshUniformsPhysical( m_uniforms, material );
W
WestLangley 已提交
1858

1859
				} else {
W
WestLangley 已提交
1860

1861
					refreshUniformsStandard( m_uniforms, material );
W
WestLangley 已提交
1862

1863
				}
W
WestLangley 已提交
1864

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

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

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

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

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

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

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

				refreshUniformsLine( m_uniforms, material );

				if ( material.isLineDashedMaterial ) {

					refreshUniformsDash( m_uniforms, material );

				}

			} else if ( material.isPointsMaterial ) {

				refreshUniformsPoints( m_uniforms, material );

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

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

M
Mr.doob 已提交
1899 1900
			}

M
Mr.doob 已提交
1901 1902 1903
			// RectAreaLight Texture
			// TODO (mrdoob): Find a nicer implementation

1904 1905
			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 已提交
1906

1907
			WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, _this );
A
arose 已提交
1908 1909 1910

		}

1911 1912 1913 1914 1915 1916
		if ( material.isShaderMaterial && material.uniformsNeedUpdate === true ) {

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

		}
M
Mr.doob 已提交
1917

T
tschw 已提交
1918
		// common matrices
M
Mr.doob 已提交
1919

M
Mr.doob 已提交
1920 1921
		p_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix );
		p_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix );
T
tschw 已提交
1922
		p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );
A
arose 已提交
1923

T
tschw 已提交
1924
		return program;
A
arose 已提交
1925 1926 1927

	}

M
Mr.doob 已提交
1928 1929
	// Uniforms (refresh uniforms objects)

M
Mr.doob 已提交
1930
	function refreshUniformsCommon( uniforms, material ) {
M
Mr.doob 已提交
1931 1932 1933

		uniforms.opacity.value = material.opacity;

1934 1935 1936 1937 1938
		if ( material.color ) {

			uniforms.diffuse.value = material.color;

		}
M
Mr.doob 已提交
1939

1940
		if ( material.emissive ) {
M
Mr.doob 已提交
1941

1942
			uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );
M
Mr.doob 已提交
1943 1944 1945

		}

1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976
		if ( material.map ) {

			uniforms.map.value = material.map;

		}

		if ( material.alphaMap ) {

			uniforms.alphaMap.value = material.alphaMap;

		}

		if ( material.specularMap ) {

			uniforms.specularMap.value = material.specularMap;

		}

		if ( material.envMap ) {

			uniforms.envMap.value = material.envMap;

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

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

1977
			uniforms.maxMipLevel.value = properties.get( material.envMap ).__maxMipLevel;
1978

1979
		}
M
Mr.doob 已提交
1980

1981 1982 1983 1984 1985 1986 1987
		if ( material.lightMap ) {

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

		}

1988
		if ( material.aoMap ) {
1989

1990 1991
			uniforms.aoMap.value = material.aoMap;
			uniforms.aoMapIntensity.value = material.aoMapIntensity;
1992 1993 1994

		}

M
Mr.doob 已提交
1995
		// uv repeat and offset setting priorities
M
Mr.doob 已提交
1996 1997 1998 1999 2000
		// 1. color map
		// 2. specular map
		// 3. normal map
		// 4. bump map
		// 5. alpha map
2001
		// 6. emissive map
M
Mr.doob 已提交
2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012

		var uvScaleMap;

		if ( material.map ) {

			uvScaleMap = material.map;

		} else if ( material.specularMap ) {

			uvScaleMap = material.specularMap;

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

			uvScaleMap = material.displacementMap;

M
Mr.doob 已提交
2017 2018 2019 2020 2021 2022 2023 2024
		} else if ( material.normalMap ) {

			uvScaleMap = material.normalMap;

		} else if ( material.bumpMap ) {

			uvScaleMap = material.bumpMap;

2025 2026 2027 2028 2029 2030 2031 2032
		} else if ( material.roughnessMap ) {

			uvScaleMap = material.roughnessMap;

		} else if ( material.metalnessMap ) {

			uvScaleMap = material.metalnessMap;

2033 2034 2035 2036
		} else if ( material.alphaMap ) {

			uvScaleMap = material.alphaMap;

2037 2038 2039 2040
		} else if ( material.emissiveMap ) {

			uvScaleMap = material.emissiveMap;

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

		if ( uvScaleMap !== undefined ) {

2045
			// backwards compatibility
2046
			if ( uvScaleMap.isWebGLRenderTarget ) {
M
Mr.doob 已提交
2047 2048 2049 2050 2051

				uvScaleMap = uvScaleMap.texture;

			}

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

W
WestLangley 已提交
2054
				uvScaleMap.updateMatrix();
M
Mr.doob 已提交
2055

W
WestLangley 已提交
2056
			}
2057

2058
			uniforms.uvTransform.value.copy( uvScaleMap.matrix );
M
Mr.doob 已提交
2059 2060 2061

		}

M
Mr.doob 已提交
2062
	}
M
Mr.doob 已提交
2063

M
Mr.doob 已提交
2064
	function refreshUniformsLine( uniforms, material ) {
M
Mr.doob 已提交
2065 2066 2067 2068

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

M
Mr.doob 已提交
2069
	}
M
Mr.doob 已提交
2070

M
Mr.doob 已提交
2071
	function refreshUniformsDash( uniforms, material ) {
M
Mr.doob 已提交
2072 2073 2074 2075 2076

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

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

M
Mr.doob 已提交
2079
	function refreshUniformsPoints( uniforms, material ) {
M
Mr.doob 已提交
2080

2081
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
2082
		uniforms.opacity.value = material.opacity;
2083
		uniforms.size.value = material.size * _pixelRatio;
2084
		uniforms.scale.value = _height * 0.5;
M
Mr.doob 已提交
2085 2086 2087

		uniforms.map.value = material.map;

2088 2089
		if ( material.map !== null ) {

W
WestLangley 已提交
2090
			if ( material.map.matrixAutoUpdate === true ) {
2091

W
WestLangley 已提交
2092
				material.map.updateMatrix();
W
WestLangley 已提交
2093 2094

			}
2095

2096
			uniforms.uvTransform.value.copy( material.map.matrix );
2097 2098 2099

		}

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

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

		uniforms.fogColor.value = fog.color;

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

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

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

			uniforms.fogDensity.value = fog.density;

		}

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

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

		if ( material.emissiveMap ) {

			uniforms.emissiveMap.value = material.emissiveMap;

		}

	}

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

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

2134
		if ( material.emissiveMap ) {
2135

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

2138
		}
M
Mr.doob 已提交
2139

2140 2141 2142 2143
		if ( material.bumpMap ) {

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

2146
		}
M
Mr.doob 已提交
2147

2148 2149 2150 2151
		if ( material.normalMap ) {

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

		}
M
Mr.doob 已提交
2155

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

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

2162
		}
2163

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

	function refreshUniformsToon( uniforms, material ) {

		refreshUniformsPhong( uniforms, material );

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

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

		}

2176 2177
	}

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

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

		}

		if ( material.normalMap ) {

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

		}

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

2236 2237 2238
		uniforms.clearCoat.value = material.clearCoat;
		uniforms.clearCoatRoughness.value = material.clearCoatRoughness;

W
WestLangley 已提交
2239 2240 2241 2242
		refreshUniformsStandard( uniforms, material );

	}

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

	}

2271 2272 2273 2274 2275 2276
	function refreshUniformsNormal( uniforms, material ) {

		if ( material.bumpMap ) {

			uniforms.bumpMap.value = material.bumpMap;
			uniforms.bumpScale.value = material.bumpScale;
2277
			if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1;
2278 2279 2280 2281 2282 2283 2284

		}

		if ( material.normalMap ) {

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

		}

		if ( material.displacementMap ) {

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

		}

	}

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

M
Mr.doob 已提交
2301
	function markUniformsLightsNeedsUpdate( uniforms, value ) {
2302

M
Mr.doob 已提交
2303
		uniforms.ambientLightColor.needsUpdate = value;
2304

B
Ben Houston 已提交
2305 2306 2307
		uniforms.directionalLights.needsUpdate = value;
		uniforms.pointLights.needsUpdate = value;
		uniforms.spotLights.needsUpdate = value;
2308
		uniforms.rectAreaLights.needsUpdate = value;
B
Ben Houston 已提交
2309
		uniforms.hemisphereLights.needsUpdate = value;
2310

M
Mr.doob 已提交
2311
	}
2312

M
Mr.doob 已提交
2313 2314
	// Textures

T
tschw 已提交
2315 2316 2317 2318 2319 2320
	function allocTextureUnit() {

		var textureUnit = _usedTextureUnits;

		if ( textureUnit >= capabilities.maxTextures ) {

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

		}

		_usedTextureUnits += 1;

		return textureUnit;

	}

2331
	this.allocTextureUnit = allocTextureUnit;
T
tschw 已提交
2332

2333
	// this.setTexture2D = setTexture2D;
M
Mr.doob 已提交
2334
	this.setTexture2D = ( function () {
T
tschw 已提交
2335

2336
		var warned = false;
T
tschw 已提交
2337

2338
		// backwards compatibility: peel texture.texture
W
WestLangley 已提交
2339
		return function setTexture2D( texture, slot ) {
T
tschw 已提交
2340

T
Takahiro 已提交
2341
			if ( texture && texture.isWebGLRenderTarget ) {
T
tschw 已提交
2342

2343
				if ( ! warned ) {
T
tschw 已提交
2344

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

2348
				}
T
tschw 已提交
2349

2350
				texture = texture.texture;
T
tschw 已提交
2351

2352
			}
T
tschw 已提交
2353

2354
			textures.setTexture2D( texture, slot );
T
tschw 已提交
2355

2356
		};
T
tschw 已提交
2357

2358
	}() );
T
tschw 已提交
2359

M
Mr.doob 已提交
2360
	this.setTexture = ( function () {
2361 2362 2363

		var warned = false;

W
WestLangley 已提交
2364
		return function setTexture( texture, slot ) {
2365 2366 2367 2368 2369 2370 2371 2372

			if ( ! warned ) {

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

			}

2373
			textures.setTexture2D( texture, slot );
2374 2375 2376 2377 2378

		};

	}() );

M
Mr.doob 已提交
2379
	this.setTextureCube = ( function () {
2380 2381 2382

		var warned = false;

W
WestLangley 已提交
2383
		return function setTextureCube( texture, slot ) {
2384 2385

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

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

				// CompressedTexture can have Array in image :/

				// this function alone should take care of cube textures
2407
				textures.setTextureCube( texture, slot );
2408 2409 2410 2411 2412

			} else {

				// assumed: texture property of THREE.WebGLRenderTargetCube

2413
				textures.setTextureCubeDynamic( texture, slot );
2414 2415 2416 2417 2418 2419

			}

		};

	}() );
T
tschw 已提交
2420

2421
	this.getRenderTarget = function () {
2422 2423 2424

		return _currentRenderTarget;

M
Michael Herzog 已提交
2425
	};
2426

2427
	this.setRenderTarget = function ( renderTarget ) {
M
Mr.doob 已提交
2428

2429 2430
		_currentRenderTarget = renderTarget;

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

2433
			textures.setupRenderTarget( renderTarget );
M
Mr.doob 已提交
2434 2435 2436

		}

M
Mr.doob 已提交
2437
		var framebuffer = null;
M
Mr.doob 已提交
2438
		var isCube = false;
M
Mr.doob 已提交
2439 2440 2441

		if ( renderTarget ) {

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

M
Mr.doob 已提交
2444
			if ( renderTarget.isWebGLRenderTargetCube ) {
M
Mr.doob 已提交
2445

M
Mr.doob 已提交
2446
				framebuffer = __webglFramebuffer[ renderTarget.activeCubeFace ];
M
Mr.doob 已提交
2447
				isCube = true;
M
Mr.doob 已提交
2448 2449 2450

			} else {

M
Mr.doob 已提交
2451
				framebuffer = __webglFramebuffer;
M
Mr.doob 已提交
2452 2453 2454

			}

M
Mr.doob 已提交
2455
			_currentViewport.copy( renderTarget.viewport );
2456 2457
			_currentScissor.copy( renderTarget.scissor );
			_currentScissorTest = renderTarget.scissorTest;
2458

M
Mr.doob 已提交
2459 2460
		} else {

M
Mr.doob 已提交
2461
			_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );
2462
			_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );
2463
			_currentScissorTest = _scissorTest;
2464

M
Mr.doob 已提交
2465 2466
		}

M
Mr.doob 已提交
2467
		if ( _currentFramebuffer !== framebuffer ) {
M
Mr.doob 已提交
2468 2469 2470 2471 2472 2473

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

		}

M
Mr.doob 已提交
2474
		state.viewport( _currentViewport );
2475 2476
		state.scissor( _currentScissor );
		state.setScissorTest( _currentScissorTest );
2477

M
Mr.doob 已提交
2478 2479 2480
		if ( isCube ) {

			var textureProperties = properties.get( renderTarget.texture );
2481
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );
M
Mr.doob 已提交
2482 2483 2484

		}

M
Mr.doob 已提交
2485 2486
	};

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

0
06wj 已提交
2489
		if ( ! ( renderTarget && renderTarget.isWebGLRenderTarget ) ) {
2490

2491
			console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
G
gero3 已提交
2492
			return;
2493

G
gero3 已提交
2494
		}
2495

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

M
Mr.doob 已提交
2498
		if ( framebuffer ) {
2499

G
gero3 已提交
2500
			var restore = false;
2501

M
Mr.doob 已提交
2502
			if ( framebuffer !== _currentFramebuffer ) {
2503

M
Mr.doob 已提交
2504
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
2505

G
gero3 已提交
2506
				restore = true;
2507

G
gero3 已提交
2508
			}
2509

M
Mr.doob 已提交
2510
			try {
2511

M
Mr.doob 已提交
2512
				var texture = renderTarget.texture;
M
Mr.doob 已提交
2513 2514
				var textureFormat = texture.format;
				var textureType = texture.type;
2515

2516
				if ( textureFormat !== RGBAFormat && utils.convert( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {
2517

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

M
Mr.doob 已提交
2521
				}
2522

2523
				if ( textureType !== UnsignedByteType && utils.convert( textureType ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE ) && // IE11, Edge and Chrome Mac < 52 (#9513)
2524 2525
					! ( textureType === FloatType && ( extensions.get( 'OES_texture_float' ) || extensions.get( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox
					! ( textureType === HalfFloatType && extensions.get( 'EXT_color_buffer_half_float' ) ) ) {
2526

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

M
Mr.doob 已提交
2530
				}
2531

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

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

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

2538
						_gl.readPixels( x, y, width, height, utils.convert( textureFormat ), utils.convert( textureType ), buffer );
2539 2540

					}
2541

M
Mr.doob 已提交
2542
				} else {
M
Mr.doob 已提交
2543

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

				}
M
Mr.doob 已提交
2547

M
Mr.doob 已提交
2548
			} finally {
M
Mr.doob 已提交
2549

M
Mr.doob 已提交
2550 2551 2552
				if ( restore ) {

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

M
Mr.doob 已提交
2554 2555 2556
				}

			}
M
Mr.doob 已提交
2557 2558 2559

		}

M
Mr.doob 已提交
2560 2561
	};

2562
	this.copyFramebufferToTexture = function ( position, texture, level ) {
2563 2564 2565

		var width = texture.image.width;
		var height = texture.image.height;
2566
		var glFormat = utils.convert( texture.format );
2567 2568 2569

		this.setTexture2D( texture, 0 );

2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584
		_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 );
		var pixels = srcTexture.isDataTexture ? srcTexture.image.data : srcTexture.image;

		this.setTexture2D( dstTexture, 0 );

		_gl.texSubImage2D( _gl.TEXTURE_2D, level || 0, position.x, position.y, width, height, glFormat, glType, pixels );
2585 2586 2587

	};

M
Mr.doob 已提交
2588
}
R
Rich Harris 已提交
2589

T
Tristan VALCKE 已提交
2590

2591
export { WebGLRenderer };