WebGLRenderer.js 57.0 KB
Newer Older
M
Mugen87 已提交
1
import { REVISION, RGBAFormat, HalfFloatType, FloatType, UnsignedByteType, FrontFaceDirectionCW, TriangleFanDrawMode, TriangleStripDrawMode, TrianglesDrawMode, NoColors, LinearToneMapping } from '../constants.js';
B
bentok 已提交
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
import { _Math } from '../math/Math.js';
import { Matrix4 } from '../math/Matrix4.js';
import { DataTexture } from '../textures/DataTexture.js';
import { WebGLUniforms } from './webgl/WebGLUniforms.js';
import { UniformsLib } from './shaders/UniformsLib.js';
import { UniformsUtils } from './shaders/UniformsUtils.js';
import { ShaderLib } from './shaders/ShaderLib.js';
import { WebGLFlareRenderer } from './webgl/WebGLFlareRenderer.js';
import { WebGLSpriteRenderer } from './webgl/WebGLSpriteRenderer.js';
import { WebGLShadowMap } from './webgl/WebGLShadowMap.js';
import { WebGLAttributes } from './webgl/WebGLAttributes.js';
import { WebGLBackground } from './webgl/WebGLBackground.js';
import { WebGLRenderLists } from './webgl/WebGLRenderLists.js';
import { WebGLMorphtargets } from './webgl/WebGLMorphtargets.js';
import { WebGLIndexedBufferRenderer } from './webgl/WebGLIndexedBufferRenderer.js';
import { WebGLBufferRenderer } from './webgl/WebGLBufferRenderer.js';
import { WebGLGeometries } from './webgl/WebGLGeometries.js';
import { WebGLLights } from './webgl/WebGLLights.js';
import { WebGLObjects } from './webgl/WebGLObjects.js';
import { WebGLPrograms } from './webgl/WebGLPrograms.js';
import { WebGLTextures } from './webgl/WebGLTextures.js';
import { WebGLProperties } from './webgl/WebGLProperties.js';
import { WebGLState } from './webgl/WebGLState.js';
import { WebGLCapabilities } from './webgl/WebGLCapabilities.js';
import { WebVRManager } from './webvr/WebVRManager.js';
import { WebGLExtensions } from './webgl/WebGLExtensions.js';
import { Vector3 } from '../math/Vector3.js';
import { WebGLClipping } from './webgl/WebGLClipping.js';
import { Frustum } from '../math/Frustum.js';
import { Vector4 } from '../math/Vector4.js';
import { WebGLUtils } from './webgl/WebGLUtils.js';
R
Rich Harris 已提交
33

M
Mr.doob 已提交
34 35 36 37 38
/**
 * @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 已提交
39
 * @author tschw
M
Mr.doob 已提交
40 41
 */

M
Mr.doob 已提交
42
function WebGLRenderer( parameters ) {
M
Mr.doob 已提交
43

M
Mr.doob 已提交
44
	console.log( 'THREE.WebGLRenderer', REVISION );
M
Mr.doob 已提交
45 46 47

	parameters = parameters || {};

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

51 52 53 54 55 56
		_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,
		_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false;
M
Mr.doob 已提交
57

58 59
	var lightsArray = [];
	var shadowsArray = [];
M
Mr.doob 已提交
60

61
	var currentRenderList = null;
62

63 64
	var spritesArray = [];
	var flaresArray = [];
M
Mr.doob 已提交
65

M
Mr.doob 已提交
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
	// 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 已提交
82 83 84 85 86
	// user-defined clipping

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

M
Mr.doob 已提交
87 88
	// physically based shading

89
	this.gammaFactor = 2.0;	// for backwards compatibility
M
Mr.doob 已提交
90 91 92
	this.gammaInput = false;
	this.gammaOutput = false;

93 94
	// physical lights

95
	this.physicallyCorrectLights = false;
96

B
Ben Houston 已提交
97 98
	// tone mapping

R
Rich Harris 已提交
99
	this.toneMapping = LinearToneMapping;
B
Ben Houston 已提交
100 101 102
	this.toneMappingExposure = 1.0;
	this.toneMappingWhitePoint = 1.0;

M
Mr.doob 已提交
103 104 105 106 107 108 109 110 111
	// morphs

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

	// internal properties

	var _this = this,

112 113
		_isContextLost = false,

114
		// internal state cache
M
Mr.doob 已提交
115

116 117 118 119
		_currentRenderTarget = null,
		_currentFramebuffer = null,
		_currentMaterialId = - 1,
		_currentGeometryProgram = '',
120

121
		_currentCamera = null,
122
		_currentArrayCamera = null,
M
Mr.doob 已提交
123

M
Mr.doob 已提交
124
		_currentViewport = new Vector4(),
125 126
		_currentScissor = new Vector4(),
		_currentScissorTest = null,
127

128
		//
129

130
		_usedTextureUnits = 0,
M
Mr.doob 已提交
131

132
		//
M
Mr.doob 已提交
133

134 135
		_width = _canvas.width,
		_height = _canvas.height,
M
Mr.doob 已提交
136

137
		_pixelRatio = 1,
M
Mr.doob 已提交
138

M
Mr.doob 已提交
139
		_viewport = new Vector4( 0, 0, _width, _height ),
140 141
		_scissor = new Vector4( 0, 0, _width, _height ),
		_scissorTest = false,
142

143
		// frustum
M
Mr.doob 已提交
144

145
		_frustum = new Frustum(),
M
Mr.doob 已提交
146

147
		// clipping
T
tschw 已提交
148

149 150 151
		_clipping = new WebGLClipping(),
		_clippingEnabled = false,
		_localClippingEnabled = false,
T
tschw 已提交
152

153
		// camera matrices cache
M
Mr.doob 已提交
154

155
		_projScreenMatrix = new Matrix4(),
M
Mr.doob 已提交
156

A
aardgoose 已提交
157
		_vector3 = new Vector3(),
158

159
		// info
M
Mr.doob 已提交
160

M
Mr.doob 已提交
161 162 163 164 165
		_infoMemory = {
			geometries: 0,
			textures: 0
		},

166
		_infoRender = {
167

168
			frame: 0,
169 170 171 172
			calls: 0,
			vertices: 0,
			faces: 0,
			points: 0
173

174
		};
M
Mr.doob 已提交
175

M
Mr.doob 已提交
176
	this.info = {
177

M
Mr.doob 已提交
178
		render: _infoRender,
M
Mr.doob 已提交
179
		memory: _infoMemory,
180
		programs: null
M
Mr.doob 已提交
181 182

	};
183

184 185 186 187 188
	function getTargetPixelRatio() {

		return _currentRenderTarget === null ? _pixelRatio : 1;

	}
189

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

	var _gl;

M
Mr.doob 已提交
194 195
	try {

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

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

		if ( _gl === null ) {

G
gero3 已提交
209
			if ( _canvas.getContext( 'webgl' ) !== null ) {
210 211 212 213 214 215 216 217

				throw 'Error creating WebGL context with your selected attributes.';

			} else {

				throw 'Error creating WebGL context.';

			}
M
Mr.doob 已提交
218 219 220

		}

221 222 223 224 225 226 227 228 229 230 231 232
		// Some experimental-webgl implementations do not have getShaderPrecisionFormat

		if ( _gl.getShaderPrecisionFormat === undefined ) {

			_gl.getShaderPrecisionFormat = function () {

				return { 'rangeMin': 1, 'rangeMax': 1, 'precision': 1 };

			};

		}

D
dubejf 已提交
233
		_canvas.addEventListener( 'webglcontextlost', onContextLost, false );
234
		_canvas.addEventListener( 'webglcontextrestored', onContextRestore, false );
235

M
Mr.doob 已提交
236 237
	} catch ( error ) {

238
		console.error( 'THREE.WebGLRenderer: ' + error );
M
Mr.doob 已提交
239 240 241

	}

242
	var extensions, capabilities, state;
243 244
	var properties, textures, attributes, geometries, objects, lights;
	var programCache, renderLists;
245

246
	var background, morphtargets, bufferRenderer, indexedBufferRenderer;
247
	var flareRenderer, spriteRenderer;
248

249 250
	var utils;

251
	function initGLContext() {
252

253 254 255 256 257 258 259
		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 已提交
260
		extensions.get( 'OES_element_index_uint' );
261
		extensions.get( 'ANGLE_instanced_arrays' );
262

263 264
		utils = new WebGLUtils( _gl, extensions );

265
		capabilities = new WebGLCapabilities( _gl, extensions, parameters );
266

267
		state = new WebGLState( _gl, extensions, utils );
268 269
		state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );
		state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );
270

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

M
Mr.doob 已提交
281
		background = new WebGLBackground( _this, state, geometries, _premultipliedAlpha );
M
Mr.doob 已提交
282

283 284
		bufferRenderer = new WebGLBufferRenderer( _gl, extensions, _infoRender );
		indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );
285

286 287
		flareRenderer = new WebGLFlareRenderer( _this, _gl, state, textures, capabilities );
		spriteRenderer = new WebGLSpriteRenderer( _this, _gl, state, textures, capabilities );
288

289
		_this.info.programs = programCache.programs;
290

291 292 293 294 295 296 297
		_this.context = _gl;
		_this.capabilities = capabilities;
		_this.extensions = extensions;
		_this.properties = properties;
		_this.renderLists = renderLists;
		_this.state = state;

298 299
	}

300
	initGLContext();
301

302
	// vr
303

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

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

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

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

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

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

	this.getContext = function () {

		return _gl;

	};

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

		return _gl.getContextAttributes();

	};

328 329
	this.forceContextLoss = function () {

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

	};

335 336 337 338 339 340 341
	this.forceContextRestore = function () {

		var extension = extensions.get( 'WEBGL_lose_context' );
		if ( extension ) extension.restoreContext();

	};

342 343
	this.getPixelRatio = function () {

344
		return _pixelRatio;
345 346 347 348 349

	};

	this.setPixelRatio = function ( value ) {

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

		_pixelRatio = value;

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

	};

358 359 360
	this.getSize = function () {

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

	};

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

369 370 371 372 373 374 375 376 377
		var device = vr.getDevice();

		if ( device && device.isPresenting ) {

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

		}

378 379 380
		_width = width;
		_height = height;

381 382
		_canvas.width = width * _pixelRatio;
		_canvas.height = height * _pixelRatio;
383

384
		if ( updateStyle !== false ) {
385

G
gero3 已提交
386 387
			_canvas.style.width = width + 'px';
			_canvas.style.height = height + 'px';
388

G
gero3 已提交
389
		}
M
Mr.doob 已提交
390

391
		this.setViewport( 0, 0, width, height );
M
Mr.doob 已提交
392 393 394

	};

M
Mr.doob 已提交
395 396 397 398 399 400 401 402 403
	this.getDrawingBufferSize = function () {

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

	};

404 405 406 407 408 409 410 411 412 413 414 415 416 417
	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 );

	};

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

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

M
Mr.doob 已提交
423 424
	};

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

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

M
Mr.doob 已提交
430 431
	};

432 433
	this.setScissorTest = function ( boolean ) {

434
		state.setScissorTest( _scissorTest = boolean );
M
Mr.doob 已提交
435 436 437 438 439

	};

	// Clearing

M
Mugen87 已提交
440
	this.getClearColor = function () {
441 442 443 444 445 446 447 448 449 450 451

		return background.getClearColor();

	};

	this.setClearColor = function () {

		background.setClearColor.apply( background, arguments );

	};

M
Mugen87 已提交
452
	this.getClearAlpha = function () {
453 454 455 456 457

		return background.getClearAlpha();

	};

M
Mugen87 已提交
458
	this.setClearAlpha = function () {
459 460 461 462

		background.setClearAlpha.apply( background, arguments );

	};
M
Mr.doob 已提交
463 464 465 466 467 468 469 470 471 472

	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 );
473 474 475 476 477

	};

	this.clearColor = function () {

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

	};

	this.clearDepth = function () {

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

	};

	this.clearStencil = function () {

M
Mr.doob 已提交
490
		this.clear( false, false, true );
M
Mr.doob 已提交
491 492 493 494 495 496 497 498 499 500

	};

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

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

	};

M
Mr.doob 已提交
501
	//
M
Mr.doob 已提交
502

M
Mr.doob 已提交
503
	this.dispose = function () {
D
dubejf 已提交
504 505

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

508 509
		renderLists.dispose();

510
		vr.dispose();
511

D
dubejf 已提交
512 513
	};

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

D
dubejf 已提交
516 517 518 519
	function onContextLost( event ) {

		event.preventDefault();

520 521
		console.log( 'THREE.WebGLRenderer: Context Lost.' );

522 523 524 525
		_isContextLost = true;

	}

M
Mugen87 已提交
526
	function onContextRestore( /* event */ ) {
D
dubejf 已提交
527

528
		console.log( 'THREE.WebGLRenderer: Context Restored.' );
529 530

		_isContextLost = false;
D
dubejf 已提交
531

532 533
		initGLContext();

M
Mr.doob 已提交
534
	}
D
dubejf 已提交
535

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

		var material = event.target;

		material.removeEventListener( 'dispose', onMaterialDispose );

		deallocateMaterial( material );

544
	}
M
Mr.doob 已提交
545 546 547

	// Buffer deallocation

548
	function deallocateMaterial( material ) {
M
Mr.doob 已提交
549

550 551
		releaseMaterialProgramReference( material );

552
		properties.remove( material );
553

554
	}
555 556


557
	function releaseMaterialProgramReference( material ) {
558

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

		material.program = undefined;

563
		if ( programInfo !== undefined ) {
M
Mr.doob 已提交
564

565
			programCache.releaseProgram( programInfo );
M
Mr.doob 已提交
566

M
Mr.doob 已提交
567 568
		}

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

	// Buffer rendering

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

		object.render( function ( object ) {

			_this.renderBufferImmediate( object, program, material );

		} );

	}

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

585
		state.initAttributes();
586

587
		var buffers = properties.get( object );
588

589 590 591 592
		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 已提交
593

594
		var programAttributes = program.getAttributes();
595

M
Mr.doob 已提交
596 597
		if ( object.hasPositions ) {

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

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

		}

		if ( object.hasNormals ) {

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

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

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

617
					var array = object.normalArray;
M
Mr.doob 已提交
618

619 620 621
					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 已提交
622

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

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

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

				}

			}

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

641
			state.enableAttribute( programAttributes.normal );
642

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

		}

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

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

652
			state.enableAttribute( programAttributes.uv );
653

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

		}

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

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

663
			state.enableAttribute( programAttributes.color );
664

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

		}

669
		state.disableUnusedAttributes();
670

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

		object.count = 0;

	};

677
	this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {
678

679
		state.setMaterial( material );
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 = 0;
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 759
		var drawStart = Math.max( rangeStart, groupStart );
		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, startIndex ) {
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
		if ( startIndex === undefined ) startIndex = 0;

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, ( startIndex * stride + 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, startIndex * size * bytesPerElement );
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

974 975
		lightsArray.length = 0;
		shadowsArray.length = 0;
976

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

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

981 982 983 984 985 986 987
				lightsArray.push( object );

				if ( object.castShadow ) {

					shadowsArray.push( object );

				}
M
Mr.doob 已提交
988

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

		} );

993
		lights.setup( lightsArray, shadowsArray, 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

1021 1022
	var isAnimating = false;
	var onAnimationFrame = null;
1023

1024
	function start() {
1025

1026
		if ( isAnimating ) return;
1027 1028

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

1030
		if ( device && device.isPresenting ) {
1031 1032 1033 1034 1035 1036 1037 1038

			device.requestAnimationFrame( loop );

		} else {

			window.requestAnimationFrame( loop );

		}
1039

1040
		isAnimating = true;
1041

1042
	}
1043

1044
	function loop( time ) {
1045

1046
		if ( onAnimationFrame !== null ) onAnimationFrame( time );
1047 1048

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

1050
		if ( device && device.isPresenting ) {
1051 1052 1053 1054 1055 1056 1057 1058

			device.requestAnimationFrame( loop );

		} else {

			window.requestAnimationFrame( loop );

		}
1059

1060 1061 1062
	}

	this.animate = function ( callback ) {
1063

1064 1065
		onAnimationFrame = callback;
		start();
1066 1067 1068

	};

1069 1070
	// Rendering

M
Mr.doob 已提交
1071
	this.render = function ( scene, camera, renderTarget, forceClear ) {
1072

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

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

		}

1080 1081
		if ( _isContextLost ) return;

M
Mr.doob 已提交
1082 1083
		// reset caching for this frame

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

		// update scene graph

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

		// update camera matrices and frustum

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

1096 1097 1098 1099 1100 1101
		if ( vr.enabled ) {

			camera = vr.getCamera( camera );

		}

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

1105 1106 1107
		lightsArray.length = 0;
		shadowsArray.length = 0;

1108 1109
		spritesArray.length = 0;
		flaresArray.length = 0;
M
Mr.doob 已提交
1110

T
tschw 已提交
1111
		_localClippingEnabled = this.localClippingEnabled;
M
Mr.doob 已提交
1112
		_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );
T
tschw 已提交
1113

1114 1115 1116
		currentRenderList = renderLists.get( scene, camera );
		currentRenderList.init();

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

M
Mr.doob 已提交
1119
		if ( _this.sortObjects === true ) {
1120

1121
			currentRenderList.sort();
M
Mr.doob 已提交
1122

1123 1124
		}

M
Mr.doob 已提交
1125
		//
M
Mr.doob 已提交
1126

T
tschw 已提交
1127
		if ( _clippingEnabled ) _clipping.beginShadows();
T
tschw 已提交
1128

1129
		shadowMap.render( shadowsArray, scene, camera );
M
Mr.doob 已提交
1130

1131
		lights.setup( lightsArray, shadowsArray, camera );
1132

T
tschw 已提交
1133
		if ( _clippingEnabled ) _clipping.endShadows();
T
tschw 已提交
1134

M
Mr.doob 已提交
1135 1136
		//

M
Mr.doob 已提交
1137
		_infoRender.frame ++;
1138 1139 1140 1141
		_infoRender.calls = 0;
		_infoRender.vertices = 0;
		_infoRender.faces = 0;
		_infoRender.points = 0;
M
Mr.doob 已提交
1142

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

			renderTarget = null;

		}

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

M
Mr.doob 已提交
1151 1152
		//

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

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

1157 1158
		var opaqueObjects = currentRenderList.opaque;
		var transparentObjects = currentRenderList.transparent;
M
Mr.doob 已提交
1159

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

1162
			var overrideMaterial = scene.overrideMaterial;
1163

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

1167
		} else {
M
Mr.doob 已提交
1168

1169
			// opaque pass (front-to-back order)
M
Mr.doob 已提交
1170

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

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

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

		}

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

1181 1182
		spriteRenderer.render( spritesArray, scene, camera );
		flareRenderer.render( flaresArray, scene, camera, _currentViewport );
M
Mr.doob 已提交
1183 1184 1185

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

M
Mr.doob 已提交
1186 1187
		if ( renderTarget ) {

1188
			textures.updateRenderTargetMipmap( renderTarget );
M
Mr.doob 已提交
1189 1190 1191

		}

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

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

1198 1199
		state.setPolygonOffset( false );

M
Mr.doob 已提交
1200 1201 1202 1203 1204
		if ( vr.enabled ) {

			vr.submitFrame();

		}
M
Mr.doob 已提交
1205

M
Mr.doob 已提交
1206 1207 1208
		// _gl.finish();

	};
M
Mr.doob 已提交
1209

1210
	/*
M
Mr.doob 已提交
1211 1212
	// TODO Duplicated code (Frustum)

1213 1214
	var _sphere = new Sphere();

T
tschw 已提交
1215 1216 1217 1218 1219 1220 1221
	function isObjectViewable( object ) {

		var geometry = object.geometry;

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

M
Mr.doob 已提交
1222
		_sphere.copy( geometry.boundingSphere ).
1223
		applyMatrix4( object.matrixWorld );
M
Mr.doob 已提交
1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239

		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 已提交
1240 1241

		if ( ! _frustum.intersectsSphere( sphere ) ) return false;
T
tschw 已提交
1242 1243 1244 1245

		var numPlanes = _clipping.numPlanes;

		if ( numPlanes === 0 ) return true;
T
tschw 已提交
1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257

		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 已提交
1258
		} while ( ++ i !== numPlanes );
T
tschw 已提交
1259 1260 1261 1262

		return true;

	}
1263
	*/
T
tschw 已提交
1264

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

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

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

1271
		if ( visible ) {
1272

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

1275 1276 1277 1278 1279 1280 1281
				lightsArray.push( object );

				if ( object.castShadow ) {

					shadowsArray.push( object );

				}
M
Mr.doob 已提交
1282

1283
			} else if ( object.isSprite ) {
M
Mr.doob 已提交
1284

1285
				if ( ! object.frustumCulled || _frustum.intersectsSprite( object ) ) {
1286

1287
					spritesArray.push( object );
M
Mr.doob 已提交
1288

1289
				}
M
Mr.doob 已提交
1290

1291
			} else if ( object.isLensFlare ) {
M
Mr.doob 已提交
1292

1293
				flaresArray.push( object );
M
Mr.doob 已提交
1294

1295
			} else if ( object.isImmediateRenderObject ) {
M
Mr.doob 已提交
1296

1297
				if ( sortObjects ) {
M
Mr.doob 已提交
1298

1299 1300
					_vector3.setFromMatrixPosition( object.matrixWorld )
						.applyMatrix4( _projScreenMatrix );
M
Mr.doob 已提交
1301

1302
				}
M
Mr.doob 已提交
1303

1304
				currentRenderList.push( object, null, object.material, _vector3.z, null );
1305

1306
			} else if ( object.isMesh || object.isLine || object.isPoints ) {
1307

1308
				if ( object.isSkinnedMesh ) {
1309

1310
					object.skeleton.update();
1311

1312
				}
1313

1314
				if ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) {
1315

1316 1317 1318 1319 1320 1321
					if ( sortObjects ) {

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

					}
1322

1323 1324
					var geometry = objects.update( object );
					var material = object.material;
1325

1326
					if ( Array.isArray( material ) ) {
1327

1328
						var groups = geometry.groups;
1329

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

1332 1333
							var group = groups[ i ];
							var groupMaterial = material[ group.materialIndex ];
1334

1335
							if ( groupMaterial && groupMaterial.visible ) {
1336

1337 1338 1339
								currentRenderList.push( object, geometry, groupMaterial, _vector3.z, group );

							}
M
Mr.doob 已提交
1340

M
Mr.doob 已提交
1341
						}
M
Mr.doob 已提交
1342

1343
					} else if ( material.visible ) {
1344

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

1347
					}
M
Mr.doob 已提交
1348

1349
				}
M
Mr.doob 已提交
1350

1351
			}
M
Mr.doob 已提交
1352

M
Mr.doob 已提交
1353
		}
M
Mr.doob 已提交
1354

M
Mr.doob 已提交
1355
		var children = object.children;
M
Mr.doob 已提交
1356

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

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

1361
		}
1362

1363
	}
M
Mr.doob 已提交
1364

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

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

1369
			var renderItem = renderList[ i ];
1370

1371 1372 1373 1374
			var object = renderItem.object;
			var geometry = renderItem.geometry;
			var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;
			var group = renderItem.group;
1375

1376
			if ( camera.isArrayCamera ) {
M
Mr.doob 已提交
1377

1378 1379
				_currentArrayCamera = camera;

1380
				var cameras = camera.cameras;
1381

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

1384
					var camera2 = cameras[ j ];
M
Mr.doob 已提交
1385

1386
					if ( object.layers.test( camera2.layers ) ) {
1387

1388
						var bounds = camera2.bounds;
M
Mr.doob 已提交
1389

1390 1391 1392 1393 1394
						var x = bounds.x * _width;
						var y = bounds.y * _height;
						var width = bounds.z * _width;
						var height = bounds.w * _height;

1395
						state.viewport( _currentViewport.set( x, y, width, height ).multiplyScalar( _pixelRatio ) );
1396 1397 1398 1399

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

					}
M
Mr.doob 已提交
1400

1401
				}
1402

1403
			} else {
M
Mr.doob 已提交
1404

1405 1406
				_currentArrayCamera = null;

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

1409
			}
M
Mr.doob 已提交
1410

1411
		}
M
Mr.doob 已提交
1412

1413
	}
G
gero3 已提交
1414

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

1417 1418
		object.onBeforeRender( _this, scene, camera, geometry, material, group );

M
Mr.doob 已提交
1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437
		object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
		object.normalMatrix.getNormalMatrix( object.modelViewMatrix );

		if ( object.isImmediateRenderObject ) {

			state.setMaterial( material );

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

			_currentGeometryProgram = '';

			renderObjectImmediate( object, program, material );

		} else {

			_this.renderBufferDirect( camera, scene.fog, geometry, material, object, group );

		}

M
Mr.doob 已提交
1438 1439
		object.onAfterRender( _this, scene, camera, geometry, material, group );

M
Mr.doob 已提交
1440 1441
	}

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

1444
		var materialProperties = properties.get( material );
G
gero3 已提交
1445

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

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

1451
		var program = materialProperties.program;
T
tschw 已提交
1452
		var programChange = true;
1453

1454
		if ( program === undefined ) {
B
Ben Adams 已提交
1455

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

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

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

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

T
tschw 已提交
1466
			// same glsl and uniform list
T
tschw 已提交
1467 1468
			return;

T
tschw 已提交
1469
		} else {
B
Ben Adams 已提交
1470

T
tschw 已提交
1471 1472
			// only rebuild uniform list
			programChange = false;
B
Ben Adams 已提交
1473 1474 1475

		}

1476
		if ( programChange ) {
B
Ben Adams 已提交
1477

1478
			if ( parameters.shaderID ) {
B
Ben Adams 已提交
1479

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

1482
				materialProperties.shader = {
1483
					name: material.type,
1484
					uniforms: UniformsUtils.clone( shader.uniforms ),
1485 1486 1487
					vertexShader: shader.vertexShader,
					fragmentShader: shader.fragmentShader
				};
B
Ben Adams 已提交
1488

1489
			} else {
B
Ben Adams 已提交
1490

1491
				materialProperties.shader = {
1492 1493 1494 1495 1496
					name: material.type,
					uniforms: material.uniforms,
					vertexShader: material.vertexShader,
					fragmentShader: material.fragmentShader
				};
G
gero3 已提交
1497

1498
			}
G
gero3 已提交
1499

1500
			material.onBeforeCompile( materialProperties.shader );
G
gero3 已提交
1501

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

1504 1505
			materialProperties.program = program;
			material.program = program;
1506 1507 1508

		}

1509
		var programAttributes = program.getAttributes();
M
Mr.doob 已提交
1510 1511 1512 1513 1514

		if ( material.morphTargets ) {

			material.numSupportedMorphTargets = 0;

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

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

					material.numSupportedMorphTargets ++;

				}

			}

		}

		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

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

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

					material.numSupportedMorphNormals ++;

				}

			}

		}

1543
		var uniforms = materialProperties.shader.uniforms;
T
tschw 已提交
1544

1545
		if ( ! material.isShaderMaterial &&
1546 1547
			! material.isRawShaderMaterial ||
			material.clipping === true ) {
T
tschw 已提交
1548

T
tschw 已提交
1549
			materialProperties.numClippingPlanes = _clipping.numPlanes;
1550
			materialProperties.numIntersection = _clipping.numIntersection;
T
tschw 已提交
1551
			uniforms.clippingPlanes = _clipping.uniform;
T
tschw 已提交
1552 1553 1554

		}

1555
		materialProperties.fog = fog;
1556

1557
		// store the light setup it was created for
1558

1559
		materialProperties.lightsHash = lights.state.hash;
1560

M
Mr.doob 已提交
1561
		if ( material.lights ) {
1562 1563 1564

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

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

1580 1581
		}

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

T
tschw 已提交
1586
		materialProperties.uniformsList = uniformsList;
A
arose 已提交
1587

M
Mr.doob 已提交
1588
	}
M
Mr.doob 已提交
1589

1590
	function setProgram( camera, fog, material, object ) {
M
Mr.doob 已提交
1591 1592 1593

		_usedTextureUnits = 0;

1594
		var materialProperties = properties.get( material );
1595

T
tschw 已提交
1596 1597 1598 1599 1600
		if ( _clippingEnabled ) {

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

				var useCache =
1601 1602
					camera === _currentCamera &&
					material.id === _currentMaterialId;
T
tschw 已提交
1603 1604 1605 1606

				// we might want to call this function with some ClippingGroup
				// object instead of the material, once it becomes feasible
				// (#8465, #8379)
T
tschw 已提交
1607
				_clipping.setState(
1608 1609
					material.clippingPlanes, material.clipIntersection, material.clipShadows,
					camera, materialProperties, useCache );
T
tschw 已提交
1610 1611 1612 1613 1614

			}

		}

1615
		if ( material.needsUpdate === false ) {
1616

1617
			if ( materialProperties.program === undefined ) {
1618

1619
				material.needsUpdate = true;
1620

1621
			} else if ( material.fog && materialProperties.fog !== fog ) {
1622

M
Mr.doob 已提交
1623
				material.needsUpdate = true;
1624

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

1627
				material.needsUpdate = true;
1628

1629
			} else if ( materialProperties.numClippingPlanes !== undefined &&
1630
				( materialProperties.numClippingPlanes !== _clipping.numPlanes ||
M
Mr.doob 已提交
1631
				materialProperties.numIntersection !== _clipping.numIntersection ) ) {
1632 1633 1634

				material.needsUpdate = true;

1635
			}
1636 1637 1638 1639

		}

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

1641
			initMaterial( material, fog, object );
M
Mr.doob 已提交
1642 1643 1644 1645
			material.needsUpdate = false;

		}

1646
		var refreshProgram = false;
M
Mr.doob 已提交
1647
		var refreshMaterial = false;
1648
		var refreshLights = false;
M
Mr.doob 已提交
1649

1650
		var program = materialProperties.program,
1651
			p_uniforms = program.getUniforms(),
1652
			m_uniforms = materialProperties.shader.uniforms;
M
Mr.doob 已提交
1653

1654
		if ( state.useProgram( program.program ) ) {
M
Mr.doob 已提交
1655

1656
			refreshProgram = true;
M
Mr.doob 已提交
1657
			refreshMaterial = true;
1658
			refreshLights = true;
M
Mr.doob 已提交
1659 1660 1661 1662 1663 1664

		}

		if ( material.id !== _currentMaterialId ) {

			_currentMaterialId = material.id;
1665

M
Mr.doob 已提交
1666 1667 1668 1669
			refreshMaterial = true;

		}

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

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

G
gero3 已提交
1674
			if ( capabilities.logarithmicDepthBuffer ) {
1675

T
tschw 已提交
1676
				p_uniforms.setValue( _gl, 'logDepthBufFC',
1677
					2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
1678 1679 1680

			}

1681
			// Avoid unneeded uniform updates per ArrayCamera's sub-camera
1682

1683
			if ( _currentCamera !== ( _currentArrayCamera || camera ) ) {
1684

1685
				_currentCamera = ( _currentArrayCamera || camera );
1686 1687 1688 1689 1690 1691

				// 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 已提交
1692
				refreshLights = true;		// remains set until update done
1693 1694

			}
M
Mr.doob 已提交
1695

1696 1697 1698
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)

1699
			if ( material.isShaderMaterial ||
1700 1701 1702
				material.isMeshPhongMaterial ||
				material.isMeshStandardMaterial ||
				material.envMap ) {
1703

T
tschw 已提交
1704 1705 1706
				var uCamPos = p_uniforms.map.cameraPosition;

				if ( uCamPos !== undefined ) {
1707

T
tschw 已提交
1708
					uCamPos.setValue( _gl,
1709
						_vector3.setFromMatrixPosition( camera.matrixWorld ) );
1710 1711 1712 1713 1714

				}

			}

1715
			if ( material.isMeshPhongMaterial ||
1716 1717 1718 1719
				material.isMeshLambertMaterial ||
				material.isMeshBasicMaterial ||
				material.isMeshStandardMaterial ||
				material.isShaderMaterial ||
1720
				material.skinning ) {
1721

T
tschw 已提交
1722
				p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );
1723 1724 1725

			}

M
Mr.doob 已提交
1726 1727 1728 1729 1730 1731
		}

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

1732
		if ( material.skinning ) {
M
Mr.doob 已提交
1733

T
tschw 已提交
1734 1735
			p_uniforms.setOptional( _gl, object, 'bindMatrix' );
			p_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );
1736

T
tschw 已提交
1737
			var skeleton = object.skeleton;
1738

T
tschw 已提交
1739
			if ( skeleton ) {
1740

1741 1742
				var bones = skeleton.bones;

1743
				if ( capabilities.floatVertexTextures ) {
M
Mr.doob 已提交
1744

1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755
					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
1756
						size = _Math.ceilPowerOfTwo( size );
1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769
						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 );

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

					}

M
Mr.doob 已提交
1770 1771
					p_uniforms.setValue( _gl, 'boneTexture', skeleton.boneTexture );
					p_uniforms.setValue( _gl, 'boneTextureSize', skeleton.boneTextureSize );
M
Mr.doob 已提交
1772

T
tschw 已提交
1773
				} else {
M
Mr.doob 已提交
1774

T
tschw 已提交
1775
					p_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );
M
Mr.doob 已提交
1776 1777 1778 1779 1780 1781 1782 1783 1784

				}

			}

		}

		if ( refreshMaterial ) {

1785 1786 1787
			p_uniforms.setValue( _gl, 'toneMappingExposure', _this.toneMappingExposure );
			p_uniforms.setValue( _gl, 'toneMappingWhitePoint', _this.toneMappingWhitePoint );

M
Mr.doob 已提交
1788
			if ( material.lights ) {
M
Mr.doob 已提交
1789

1790
				// the current material requires lighting info
M
Mr.doob 已提交
1791

T
tschw 已提交
1792 1793 1794 1795 1796 1797
				// 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 已提交
1798

T
tschw 已提交
1799
				markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
G
gero3 已提交
1800

T
tschw 已提交
1801
			}
G
gero3 已提交
1802

T
tschw 已提交
1803
			// refresh uniforms common to several materials
G
gero3 已提交
1804

T
tschw 已提交
1805
			if ( fog && material.fog ) {
G
gero3 已提交
1806

T
tschw 已提交
1807
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
1808 1809 1810

			}

1811
			if ( material.isMeshBasicMaterial ) {
M
Mr.doob 已提交
1812 1813 1814

				refreshUniformsCommon( m_uniforms, material );

1815
			} else if ( material.isMeshLambertMaterial ) {
M
Mr.doob 已提交
1816

1817 1818
				refreshUniformsCommon( m_uniforms, material );
				refreshUniformsLambert( m_uniforms, material );
M
Mr.doob 已提交
1819

1820
			} else if ( material.isMeshPhongMaterial ) {
M
Mr.doob 已提交
1821

1822
				refreshUniformsCommon( m_uniforms, material );
M
Mr.doob 已提交
1823

1824
				if ( material.isMeshToonMaterial ) {
M
Mr.doob 已提交
1825

1826
					refreshUniformsToon( m_uniforms, material );
M
Mr.doob 已提交
1827

1828
				} else {
M
Mr.doob 已提交
1829

1830
					refreshUniformsPhong( m_uniforms, material );
M
Mr.doob 已提交
1831

1832
				}
1833

1834
			} else if ( material.isMeshStandardMaterial ) {
1835

1836
				refreshUniformsCommon( m_uniforms, material );
T
Takahiro 已提交
1837

1838
				if ( material.isMeshPhysicalMaterial ) {
T
Takahiro 已提交
1839

1840
					refreshUniformsPhysical( m_uniforms, material );
1841

1842
				} else {
1843

1844
					refreshUniformsStandard( m_uniforms, material );
W
WestLangley 已提交
1845

1846
				}
W
WestLangley 已提交
1847

1848
			} else if ( material.isMeshDepthMaterial ) {
M
Mr.doob 已提交
1849

1850
				refreshUniformsCommon( m_uniforms, material );
W
WestLangley 已提交
1851
				refreshUniformsDepth( m_uniforms, material );
1852

W
WestLangley 已提交
1853
			} else if ( material.isMeshDistanceMaterial ) {
1854

1855
				refreshUniformsCommon( m_uniforms, material );
W
WestLangley 已提交
1856
				refreshUniformsDistance( m_uniforms, material );
1857

1858
			} else if ( material.isMeshNormalMaterial ) {
M
Mr.doob 已提交
1859

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

1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876
			} else if ( material.isLineBasicMaterial ) {

				refreshUniformsLine( m_uniforms, material );

				if ( material.isLineDashedMaterial ) {

					refreshUniformsDash( m_uniforms, material );

				}

			} else if ( material.isPointsMaterial ) {

				refreshUniformsPoints( m_uniforms, material );

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

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

M
Mr.doob 已提交
1882 1883
			}

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

			if ( m_uniforms.ltcMat !== undefined ) m_uniforms.ltcMat.value = UniformsLib.LTC_MAT_TEXTURE;
			if ( m_uniforms.ltcMag !== undefined ) m_uniforms.ltcMag.value = UniformsLib.LTC_MAG_TEXTURE;

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

		}

M
Mr.doob 已提交
1895

T
tschw 已提交
1896
		// common matrices
M
Mr.doob 已提交
1897

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

T
tschw 已提交
1902
		return program;
A
arose 已提交
1903 1904 1905

	}

M
Mr.doob 已提交
1906 1907
	// Uniforms (refresh uniforms objects)

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

		uniforms.opacity.value = material.opacity;

1912 1913 1914 1915 1916
		if ( material.color ) {

			uniforms.diffuse.value = material.color;

		}
M
Mr.doob 已提交
1917

1918
		if ( material.emissive ) {
M
Mr.doob 已提交
1919

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

		}

1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955
		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;

		}
M
Mr.doob 已提交
1956

1957 1958 1959 1960 1961 1962 1963
		if ( material.lightMap ) {

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

		}

1964
		if ( material.aoMap ) {
1965

1966 1967
			uniforms.aoMap.value = material.aoMap;
			uniforms.aoMapIntensity.value = material.aoMapIntensity;
1968 1969 1970

		}

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

		var uvScaleMap;

		if ( material.map ) {

			uvScaleMap = material.map;

		} else if ( material.specularMap ) {

			uvScaleMap = material.specularMap;

1989 1990 1991 1992
		} else if ( material.displacementMap ) {

			uvScaleMap = material.displacementMap;

M
Mr.doob 已提交
1993 1994 1995 1996 1997 1998 1999 2000
		} else if ( material.normalMap ) {

			uvScaleMap = material.normalMap;

		} else if ( material.bumpMap ) {

			uvScaleMap = material.bumpMap;

2001 2002 2003 2004 2005 2006 2007 2008
		} else if ( material.roughnessMap ) {

			uvScaleMap = material.roughnessMap;

		} else if ( material.metalnessMap ) {

			uvScaleMap = material.metalnessMap;

2009 2010 2011 2012
		} else if ( material.alphaMap ) {

			uvScaleMap = material.alphaMap;

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

			uvScaleMap = material.emissiveMap;

M
Mr.doob 已提交
2017 2018 2019 2020
		}

		if ( uvScaleMap !== undefined ) {

2021
			// backwards compatibility
2022
			if ( uvScaleMap.isWebGLRenderTarget ) {
M
Mr.doob 已提交
2023 2024 2025 2026 2027

				uvScaleMap = uvScaleMap.texture;

			}

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

T
Tentone 已提交
2030 2031 2032 2033
				var offset = uvScaleMap.offset;
				var repeat = uvScaleMap.repeat;
				var rotation = uvScaleMap.rotation;
				var center = uvScaleMap.center;
M
Mr.doob 已提交
2034

T
Tentone 已提交
2035
				uvScaleMap.matrix.setUvTransform( offset.x, offset.y, repeat.x, repeat.y, rotation, center.x, center.y );
W
WestLangley 已提交
2036 2037

			}
M
Mr.doob 已提交
2038

2039 2040
			uniforms.uvTransform.value.copy( uvScaleMap.matrix );

M
Mr.doob 已提交
2041 2042
		}

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

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

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

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

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

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

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

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

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

		uniforms.map.value = material.map;

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

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

T
Tentone 已提交
2073 2074 2075 2076 2077 2078
				var offset = material.map.offset;
				var repeat = material.map.repeat;
				var rotation = material.map.rotation;
				var center = material.map.center;

				material.map.matrix.setUvTransform( offset.x, offset.y, repeat.x, repeat.y, rotation, center.x, center.y );
W
WestLangley 已提交
2079 2080

			}
2081

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

2084 2085
		}

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

M
Mr.doob 已提交
2088
	function refreshUniformsFog( uniforms, fog ) {
M
Mr.doob 已提交
2089 2090 2091

		uniforms.fogColor.value = fog.color;

2092
		if ( fog.isFog ) {
M
Mr.doob 已提交
2093 2094 2095 2096

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

2097
		} else if ( fog.isFogExp2 ) {
M
Mr.doob 已提交
2098 2099 2100 2101 2102

			uniforms.fogDensity.value = fog.density;

		}

M
Mr.doob 已提交
2103
	}
M
Mr.doob 已提交
2104

M
Mr.doob 已提交
2105
	function refreshUniformsLambert( uniforms, material ) {
2106 2107 2108 2109 2110 2111 2112 2113 2114

		if ( material.emissiveMap ) {

			uniforms.emissiveMap.value = material.emissiveMap;

		}

	}

M
Mr.doob 已提交
2115
	function refreshUniformsPhong( uniforms, material ) {
M
Mr.doob 已提交
2116

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

2120
		if ( material.emissiveMap ) {
2121

2122
			uniforms.emissiveMap.value = material.emissiveMap;
2123

2124
		}
M
Mr.doob 已提交
2125

2126 2127 2128 2129
		if ( material.bumpMap ) {

			uniforms.bumpMap.value = material.bumpMap;
			uniforms.bumpScale.value = material.bumpScale;
M
Mr.doob 已提交
2130

2131
		}
M
Mr.doob 已提交
2132

2133 2134 2135 2136 2137 2138
		if ( material.normalMap ) {

			uniforms.normalMap.value = material.normalMap;
			uniforms.normalScale.value.copy( material.normalScale );

		}
M
Mr.doob 已提交
2139

2140 2141 2142 2143 2144
		if ( material.displacementMap ) {

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

2146
		}
2147

T
Takahiro 已提交
2148 2149 2150 2151 2152 2153
	}

	function refreshUniformsToon( uniforms, material ) {

		refreshUniformsPhong( uniforms, material );

T
Takahiro 已提交
2154
		if ( material.gradientMap ) {
T
Takahiro 已提交
2155

T
Takahiro 已提交
2156
			uniforms.gradientMap.value = material.gradientMap;
T
Takahiro 已提交
2157 2158 2159

		}

2160 2161
	}

M
Mr.doob 已提交
2162
	function refreshUniformsStandard( uniforms, material ) {
W
WestLangley 已提交
2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 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 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215

		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;

		}

		if ( material.normalMap ) {

			uniforms.normalMap.value = material.normalMap;
			uniforms.normalScale.value.copy( material.normalScale );

		}

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

2218 2219 2220
		uniforms.clearCoat.value = material.clearCoat;
		uniforms.clearCoatRoughness.value = material.clearCoatRoughness;

W
WestLangley 已提交
2221 2222 2223 2224
		refreshUniformsStandard( uniforms, material );

	}

W
WestLangley 已提交
2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252
	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;

	}

2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278
	function refreshUniformsNormal( uniforms, material ) {

		if ( material.bumpMap ) {

			uniforms.bumpMap.value = material.bumpMap;
			uniforms.bumpScale.value = material.bumpScale;

		}

		if ( material.normalMap ) {

			uniforms.normalMap.value = material.normalMap;
			uniforms.normalScale.value.copy( material.normalScale );

		}

		if ( material.displacementMap ) {

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

		}

	}

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

M
Mr.doob 已提交
2281
	function markUniformsLightsNeedsUpdate( uniforms, value ) {
2282

M
Mr.doob 已提交
2283
		uniforms.ambientLightColor.needsUpdate = value;
2284

B
Ben Houston 已提交
2285 2286 2287
		uniforms.directionalLights.needsUpdate = value;
		uniforms.pointLights.needsUpdate = value;
		uniforms.spotLights.needsUpdate = value;
2288
		uniforms.rectAreaLights.needsUpdate = value;
B
Ben Houston 已提交
2289
		uniforms.hemisphereLights.needsUpdate = value;
2290

M
Mr.doob 已提交
2291
	}
2292

M
Mr.doob 已提交
2293 2294 2295 2296
	// GL state setting

	this.setFaceCulling = function ( cullFace, frontFaceDirection ) {

T
tschw 已提交
2297
		state.setCullFace( cullFace );
R
Rich Harris 已提交
2298
		state.setFlipSided( frontFaceDirection === FrontFaceDirectionCW );
M
Mr.doob 已提交
2299 2300 2301 2302 2303

	};

	// Textures

T
tschw 已提交
2304 2305 2306 2307 2308 2309
	function allocTextureUnit() {

		var textureUnit = _usedTextureUnits;

		if ( textureUnit >= capabilities.maxTextures ) {

M
Mugen87 已提交
2310
			console.warn( 'THREE.WebGLRenderer: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );
T
tschw 已提交
2311 2312 2313 2314 2315 2316 2317 2318 2319

		}

		_usedTextureUnits += 1;

		return textureUnit;

	}

2320
	this.allocTextureUnit = allocTextureUnit;
T
tschw 已提交
2321

2322
	// this.setTexture2D = setTexture2D;
M
Mr.doob 已提交
2323
	this.setTexture2D = ( function () {
T
tschw 已提交
2324

2325
		var warned = false;
T
tschw 已提交
2326

2327
		// backwards compatibility: peel texture.texture
W
WestLangley 已提交
2328
		return function setTexture2D( texture, slot ) {
T
tschw 已提交
2329

T
Takahiro 已提交
2330
			if ( texture && texture.isWebGLRenderTarget ) {
T
tschw 已提交
2331

2332
				if ( ! warned ) {
T
tschw 已提交
2333

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

2337
				}
T
tschw 已提交
2338

2339
				texture = texture.texture;
T
tschw 已提交
2340

2341
			}
T
tschw 已提交
2342

2343
			textures.setTexture2D( texture, slot );
T
tschw 已提交
2344

2345
		};
T
tschw 已提交
2346

2347
	}() );
T
tschw 已提交
2348

M
Mr.doob 已提交
2349
	this.setTexture = ( function () {
2350 2351 2352

		var warned = false;

W
WestLangley 已提交
2353
		return function setTexture( texture, slot ) {
2354 2355 2356 2357 2358 2359 2360 2361

			if ( ! warned ) {

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

			}

2362
			textures.setTexture2D( texture, slot );
2363 2364 2365 2366 2367

		};

	}() );

M
Mr.doob 已提交
2368
	this.setTextureCube = ( function () {
2369 2370 2371

		var warned = false;

W
WestLangley 已提交
2372
		return function setTextureCube( texture, slot ) {
2373 2374

			// backwards compatibility: peel texture.texture
T
Takahiro 已提交
2375
			if ( texture && texture.isWebGLRenderTargetCube ) {
2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389

				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 已提交
2390
			if ( ( texture && texture.isCubeTexture ) ||
2391
				( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {
2392 2393 2394 2395

				// CompressedTexture can have Array in image :/

				// this function alone should take care of cube textures
2396
				textures.setTextureCube( texture, slot );
2397 2398 2399 2400 2401

			} else {

				// assumed: texture property of THREE.WebGLRenderTargetCube

2402
				textures.setTextureCubeDynamic( texture, slot );
2403 2404 2405 2406 2407 2408

			}

		};

	}() );
T
tschw 已提交
2409

2410
	this.getRenderTarget = function () {
2411 2412 2413

		return _currentRenderTarget;

M
Michael Herzog 已提交
2414
	};
2415

2416
	this.setRenderTarget = function ( renderTarget ) {
M
Mr.doob 已提交
2417

2418 2419
		_currentRenderTarget = renderTarget;

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

2422
			textures.setupRenderTarget( renderTarget );
M
Mr.doob 已提交
2423 2424 2425

		}

M
Mr.doob 已提交
2426
		var framebuffer = null;
M
Mr.doob 已提交
2427
		var isCube = false;
M
Mr.doob 已提交
2428 2429 2430

		if ( renderTarget ) {

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

M
Mr.doob 已提交
2433
			if ( renderTarget.isWebGLRenderTargetCube ) {
M
Mr.doob 已提交
2434

M
Mr.doob 已提交
2435
				framebuffer = __webglFramebuffer[ renderTarget.activeCubeFace ];
M
Mr.doob 已提交
2436
				isCube = true;
M
Mr.doob 已提交
2437 2438 2439

			} else {

M
Mr.doob 已提交
2440
				framebuffer = __webglFramebuffer;
M
Mr.doob 已提交
2441 2442 2443

			}

M
Mr.doob 已提交
2444
			_currentViewport.copy( renderTarget.viewport );
2445 2446
			_currentScissor.copy( renderTarget.scissor );
			_currentScissorTest = renderTarget.scissorTest;
2447

M
Mr.doob 已提交
2448 2449
		} else {

M
Mr.doob 已提交
2450
			_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );
2451
			_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );
2452
			_currentScissorTest = _scissorTest;
2453

M
Mr.doob 已提交
2454 2455
		}

M
Mr.doob 已提交
2456
		if ( _currentFramebuffer !== framebuffer ) {
M
Mr.doob 已提交
2457 2458 2459 2460 2461 2462

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

		}

M
Mr.doob 已提交
2463
		state.viewport( _currentViewport );
2464 2465
		state.scissor( _currentScissor );
		state.setScissorTest( _currentScissorTest );
2466

M
Mr.doob 已提交
2467 2468 2469
		if ( isCube ) {

			var textureProperties = properties.get( renderTarget.texture );
2470
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );
M
Mr.doob 已提交
2471 2472 2473

		}

M
Mr.doob 已提交
2474 2475
	};

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

0
06wj 已提交
2478
		if ( ! ( renderTarget && renderTarget.isWebGLRenderTarget ) ) {
2479

2480
			console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
G
gero3 已提交
2481
			return;
2482

G
gero3 已提交
2483
		}
2484

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

M
Mr.doob 已提交
2487
		if ( framebuffer ) {
2488

G
gero3 已提交
2489
			var restore = false;
2490

M
Mr.doob 已提交
2491
			if ( framebuffer !== _currentFramebuffer ) {
2492

M
Mr.doob 已提交
2493
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
2494

G
gero3 已提交
2495
				restore = true;
2496

G
gero3 已提交
2497
			}
2498

M
Mr.doob 已提交
2499
			try {
2500

M
Mr.doob 已提交
2501
				var texture = renderTarget.texture;
M
Mr.doob 已提交
2502 2503
				var textureFormat = texture.format;
				var textureType = texture.type;
2504

2505
				if ( textureFormat !== RGBAFormat && utils.convert( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {
2506

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

M
Mr.doob 已提交
2510
				}
2511

2512
				if ( textureType !== UnsignedByteType && utils.convert( textureType ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE ) && // IE11, Edge and Chrome Mac < 52 (#9513)
2513 2514
					! ( 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' ) ) ) {
2515

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

M
Mr.doob 已提交
2519
				}
2520

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

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

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

2527
						_gl.readPixels( x, y, width, height, utils.convert( textureFormat ), utils.convert( textureType ), buffer );
2528 2529

					}
2530

M
Mr.doob 已提交
2531
				} else {
M
Mr.doob 已提交
2532

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

				}
M
Mr.doob 已提交
2536

M
Mr.doob 已提交
2537
			} finally {
M
Mr.doob 已提交
2538

M
Mr.doob 已提交
2539 2540 2541
				if ( restore ) {

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

M
Mr.doob 已提交
2543 2544 2545
				}

			}
M
Mr.doob 已提交
2546 2547 2548

		}

M
Mr.doob 已提交
2549 2550
	};

M
Mr.doob 已提交
2551
}
R
Rich Harris 已提交
2552

T
Tristan VALCKE 已提交
2553

2554
export { WebGLRenderer };