WebGLRenderer.js 56.7 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 33
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 { BufferGeometry } from '../core/BufferGeometry.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 已提交
34

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

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

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

	parameters = parameters || {};

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

52 53 54 55 56 57
		_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 已提交
58

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

62
	var currentRenderList = null;
63

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

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

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

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

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

94 95
	// physical lights

96
	this.physicallyCorrectLights = false;
97

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

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

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

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

	// internal properties

	var _this = this,

113 114
		_isContextLost = false,

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

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

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

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

129
		//
130

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

133
		//
M
Mr.doob 已提交
134

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

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

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

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

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

148
		// clipping
T
tschw 已提交
149

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

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

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

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

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

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

167
		_infoRender = {
168

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

175
		};
M
Mr.doob 已提交
176

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

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

	};
184

185 186 187 188 189
	function getTargetPixelRatio() {

		return _currentRenderTarget === null ? _pixelRatio : 1;

	}
190

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

	var _gl;

M
Mr.doob 已提交
195 196
	try {

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

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

		if ( _gl === null ) {

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

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

			} else {

				throw 'Error creating WebGL context.';

			}
M
Mr.doob 已提交
219 220 221

		}

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

		if ( _gl.getShaderPrecisionFormat === undefined ) {

			_gl.getShaderPrecisionFormat = function () {

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

			};

		}

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

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

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

	}

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

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

250 251
	var utils;

252
	function initGLContext() {
253

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

263
		if ( extensions.get( 'OES_element_index_uint' ) ) {
M
Mr.doob 已提交
264

265
			BufferGeometry.MaxIndex = 4294967296;
266

267
		}
268

269 270
		utils = new WebGLUtils( _gl, extensions );

271
		capabilities = new WebGLCapabilities( _gl, extensions, parameters );
272

273
		state = new WebGLState( _gl, extensions, utils );
274 275
		state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );
		state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );
276

277
		properties = new WebGLProperties();
278
		textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, utils, _infoMemory );
279 280
		attributes = new WebGLAttributes( _gl );
		geometries = new WebGLGeometries( _gl, attributes, _infoMemory );
M
Mr.doob 已提交
281
		objects = new WebGLObjects( geometries, _infoRender );
282
		morphtargets = new WebGLMorphtargets( _gl );
283
		programCache = new WebGLPrograms( _this, extensions, capabilities );
284
		lights = new WebGLLights();
285
		renderLists = new WebGLRenderLists();
286

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

289 290
		bufferRenderer = new WebGLBufferRenderer( _gl, extensions, _infoRender );
		indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );
291

292 293
		flareRenderer = new WebGLFlareRenderer( _this, _gl, state, textures, capabilities );
		spriteRenderer = new WebGLSpriteRenderer( _this, _gl, state, textures, capabilities );
294

295
		_this.info.programs = programCache.programs;
296

297 298 299 300 301 302 303
		_this.context = _gl;
		_this.capabilities = capabilities;
		_this.extensions = extensions;
		_this.properties = properties;
		_this.renderLists = renderLists;
		_this.state = state;

304 305
	}

306
	initGLContext();
307

308
	// vr
309

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

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

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

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

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

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

	this.getContext = function () {

		return _gl;

	};

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

		return _gl.getContextAttributes();

	};

334 335
	this.forceContextLoss = function () {

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

	};

341 342 343 344 345 346 347
	this.forceContextRestore = function () {

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

	};

348 349
	this.getPixelRatio = function () {

350
		return _pixelRatio;
351 352 353 354 355

	};

	this.setPixelRatio = function ( value ) {

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

		_pixelRatio = value;

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

	};

364 365 366
	this.getSize = function () {

		return {
367 368
			width: _width,
			height: _height
369 370 371 372
		};

	};

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

375 376 377 378 379 380 381 382 383
		var device = vr.getDevice();

		if ( device && device.isPresenting ) {

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

		}

384 385 386
		_width = width;
		_height = height;

387 388
		_canvas.width = width * _pixelRatio;
		_canvas.height = height * _pixelRatio;
389

390
		if ( updateStyle !== false ) {
391

G
gero3 已提交
392 393
			_canvas.style.width = width + 'px';
			_canvas.style.height = height + 'px';
394

G
gero3 已提交
395
		}
M
Mr.doob 已提交
396

397
		this.setViewport( 0, 0, width, height );
M
Mr.doob 已提交
398 399 400

	};

M
Mr.doob 已提交
401 402 403 404 405 406 407 408 409
	this.getDrawingBufferSize = function () {

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

	};

410 411 412 413 414 415 416 417 418 419 420 421 422 423
	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 已提交
424 425
	this.setViewport = function ( x, y, width, height ) {

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

M
Mr.doob 已提交
429 430
	};

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

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

M
Mr.doob 已提交
436 437
	};

438 439
	this.setScissorTest = function ( boolean ) {

440
		state.setScissorTest( _scissorTest = boolean );
M
Mr.doob 已提交
441 442 443 444 445

	};

	// Clearing

446 447 448 449
	this.getClearColor = background.getClearColor;
	this.setClearColor = background.setClearColor;
	this.getClearAlpha = background.getClearAlpha;
	this.setClearAlpha = background.setClearAlpha;
M
Mr.doob 已提交
450 451 452 453 454 455 456 457 458 459

	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 );
460 461 462 463 464

	};

	this.clearColor = function () {

M
Mr.doob 已提交
465
		this.clear( true, false, false );
466 467 468 469 470

	};

	this.clearDepth = function () {

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

	};

	this.clearStencil = function () {

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

	};

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

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

	};

M
Mr.doob 已提交
488
	//
M
Mr.doob 已提交
489

M
Mr.doob 已提交
490
	this.dispose = function () {
D
dubejf 已提交
491 492

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

495 496
		renderLists.dispose();

497
		vr.dispose();
498

D
dubejf 已提交
499 500
	};

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

D
dubejf 已提交
503 504 505 506
	function onContextLost( event ) {

		event.preventDefault();

507 508
		console.log( 'THREE.WebGLRenderer: Context Lost.' );

509 510 511 512 513
		_isContextLost = true;

	}

	function onContextRestore( event ) {
D
dubejf 已提交
514

515
		console.log( 'THREE.WebGLRenderer: Context Restored.' );
516 517

		_isContextLost = false;
D
dubejf 已提交
518

519 520
		initGLContext();

M
Mr.doob 已提交
521
	}
D
dubejf 已提交
522

523
	function onMaterialDispose( event ) {
M
Mr.doob 已提交
524 525 526 527 528 529 530

		var material = event.target;

		material.removeEventListener( 'dispose', onMaterialDispose );

		deallocateMaterial( material );

531
	}
M
Mr.doob 已提交
532 533 534

	// Buffer deallocation

535
	function deallocateMaterial( material ) {
M
Mr.doob 已提交
536

537 538
		releaseMaterialProgramReference( material );

539
		properties.remove( material );
540

541
	}
542 543


544
	function releaseMaterialProgramReference( material ) {
545

546
		var programInfo = properties.get( material ).program;
M
Mr.doob 已提交
547 548 549

		material.program = undefined;

550
		if ( programInfo !== undefined ) {
M
Mr.doob 已提交
551

552
			programCache.releaseProgram( programInfo );
M
Mr.doob 已提交
553

M
Mr.doob 已提交
554 555
		}

556
	}
M
Mr.doob 已提交
557 558 559

	// Buffer rendering

M
Mr.doob 已提交
560 561 562 563 564 565 566 567 568 569
	function renderObjectImmediate( object, program, material ) {

		object.render( function ( object ) {

			_this.renderBufferImmediate( object, program, material );

		} );

	}

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

572
		state.initAttributes();
573

574
		var buffers = properties.get( object );
575

576 577 578 579
		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 已提交
580

581
		var programAttributes = program.getAttributes();
582

M
Mr.doob 已提交
583 584
		if ( object.hasPositions ) {

585
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );
M
Mr.doob 已提交
586
			_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );
587

588 589
			state.enableAttribute( programAttributes.position );
			_gl.vertexAttribPointer( programAttributes.position, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
590 591 592 593 594

		}

		if ( object.hasNormals ) {

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

597
			if ( ! material.isMeshPhongMaterial &&
598
				! material.isMeshStandardMaterial &&
599
				! material.isMeshNormalMaterial &&
600
				material.flatShading === true ) {
M
Mr.doob 已提交
601

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

604
					var array = object.normalArray;
M
Mr.doob 已提交
605

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

610 611 612
					array[ i + 0 ] = nx;
					array[ i + 1 ] = ny;
					array[ i + 2 ] = nz;
M
Mr.doob 已提交
613

614 615 616
					array[ i + 3 ] = nx;
					array[ i + 4 ] = ny;
					array[ i + 5 ] = nz;
M
Mr.doob 已提交
617

618 619 620
					array[ i + 6 ] = nx;
					array[ i + 7 ] = ny;
					array[ i + 8 ] = nz;
M
Mr.doob 已提交
621 622 623 624 625 626

				}

			}

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

628
			state.enableAttribute( programAttributes.normal );
629

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

		}

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

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

639
			state.enableAttribute( programAttributes.uv );
640

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

		}

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

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

650
			state.enableAttribute( programAttributes.color );
651

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

		}

656
		state.disableUnusedAttributes();
657

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

		object.count = 0;

	};

664
	this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {
665

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

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

M
Mr.doob 已提交
671
		var updateBuffers = false;
M
Mr.doob 已提交
672 673 674 675 676 677 678 679

		if ( geometryProgram !== _currentGeometryProgram ) {

			_currentGeometryProgram = geometryProgram;
			updateBuffers = true;

		}

680
		if ( object.morphTargetInfluences ) {
681

682
			morphtargets.update( object, geometry, material, program );
M
Mr.doob 已提交
683 684 685 686 687

			updateBuffers = true;

		}

688 689
		//

690
		var index = geometry.index;
691
		var position = geometry.attributes.position;
692
		var rangeFactor = 1;
693

694 695
		if ( material.wireframe === true ) {

696
			index = geometries.getWireframeAttribute( geometry );
697
			rangeFactor = 2;
698 699 700

		}

M
Mr.doob 已提交
701
		var attribute;
M
Mr.doob 已提交
702
		var renderer = bufferRenderer;
703

704
		if ( index !== null ) {
705

M
Mr.doob 已提交
706
			attribute = attributes.get( index );
707

708
			renderer = indexedBufferRenderer;
M
Mr.doob 已提交
709
			renderer.setIndex( attribute );
710

711
		}
M
Mr.doob 已提交
712

713
		if ( updateBuffers ) {
M
Mr.doob 已提交
714

715
			setupVertexAttributes( material, program, geometry );
M
Mr.doob 已提交
716

717
			if ( index !== null ) {
718

M
Mr.doob 已提交
719
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, attribute.buffer );
720 721 722

			}

723
		}
724

725 726
		//

727
		var dataCount = 0;
728

M
Mr.doob 已提交
729
		if ( index !== null ) {
730

M
Mr.doob 已提交
731
			dataCount = index.count;
732

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

M
Mr.doob 已提交
735
			dataCount = position.count;
736

M
Mr.doob 已提交
737
		}
738

M
Mr.doob 已提交
739 740
		var rangeStart = geometry.drawRange.start * rangeFactor;
		var rangeCount = geometry.drawRange.count * rangeFactor;
741

M
Mr.doob 已提交
742 743
		var groupStart = group !== null ? group.start * rangeFactor : 0;
		var groupCount = group !== null ? group.count * rangeFactor : Infinity;
744

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

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

750 751
		if ( drawCount === 0 ) return;

M
Mr.doob 已提交
752
		//
753

754
		if ( object.isMesh ) {
755

756
			if ( material.wireframe === true ) {
757

758
				state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );
759
				renderer.setMode( _gl.LINES );
760

761
			} else {
M
Mr.doob 已提交
762 763

				switch ( object.drawMode ) {
764

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

R
Rich Harris 已提交
769
					case TriangleStripDrawMode:
B
Ben Adams 已提交
770 771 772
						renderer.setMode( _gl.TRIANGLE_STRIP );
						break;

R
Rich Harris 已提交
773
					case TriangleFanDrawMode:
B
Ben Adams 已提交
774 775 776 777
						renderer.setMode( _gl.TRIANGLE_FAN );
						break;

				}
778

779
			}
780

781

782
		} else if ( object.isLine ) {
783

784
			var lineWidth = material.linewidth;
785

786
			if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material
787

788
			state.setLineWidth( lineWidth * getTargetPixelRatio() );
789

790
			if ( object.isLineSegments ) {
791

792
				renderer.setMode( _gl.LINES );
793

794 795 796 797
			} else if ( object.isLineLoop ) {

				renderer.setMode( _gl.LINE_LOOP );

798
			} else {
799

800
				renderer.setMode( _gl.LINE_STRIP );
801 802

			}
M
Mr.doob 已提交
803

804
		} else if ( object.isPoints ) {
805 806

			renderer.setMode( _gl.POINTS );
807 808

		}
809

T
Takahiro 已提交
810
		if ( geometry && geometry.isInstancedBufferGeometry ) {
M
Mr.doob 已提交
811 812 813

			if ( geometry.maxInstancedCount > 0 ) {

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

J
jfranc 已提交
816
			}
817 818 819

		} else {

M
Mr.doob 已提交
820
			renderer.render( drawStart, drawCount );
821

M
Mr.doob 已提交
822 823 824 825
		}

	};

826
	function setupVertexAttributes( material, program, geometry, startIndex ) {
M
Mr.doob 已提交
827

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

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

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

M
Mr.doob 已提交
835 836 837
			}

		}
B
Ben Adams 已提交
838

839 840
		if ( startIndex === undefined ) startIndex = 0;

841 842
		state.initAttributes();

843
		var geometryAttributes = geometry.attributes;
844

845
		var programAttributes = program.getAttributes();
846

847
		var materialDefaultAttributeValues = material.defaultAttributeValues;
848

849
		for ( var name in programAttributes ) {
850

851
			var programAttribute = programAttributes[ name ];
M
Mr.doob 已提交
852

M
Mr.doob 已提交
853
			if ( programAttribute >= 0 ) {
M
Mr.doob 已提交
854

855
				var geometryAttribute = geometryAttributes[ name ];
856

M
Mr.doob 已提交
857
				if ( geometryAttribute !== undefined ) {
M
Mr.doob 已提交
858

859
					var normalized = geometryAttribute.normalized;
860
					var size = geometryAttribute.itemSize;
861

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

864 865 866 867
					// TODO Attribute may not be available on context restore

					if ( attribute === undefined ) continue;

M
Mr.doob 已提交
868 869 870
					var buffer = attribute.buffer;
					var type = attribute.type;
					var bytesPerElement = attribute.bytesPerElement;
871

A
aardgoose 已提交
872
					if ( geometryAttribute.isInterleavedBufferAttribute ) {
873

M
Mr.doob 已提交
874 875 876 877
						var data = geometryAttribute.data;
						var stride = data.stride;
						var offset = geometryAttribute.offset;

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

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

M
Mr.doob 已提交
882
							if ( geometry.maxInstancedCount === undefined ) {
883

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

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

M
Mr.doob 已提交
888
						} else {
B
Ben Adams 已提交
889

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

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

M
Mr.doob 已提交
894
						_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
895
						_gl.vertexAttribPointer( programAttribute, size, type, normalized, stride * bytesPerElement, ( startIndex * stride + offset ) * bytesPerElement );
B
Ben Adams 已提交
896

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

A
aardgoose 已提交
899
						if ( geometryAttribute.isInstancedBufferAttribute ) {
B
Ben Adams 已提交
900

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

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

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

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

M
Mr.doob 已提交
909 910 911 912
						} else {

							state.enableAttribute( programAttribute );

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

M
Mr.doob 已提交
915
						_gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
916
						_gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, startIndex * size * bytesPerElement );
M
Mr.doob 已提交
917

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

920 921
				} else if ( materialDefaultAttributeValues !== undefined ) {

T
tschw 已提交
922
					var value = materialDefaultAttributeValues[ name ];
923

924
					if ( value !== undefined ) {
M
Mr.doob 已提交
925

926
						switch ( value.length ) {
M
Mr.doob 已提交
927

928 929 930
							case 2:
								_gl.vertexAttrib2fv( programAttribute, value );
								break;
M
Mr.doob 已提交
931

932 933 934
							case 3:
								_gl.vertexAttrib3fv( programAttribute, value );
								break;
M
Mr.doob 已提交
935

936 937 938
							case 4:
								_gl.vertexAttrib4fv( programAttribute, value );
								break;
939

940 941
							default:
								_gl.vertexAttrib1fv( programAttribute, value );
942 943

						}
M
Mr.doob 已提交
944 945 946 947 948 949 950 951

					}

				}

			}

		}
952

953
		state.disableUnusedAttributes();
954

M
Mr.doob 已提交
955 956
	}

M
Mr.doob 已提交
957
	// Compile
M
Mr.doob 已提交
958

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

961 962
		lightsArray.length = 0;
		shadowsArray.length = 0;
963

M
Mr.doob 已提交
964
		scene.traverse( function ( object ) {
G
gero3 已提交
965 966

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

968 969 970 971 972 973 974
				lightsArray.push( object );

				if ( object.castShadow ) {

					shadowsArray.push( object );

				}
M
Mr.doob 已提交
975

G
gero3 已提交
976
			}
M
Mr.doob 已提交
977 978 979

		} );

980
		lights.setup( lightsArray, shadowsArray, camera );
M
Mr.doob 已提交
981 982 983 984 985

		scene.traverse( function ( object ) {

			if ( object.material ) {

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

G
gero3 已提交
988
					for ( var i = 0; i < object.material.length; i ++ ) {
M
Mr.doob 已提交
989 990 991

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

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

G
gero3 已提交
994
				} else {
M
Mr.doob 已提交
995 996 997

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

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

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

		} );
G
gero3 已提交
1003 1004

	};
1005

1006
	// Animation Loop
M
Mr.doob 已提交
1007

1008 1009
	var isAnimating = false;
	var onAnimationFrame = null;
1010

1011
	function start() {
1012

1013 1014
		if ( isAnimating ) return;
		( vr.getDevice() || window ).requestAnimationFrame( loop );
1015
		isAnimating = true;
1016

1017
	}
1018

1019
	function loop( time ) {
1020

1021 1022
		if ( onAnimationFrame !== null ) onAnimationFrame( time );
		( vr.getDevice() || window ).requestAnimationFrame( loop );
1023

1024 1025 1026
	}

	this.animate = function ( callback ) {
1027

1028 1029
		onAnimationFrame = callback;
		start();
1030 1031 1032

	};

1033 1034
	// Rendering

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

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

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

		}

1044 1045
		if ( _isContextLost ) return;

M
Mr.doob 已提交
1046 1047
		// reset caching for this frame

1048
		_currentGeometryProgram = '';
1049
		_currentMaterialId = - 1;
1050
		_currentCamera = null;
M
Mr.doob 已提交
1051 1052 1053

		// update scene graph

1054
		if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
M
Mr.doob 已提交
1055 1056 1057

		// update camera matrices and frustum

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

1060 1061 1062 1063 1064 1065
		if ( vr.enabled ) {

			camera = vr.getCamera( camera );

		}

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

1069 1070 1071
		lightsArray.length = 0;
		shadowsArray.length = 0;

1072 1073
		spritesArray.length = 0;
		flaresArray.length = 0;
M
Mr.doob 已提交
1074

T
tschw 已提交
1075
		_localClippingEnabled = this.localClippingEnabled;
M
Mr.doob 已提交
1076
		_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );
T
tschw 已提交
1077

1078 1079 1080
		currentRenderList = renderLists.get( scene, camera );
		currentRenderList.init();

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

M
Mr.doob 已提交
1083
		if ( _this.sortObjects === true ) {
1084

1085
			currentRenderList.sort();
M
Mr.doob 已提交
1086

1087 1088
		}

M
Mr.doob 已提交
1089
		//
M
Mr.doob 已提交
1090

T
tschw 已提交
1091
		if ( _clippingEnabled ) _clipping.beginShadows();
T
tschw 已提交
1092

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

1095
		lights.setup( lightsArray, shadowsArray, camera );
1096

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

M
Mr.doob 已提交
1099 1100
		//

M
Mr.doob 已提交
1101
		_infoRender.frame ++;
1102 1103 1104 1105
		_infoRender.calls = 0;
		_infoRender.vertices = 0;
		_infoRender.faces = 0;
		_infoRender.points = 0;
M
Mr.doob 已提交
1106

1107 1108 1109 1110 1111 1112
		if ( renderTarget === undefined ) {

			renderTarget = null;

		}

M
Mr.doob 已提交
1113 1114
		this.setRenderTarget( renderTarget );

M
Mr.doob 已提交
1115 1116
		//

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

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

1121 1122
		var opaqueObjects = currentRenderList.opaque;
		var transparentObjects = currentRenderList.transparent;
M
Mr.doob 已提交
1123

1124
		if ( scene.overrideMaterial ) {
M
Mr.doob 已提交
1125

1126
			var overrideMaterial = scene.overrideMaterial;
1127

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

1131
		} else {
M
Mr.doob 已提交
1132

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

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

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

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

		}

1143
		// custom renderers
M
Mr.doob 已提交
1144

1145 1146
		spriteRenderer.render( spritesArray, scene, camera );
		flareRenderer.render( flaresArray, scene, camera, _currentViewport );
M
Mr.doob 已提交
1147 1148 1149

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

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

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

		}

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

1158 1159 1160
		state.buffers.depth.setTest( true );
		state.buffers.depth.setMask( true );
		state.buffers.color.setMask( true );
M
Mr.doob 已提交
1161

1162 1163
		state.setPolygonOffset( false );

M
Mr.doob 已提交
1164 1165 1166 1167 1168
		if ( vr.enabled ) {

			vr.submitFrame();

		}
M
Mr.doob 已提交
1169

M
Mr.doob 已提交
1170 1171 1172
		// _gl.finish();

	};
M
Mr.doob 已提交
1173

1174
	/*
M
Mr.doob 已提交
1175 1176
	// TODO Duplicated code (Frustum)

1177 1178
	var _sphere = new Sphere();

T
tschw 已提交
1179 1180 1181 1182 1183 1184 1185
	function isObjectViewable( object ) {

		var geometry = object.geometry;

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

M
Mr.doob 已提交
1186
		_sphere.copy( geometry.boundingSphere ).
1187
		applyMatrix4( object.matrixWorld );
M
Mr.doob 已提交
1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203

		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 已提交
1204 1205

		if ( ! _frustum.intersectsSphere( sphere ) ) return false;
T
tschw 已提交
1206 1207 1208 1209

		var numPlanes = _clipping.numPlanes;

		if ( numPlanes === 0 ) return true;
T
tschw 已提交
1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221

		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 已提交
1222
		} while ( ++ i !== numPlanes );
T
tschw 已提交
1223 1224 1225 1226

		return true;

	}
1227
	*/
T
tschw 已提交
1228

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

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

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

1235
		if ( visible ) {
1236

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

1239 1240 1241 1242 1243 1244 1245
				lightsArray.push( object );

				if ( object.castShadow ) {

					shadowsArray.push( object );

				}
M
Mr.doob 已提交
1246

1247
			} else if ( object.isSprite ) {
M
Mr.doob 已提交
1248

1249
				if ( ! object.frustumCulled || _frustum.intersectsSprite( object ) ) {
1250

1251
					spritesArray.push( object );
M
Mr.doob 已提交
1252

1253
				}
M
Mr.doob 已提交
1254

1255
			} else if ( object.isLensFlare ) {
M
Mr.doob 已提交
1256

1257
				flaresArray.push( object );
M
Mr.doob 已提交
1258

1259
			} else if ( object.isImmediateRenderObject ) {
M
Mr.doob 已提交
1260

1261
				if ( sortObjects ) {
M
Mr.doob 已提交
1262

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

1266
				}
M
Mr.doob 已提交
1267

1268
				currentRenderList.push( object, null, object.material, _vector3.z, null );
1269

1270
			} else if ( object.isMesh || object.isLine || object.isPoints ) {
1271

1272
				if ( object.isSkinnedMesh ) {
1273

1274
					object.skeleton.update();
1275

1276
				}
1277

1278
				if ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) {
1279

1280 1281 1282 1283 1284 1285
					if ( sortObjects ) {

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

					}
1286

1287 1288
					var geometry = objects.update( object );
					var material = object.material;
1289

1290
					if ( Array.isArray( material ) ) {
1291

1292
						var groups = geometry.groups;
1293

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

1296 1297
							var group = groups[ i ];
							var groupMaterial = material[ group.materialIndex ];
1298

1299
							if ( groupMaterial && groupMaterial.visible ) {
1300

1301 1302 1303
								currentRenderList.push( object, geometry, groupMaterial, _vector3.z, group );

							}
M
Mr.doob 已提交
1304

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

1307
					} else if ( material.visible ) {
1308

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

1311
					}
M
Mr.doob 已提交
1312

1313
				}
M
Mr.doob 已提交
1314

1315
			}
M
Mr.doob 已提交
1316

M
Mr.doob 已提交
1317
		}
M
Mr.doob 已提交
1318

M
Mr.doob 已提交
1319
		var children = object.children;
M
Mr.doob 已提交
1320

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

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

1325
		}
1326

1327
	}
M
Mr.doob 已提交
1328

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

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

1333
			var renderItem = renderList[ i ];
1334

1335 1336 1337 1338
			var object = renderItem.object;
			var geometry = renderItem.geometry;
			var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;
			var group = renderItem.group;
1339

1340
			if ( camera.isArrayCamera ) {
M
Mr.doob 已提交
1341

1342 1343
				_currentArrayCamera = camera;

1344
				var cameras = camera.cameras;
1345

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

1348
					var camera2 = cameras[ j ];
M
Mr.doob 已提交
1349

1350
					if ( object.layers.test( camera2.layers ) ) {
1351

1352
						var bounds = camera2.bounds;
M
Mr.doob 已提交
1353

1354 1355 1356 1357 1358
						var x = bounds.x * _width;
						var y = bounds.y * _height;
						var width = bounds.z * _width;
						var height = bounds.w * _height;

1359
						state.viewport( _currentViewport.set( x, y, width, height ).multiplyScalar( _pixelRatio ) );
1360 1361 1362 1363

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

					}
M
Mr.doob 已提交
1364

1365
				}
1366

1367
			} else {
M
Mr.doob 已提交
1368

1369 1370
				_currentArrayCamera = null;

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

1373
			}
M
Mr.doob 已提交
1374

1375
		}
M
Mr.doob 已提交
1376

1377
	}
G
gero3 已提交
1378

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

1381 1382
		object.onBeforeRender( _this, scene, camera, geometry, material, group );

M
Mr.doob 已提交
1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401
		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 已提交
1402 1403
		object.onAfterRender( _this, scene, camera, geometry, material, group );

M
Mr.doob 已提交
1404 1405
	}

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

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

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

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

1415
		var program = materialProperties.program;
T
tschw 已提交
1416
		var programChange = true;
1417

1418
		if ( program === undefined ) {
B
Ben Adams 已提交
1419

M
Mr.doob 已提交
1420 1421
			// new material
			material.addEventListener( 'dispose', onMaterialDispose );
B
Ben Adams 已提交
1422

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

M
Mr.doob 已提交
1425
			// changed glsl or parameters
1426
			releaseMaterialProgramReference( material );
B
Ben Adams 已提交
1427

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

T
tschw 已提交
1430
			// same glsl and uniform list
T
tschw 已提交
1431 1432
			return;

T
tschw 已提交
1433
		} else {
B
Ben Adams 已提交
1434

T
tschw 已提交
1435 1436
			// only rebuild uniform list
			programChange = false;
B
Ben Adams 已提交
1437 1438 1439

		}

1440
		if ( programChange ) {
B
Ben Adams 已提交
1441

1442
			if ( parameters.shaderID ) {
B
Ben Adams 已提交
1443

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

1446
				materialProperties.shader = {
1447
					name: material.type,
1448
					uniforms: UniformsUtils.clone( shader.uniforms ),
1449 1450 1451
					vertexShader: shader.vertexShader,
					fragmentShader: shader.fragmentShader
				};
B
Ben Adams 已提交
1452

1453
			} else {
B
Ben Adams 已提交
1454

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

1462
			}
G
gero3 已提交
1463

1464
			material.onBeforeCompile( materialProperties.shader );
G
gero3 已提交
1465

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

1468 1469
			materialProperties.program = program;
			material.program = program;
1470 1471 1472

		}

1473
		var programAttributes = program.getAttributes();
M
Mr.doob 已提交
1474 1475 1476 1477 1478

		if ( material.morphTargets ) {

			material.numSupportedMorphTargets = 0;

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

1481
				if ( programAttributes[ 'morphTarget' + i ] >= 0 ) {
M
Mr.doob 已提交
1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494

					material.numSupportedMorphTargets ++;

				}

			}

		}

		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

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

1497
				if ( programAttributes[ 'morphNormal' + i ] >= 0 ) {
M
Mr.doob 已提交
1498 1499 1500 1501 1502 1503 1504 1505 1506

					material.numSupportedMorphNormals ++;

				}

			}

		}

1507
		var uniforms = materialProperties.shader.uniforms;
T
tschw 已提交
1508

1509
		if ( ! material.isShaderMaterial &&
1510 1511
			! material.isRawShaderMaterial ||
			material.clipping === true ) {
T
tschw 已提交
1512

T
tschw 已提交
1513
			materialProperties.numClippingPlanes = _clipping.numPlanes;
1514
			materialProperties.numIntersection = _clipping.numIntersection;
T
tschw 已提交
1515
			uniforms.clippingPlanes = _clipping.uniform;
T
tschw 已提交
1516 1517 1518

		}

1519
		materialProperties.fog = fog;
1520

1521
		// store the light setup it was created for
1522

1523
		materialProperties.lightsHash = lights.state.hash;
1524

M
Mr.doob 已提交
1525
		if ( material.lights ) {
1526 1527 1528

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

1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541
			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;
1542
			// TODO (abelnation): add area lights shadow info to uniforms
1543

1544 1545
		}

T
tschw 已提交
1546 1547
		var progUniforms = materialProperties.program.getUniforms(),
			uniformsList =
1548
				WebGLUniforms.seqWithValue( progUniforms.seq, uniforms );
A
arose 已提交
1549

T
tschw 已提交
1550
		materialProperties.uniformsList = uniformsList;
A
arose 已提交
1551

M
Mr.doob 已提交
1552
	}
M
Mr.doob 已提交
1553

1554
	function setProgram( camera, fog, material, object ) {
M
Mr.doob 已提交
1555 1556 1557

		_usedTextureUnits = 0;

1558
		var materialProperties = properties.get( material );
1559

T
tschw 已提交
1560 1561 1562 1563 1564
		if ( _clippingEnabled ) {

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

				var useCache =
1565 1566
					camera === _currentCamera &&
					material.id === _currentMaterialId;
T
tschw 已提交
1567 1568 1569 1570

				// we might want to call this function with some ClippingGroup
				// object instead of the material, once it becomes feasible
				// (#8465, #8379)
T
tschw 已提交
1571
				_clipping.setState(
1572 1573
					material.clippingPlanes, material.clipIntersection, material.clipShadows,
					camera, materialProperties, useCache );
T
tschw 已提交
1574 1575 1576 1577 1578

			}

		}

1579
		if ( material.needsUpdate === false ) {
1580

1581
			if ( materialProperties.program === undefined ) {
1582

1583
				material.needsUpdate = true;
1584

1585
			} else if ( material.fog && materialProperties.fog !== fog ) {
1586

M
Mr.doob 已提交
1587
				material.needsUpdate = true;
1588

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

1591
				material.needsUpdate = true;
1592

1593
			} else if ( materialProperties.numClippingPlanes !== undefined &&
1594
				( materialProperties.numClippingPlanes !== _clipping.numPlanes ||
M
Mr.doob 已提交
1595
				materialProperties.numIntersection !== _clipping.numIntersection ) ) {
1596 1597 1598

				material.needsUpdate = true;

1599
			}
1600 1601 1602 1603

		}

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

1605
			initMaterial( material, fog, object );
M
Mr.doob 已提交
1606 1607 1608 1609
			material.needsUpdate = false;

		}

1610
		var refreshProgram = false;
M
Mr.doob 已提交
1611
		var refreshMaterial = false;
1612
		var refreshLights = false;
M
Mr.doob 已提交
1613

1614
		var program = materialProperties.program,
1615
			p_uniforms = program.getUniforms(),
1616
			m_uniforms = materialProperties.shader.uniforms;
M
Mr.doob 已提交
1617

1618
		if ( state.useProgram( program.program ) ) {
M
Mr.doob 已提交
1619

1620
			refreshProgram = true;
M
Mr.doob 已提交
1621
			refreshMaterial = true;
1622
			refreshLights = true;
M
Mr.doob 已提交
1623 1624 1625 1626 1627 1628

		}

		if ( material.id !== _currentMaterialId ) {

			_currentMaterialId = material.id;
1629

M
Mr.doob 已提交
1630 1631 1632 1633
			refreshMaterial = true;

		}

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

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

G
gero3 已提交
1638
			if ( capabilities.logarithmicDepthBuffer ) {
1639

T
tschw 已提交
1640
				p_uniforms.setValue( _gl, 'logDepthBufFC',
1641
					2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
1642 1643 1644

			}

1645
			// Avoid unneeded uniform updates per ArrayCamera's sub-camera
1646

1647
			if ( _currentCamera !== ( _currentArrayCamera || camera ) ) {
1648

1649
				_currentCamera = ( _currentArrayCamera || camera );
1650 1651 1652 1653 1654 1655

				// 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 已提交
1656
				refreshLights = true;		// remains set until update done
1657 1658

			}
M
Mr.doob 已提交
1659

1660 1661 1662
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)

1663
			if ( material.isShaderMaterial ||
1664 1665 1666
				material.isMeshPhongMaterial ||
				material.isMeshStandardMaterial ||
				material.envMap ) {
1667

T
tschw 已提交
1668 1669 1670
				var uCamPos = p_uniforms.map.cameraPosition;

				if ( uCamPos !== undefined ) {
1671

T
tschw 已提交
1672
					uCamPos.setValue( _gl,
1673
						_vector3.setFromMatrixPosition( camera.matrixWorld ) );
1674 1675 1676 1677 1678

				}

			}

1679
			if ( material.isMeshPhongMaterial ||
1680 1681 1682 1683
				material.isMeshLambertMaterial ||
				material.isMeshBasicMaterial ||
				material.isMeshStandardMaterial ||
				material.isShaderMaterial ||
1684
				material.skinning ) {
1685

T
tschw 已提交
1686
				p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );
1687 1688 1689

			}

M
Mr.doob 已提交
1690 1691 1692 1693 1694 1695
		}

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

1696
		if ( material.skinning ) {
M
Mr.doob 已提交
1697

T
tschw 已提交
1698 1699
			p_uniforms.setOptional( _gl, object, 'bindMatrix' );
			p_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );
1700

T
tschw 已提交
1701
			var skeleton = object.skeleton;
1702

T
tschw 已提交
1703
			if ( skeleton ) {
1704

1705 1706
				var bones = skeleton.bones;

1707
				if ( capabilities.floatVertexTextures ) {
M
Mr.doob 已提交
1708

1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733
					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
						size = _Math.nextPowerOfTwo( Math.ceil( size ) );
						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 已提交
1734 1735
					p_uniforms.setValue( _gl, 'boneTexture', skeleton.boneTexture );
					p_uniforms.setValue( _gl, 'boneTextureSize', skeleton.boneTextureSize );
M
Mr.doob 已提交
1736

T
tschw 已提交
1737
				} else {
M
Mr.doob 已提交
1738

T
tschw 已提交
1739
					p_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );
M
Mr.doob 已提交
1740 1741 1742 1743 1744 1745 1746 1747 1748

				}

			}

		}

		if ( refreshMaterial ) {

1749 1750 1751
			p_uniforms.setValue( _gl, 'toneMappingExposure', _this.toneMappingExposure );
			p_uniforms.setValue( _gl, 'toneMappingWhitePoint', _this.toneMappingWhitePoint );

M
Mr.doob 已提交
1752
			if ( material.lights ) {
M
Mr.doob 已提交
1753

1754
				// the current material requires lighting info
M
Mr.doob 已提交
1755

T
tschw 已提交
1756 1757 1758 1759 1760 1761
				// 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 已提交
1762

T
tschw 已提交
1763
				markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
G
gero3 已提交
1764

T
tschw 已提交
1765
			}
G
gero3 已提交
1766

T
tschw 已提交
1767
			// refresh uniforms common to several materials
G
gero3 已提交
1768

T
tschw 已提交
1769
			if ( fog && material.fog ) {
G
gero3 已提交
1770

T
tschw 已提交
1771
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
1772 1773 1774

			}

1775
			if ( material.isMeshBasicMaterial ) {
M
Mr.doob 已提交
1776 1777 1778

				refreshUniformsCommon( m_uniforms, material );

1779
			} else if ( material.isMeshLambertMaterial ) {
M
Mr.doob 已提交
1780

1781 1782
				refreshUniformsCommon( m_uniforms, material );
				refreshUniformsLambert( m_uniforms, material );
M
Mr.doob 已提交
1783

1784
			} else if ( material.isMeshPhongMaterial ) {
M
Mr.doob 已提交
1785

1786
				refreshUniformsCommon( m_uniforms, material );
M
Mr.doob 已提交
1787

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

1790
					refreshUniformsToon( m_uniforms, material );
M
Mr.doob 已提交
1791

1792
				} else {
M
Mr.doob 已提交
1793

1794
					refreshUniformsPhong( m_uniforms, material );
M
Mr.doob 已提交
1795

1796
				}
1797

1798
			} else if ( material.isMeshStandardMaterial ) {
1799

1800
				refreshUniformsCommon( m_uniforms, material );
T
Takahiro 已提交
1801

1802
				if ( material.isMeshPhysicalMaterial ) {
T
Takahiro 已提交
1803

1804
					refreshUniformsPhysical( m_uniforms, material );
1805

1806
				} else {
1807

1808
					refreshUniformsStandard( m_uniforms, material );
W
WestLangley 已提交
1809

1810
				}
W
WestLangley 已提交
1811

1812
			} else if ( material.isMeshDepthMaterial ) {
M
Mr.doob 已提交
1813

1814
				refreshUniformsCommon( m_uniforms, material );
W
WestLangley 已提交
1815
				refreshUniformsDepth( m_uniforms, material );
1816

W
WestLangley 已提交
1817
			} else if ( material.isMeshDistanceMaterial ) {
1818

1819
				refreshUniformsCommon( m_uniforms, material );
W
WestLangley 已提交
1820
				refreshUniformsDistance( m_uniforms, material );
1821

1822
			} else if ( material.isMeshNormalMaterial ) {
M
Mr.doob 已提交
1823

1824
				refreshUniformsCommon( m_uniforms, material );
1825
				refreshUniformsNormal( m_uniforms, material );
M
Mr.doob 已提交
1826

1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840
			} else if ( material.isLineBasicMaterial ) {

				refreshUniformsLine( m_uniforms, material );

				if ( material.isLineDashedMaterial ) {

					refreshUniformsDash( m_uniforms, material );

				}

			} else if ( material.isPointsMaterial ) {

				refreshUniformsPoints( m_uniforms, material );

1841 1842 1843 1844 1845
			} else if ( material.isShadowMaterial ) {

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

M
Mr.doob 已提交
1846 1847
			}

M
Mr.doob 已提交
1848 1849 1850 1851 1852 1853
			// 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 已提交
1854
			WebGLUniforms.upload(
1855
				_gl, materialProperties.uniformsList, m_uniforms, _this );
A
arose 已提交
1856 1857 1858

		}

M
Mr.doob 已提交
1859

T
tschw 已提交
1860
		// common matrices
M
Mr.doob 已提交
1861

M
Mr.doob 已提交
1862 1863
		p_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix );
		p_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix );
T
tschw 已提交
1864
		p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );
A
arose 已提交
1865

T
tschw 已提交
1866
		return program;
A
arose 已提交
1867 1868 1869

	}

M
Mr.doob 已提交
1870 1871
	// Uniforms (refresh uniforms objects)

M
Mr.doob 已提交
1872
	function refreshUniformsCommon( uniforms, material ) {
M
Mr.doob 已提交
1873 1874 1875

		uniforms.opacity.value = material.opacity;

1876 1877 1878 1879 1880
		if ( material.color ) {

			uniforms.diffuse.value = material.color;

		}
M
Mr.doob 已提交
1881

1882
		if ( material.emissive ) {
M
Mr.doob 已提交
1883

1884
			uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );
M
Mr.doob 已提交
1885 1886 1887

		}

1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919
		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 已提交
1920

1921 1922 1923 1924 1925 1926 1927
		if ( material.lightMap ) {

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

		}

1928
		if ( material.aoMap ) {
1929

1930 1931
			uniforms.aoMap.value = material.aoMap;
			uniforms.aoMapIntensity.value = material.aoMapIntensity;
1932 1933 1934

		}

M
Mr.doob 已提交
1935
		// uv repeat and offset setting priorities
M
Mr.doob 已提交
1936 1937 1938 1939 1940
		// 1. color map
		// 2. specular map
		// 3. normal map
		// 4. bump map
		// 5. alpha map
1941
		// 6. emissive map
M
Mr.doob 已提交
1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952

		var uvScaleMap;

		if ( material.map ) {

			uvScaleMap = material.map;

		} else if ( material.specularMap ) {

			uvScaleMap = material.specularMap;

1953 1954 1955 1956
		} else if ( material.displacementMap ) {

			uvScaleMap = material.displacementMap;

M
Mr.doob 已提交
1957 1958 1959 1960 1961 1962 1963 1964
		} else if ( material.normalMap ) {

			uvScaleMap = material.normalMap;

		} else if ( material.bumpMap ) {

			uvScaleMap = material.bumpMap;

1965 1966 1967 1968 1969 1970 1971 1972
		} else if ( material.roughnessMap ) {

			uvScaleMap = material.roughnessMap;

		} else if ( material.metalnessMap ) {

			uvScaleMap = material.metalnessMap;

1973 1974 1975 1976
		} else if ( material.alphaMap ) {

			uvScaleMap = material.alphaMap;

1977 1978 1979 1980
		} else if ( material.emissiveMap ) {

			uvScaleMap = material.emissiveMap;

M
Mr.doob 已提交
1981 1982 1983 1984
		}

		if ( uvScaleMap !== undefined ) {

1985
			// backwards compatibility
1986
			if ( uvScaleMap.isWebGLRenderTarget ) {
M
Mr.doob 已提交
1987 1988 1989 1990 1991

				uvScaleMap = uvScaleMap.texture;

			}

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

M
Mugen87 已提交
1994 1995 1996 1997
				var offset = uvScaleMap.offset;
				var repeat = uvScaleMap.repeat;
				var rotation = uvScaleMap.rotation;
				uvScaleMap.matrix.setUvTransform( offset.x, offset.y, repeat.x, repeat.y, rotation, 0.5, 0.5 );
W
WestLangley 已提交
1998 1999

			}
M
Mr.doob 已提交
2000

2001 2002
			uniforms.uvTransform.value.copy( uvScaleMap.matrix );

M
Mr.doob 已提交
2003 2004
		}

M
Mr.doob 已提交
2005
	}
M
Mr.doob 已提交
2006

M
Mr.doob 已提交
2007
	function refreshUniformsLine( uniforms, material ) {
M
Mr.doob 已提交
2008 2009 2010 2011

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

M
Mr.doob 已提交
2012
	}
M
Mr.doob 已提交
2013

M
Mr.doob 已提交
2014
	function refreshUniformsDash( uniforms, material ) {
M
Mr.doob 已提交
2015 2016 2017 2018 2019

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

M
Mr.doob 已提交
2020
	}
M
Mr.doob 已提交
2021

M
Mr.doob 已提交
2022
	function refreshUniformsPoints( uniforms, material ) {
M
Mr.doob 已提交
2023

2024
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
2025
		uniforms.opacity.value = material.opacity;
2026
		uniforms.size.value = material.size * _pixelRatio;
2027
		uniforms.scale.value = _height * 0.5;
M
Mr.doob 已提交
2028 2029 2030

		uniforms.map.value = material.map;

2031 2032
		if ( material.map !== null ) {

W
WestLangley 已提交
2033
			if ( material.map.matrixAutoUpdate === true ) {
2034

M
Mugen87 已提交
2035 2036 2037 2038
				var offset = material.map.offset;
				var repeat = material.map.repeat;
				var rotation = material.map.rotation;
				material.map.matrix.setUvTransform( offset.x, offset.y, repeat.x, repeat.y, rotation, 0.5, 0.5 );
W
WestLangley 已提交
2039 2040

			}
2041

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

2044 2045
		}

M
Mr.doob 已提交
2046
	}
M
Mr.doob 已提交
2047

M
Mr.doob 已提交
2048
	function refreshUniformsFog( uniforms, fog ) {
M
Mr.doob 已提交
2049 2050 2051

		uniforms.fogColor.value = fog.color;

2052
		if ( fog.isFog ) {
M
Mr.doob 已提交
2053 2054 2055 2056

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

2057
		} else if ( fog.isFogExp2 ) {
M
Mr.doob 已提交
2058 2059 2060 2061 2062

			uniforms.fogDensity.value = fog.density;

		}

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

M
Mr.doob 已提交
2065
	function refreshUniformsLambert( uniforms, material ) {
2066 2067 2068 2069 2070 2071 2072 2073 2074

		if ( material.emissiveMap ) {

			uniforms.emissiveMap.value = material.emissiveMap;

		}

	}

M
Mr.doob 已提交
2075
	function refreshUniformsPhong( uniforms, material ) {
M
Mr.doob 已提交
2076

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

2080
		if ( material.emissiveMap ) {
2081

2082
			uniforms.emissiveMap.value = material.emissiveMap;
2083

2084
		}
M
Mr.doob 已提交
2085

2086 2087 2088 2089
		if ( material.bumpMap ) {

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

2091
		}
M
Mr.doob 已提交
2092

2093 2094 2095 2096 2097 2098
		if ( material.normalMap ) {

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

		}
M
Mr.doob 已提交
2099

2100 2101 2102 2103 2104
		if ( material.displacementMap ) {

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

2106
		}
2107

T
Takahiro 已提交
2108 2109 2110 2111 2112 2113
	}

	function refreshUniformsToon( uniforms, material ) {

		refreshUniformsPhong( uniforms, material );

T
Takahiro 已提交
2114
		if ( material.gradientMap ) {
T
Takahiro 已提交
2115

T
Takahiro 已提交
2116
			uniforms.gradientMap.value = material.gradientMap;
T
Takahiro 已提交
2117 2118 2119

		}

2120 2121
	}

M
Mr.doob 已提交
2122
	function refreshUniformsStandard( uniforms, material ) {
W
WestLangley 已提交
2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175

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

2178 2179 2180
		uniforms.clearCoat.value = material.clearCoat;
		uniforms.clearCoatRoughness.value = material.clearCoatRoughness;

W
WestLangley 已提交
2181 2182 2183 2184
		refreshUniformsStandard( uniforms, material );

	}

W
WestLangley 已提交
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
	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;

	}

2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238
	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;

		}

	}

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

M
Mr.doob 已提交
2241
	function markUniformsLightsNeedsUpdate( uniforms, value ) {
2242

M
Mr.doob 已提交
2243
		uniforms.ambientLightColor.needsUpdate = value;
2244

B
Ben Houston 已提交
2245 2246 2247
		uniforms.directionalLights.needsUpdate = value;
		uniforms.pointLights.needsUpdate = value;
		uniforms.spotLights.needsUpdate = value;
2248
		uniforms.rectAreaLights.needsUpdate = value;
B
Ben Houston 已提交
2249
		uniforms.hemisphereLights.needsUpdate = value;
2250

M
Mr.doob 已提交
2251
	}
2252

M
Mr.doob 已提交
2253 2254 2255 2256
	// GL state setting

	this.setFaceCulling = function ( cullFace, frontFaceDirection ) {

T
tschw 已提交
2257
		state.setCullFace( cullFace );
R
Rich Harris 已提交
2258
		state.setFlipSided( frontFaceDirection === FrontFaceDirectionCW );
M
Mr.doob 已提交
2259 2260 2261 2262 2263

	};

	// Textures

T
tschw 已提交
2264 2265 2266 2267 2268 2269
	function allocTextureUnit() {

		var textureUnit = _usedTextureUnits;

		if ( textureUnit >= capabilities.maxTextures ) {

M
Mugen87 已提交
2270
			console.warn( 'THREE.WebGLRenderer: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );
T
tschw 已提交
2271 2272 2273 2274 2275 2276 2277 2278 2279

		}

		_usedTextureUnits += 1;

		return textureUnit;

	}

2280
	this.allocTextureUnit = allocTextureUnit;
T
tschw 已提交
2281

2282
	// this.setTexture2D = setTexture2D;
M
Mr.doob 已提交
2283
	this.setTexture2D = ( function () {
T
tschw 已提交
2284

2285
		var warned = false;
T
tschw 已提交
2286

2287
		// backwards compatibility: peel texture.texture
W
WestLangley 已提交
2288
		return function setTexture2D( texture, slot ) {
T
tschw 已提交
2289

T
Takahiro 已提交
2290
			if ( texture && texture.isWebGLRenderTarget ) {
T
tschw 已提交
2291

2292
				if ( ! warned ) {
T
tschw 已提交
2293

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

2297
				}
T
tschw 已提交
2298

2299
				texture = texture.texture;
T
tschw 已提交
2300

2301
			}
T
tschw 已提交
2302

2303
			textures.setTexture2D( texture, slot );
T
tschw 已提交
2304

2305
		};
T
tschw 已提交
2306

2307
	}() );
T
tschw 已提交
2308

M
Mr.doob 已提交
2309
	this.setTexture = ( function () {
2310 2311 2312

		var warned = false;

W
WestLangley 已提交
2313
		return function setTexture( texture, slot ) {
2314 2315 2316 2317 2318 2319 2320 2321

			if ( ! warned ) {

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

			}

2322
			textures.setTexture2D( texture, slot );
2323 2324 2325 2326 2327

		};

	}() );

M
Mr.doob 已提交
2328
	this.setTextureCube = ( function () {
2329 2330 2331

		var warned = false;

W
WestLangley 已提交
2332
		return function setTextureCube( texture, slot ) {
2333 2334

			// backwards compatibility: peel texture.texture
T
Takahiro 已提交
2335
			if ( texture && texture.isWebGLRenderTargetCube ) {
2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349

				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 已提交
2350
			if ( ( texture && texture.isCubeTexture ) ||
2351
				( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {
2352 2353 2354 2355

				// CompressedTexture can have Array in image :/

				// this function alone should take care of cube textures
2356
				textures.setTextureCube( texture, slot );
2357 2358 2359 2360 2361

			} else {

				// assumed: texture property of THREE.WebGLRenderTargetCube

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

			}

		};

	}() );
T
tschw 已提交
2369

2370
	this.getRenderTarget = function () {
2371 2372 2373

		return _currentRenderTarget;

M
Michael Herzog 已提交
2374
	};
2375

2376
	this.setRenderTarget = function ( renderTarget ) {
M
Mr.doob 已提交
2377

2378 2379
		_currentRenderTarget = renderTarget;

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

2382
			textures.setupRenderTarget( renderTarget );
M
Mr.doob 已提交
2383 2384 2385

		}

M
Mr.doob 已提交
2386
		var framebuffer = null;
M
Mr.doob 已提交
2387
		var isCube = false;
M
Mr.doob 已提交
2388 2389 2390

		if ( renderTarget ) {

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

M
Mr.doob 已提交
2393
			if ( renderTarget.isWebGLRenderTargetCube ) {
M
Mr.doob 已提交
2394

M
Mr.doob 已提交
2395
				framebuffer = __webglFramebuffer[ renderTarget.activeCubeFace ];
M
Mr.doob 已提交
2396
				isCube = true;
M
Mr.doob 已提交
2397 2398 2399

			} else {

M
Mr.doob 已提交
2400
				framebuffer = __webglFramebuffer;
M
Mr.doob 已提交
2401 2402 2403

			}

M
Mr.doob 已提交
2404
			_currentViewport.copy( renderTarget.viewport );
2405 2406
			_currentScissor.copy( renderTarget.scissor );
			_currentScissorTest = renderTarget.scissorTest;
2407

M
Mr.doob 已提交
2408 2409
		} else {

M
Mr.doob 已提交
2410
			_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );
2411
			_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );
2412
			_currentScissorTest = _scissorTest;
2413

M
Mr.doob 已提交
2414 2415
		}

M
Mr.doob 已提交
2416
		if ( _currentFramebuffer !== framebuffer ) {
M
Mr.doob 已提交
2417 2418 2419 2420 2421 2422

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

		}

M
Mr.doob 已提交
2423
		state.viewport( _currentViewport );
2424 2425
		state.scissor( _currentScissor );
		state.setScissorTest( _currentScissorTest );
2426

M
Mr.doob 已提交
2427 2428 2429
		if ( isCube ) {

			var textureProperties = properties.get( renderTarget.texture );
2430
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );
M
Mr.doob 已提交
2431 2432 2433

		}

M
Mr.doob 已提交
2434 2435
	};

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

0
06wj 已提交
2438
		if ( ! ( renderTarget && renderTarget.isWebGLRenderTarget ) ) {
2439

2440
			console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
G
gero3 已提交
2441
			return;
2442

G
gero3 已提交
2443
		}
2444

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

M
Mr.doob 已提交
2447
		if ( framebuffer ) {
2448

G
gero3 已提交
2449
			var restore = false;
2450

M
Mr.doob 已提交
2451
			if ( framebuffer !== _currentFramebuffer ) {
2452

M
Mr.doob 已提交
2453
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
2454

G
gero3 已提交
2455
				restore = true;
2456

G
gero3 已提交
2457
			}
2458

M
Mr.doob 已提交
2459
			try {
2460

M
Mr.doob 已提交
2461
				var texture = renderTarget.texture;
M
Mr.doob 已提交
2462 2463
				var textureFormat = texture.format;
				var textureType = texture.type;
2464

2465
				if ( textureFormat !== RGBAFormat && utils.convert( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {
2466

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

M
Mr.doob 已提交
2470
				}
2471

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

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

M
Mr.doob 已提交
2479
				}
2480

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

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

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

2487
						_gl.readPixels( x, y, width, height, utils.convert( textureFormat ), utils.convert( textureType ), buffer );
2488 2489

					}
2490

M
Mr.doob 已提交
2491
				} else {
M
Mr.doob 已提交
2492

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

				}
M
Mr.doob 已提交
2496

M
Mr.doob 已提交
2497
			} finally {
M
Mr.doob 已提交
2498

M
Mr.doob 已提交
2499 2500 2501
				if ( restore ) {

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

M
Mr.doob 已提交
2503 2504 2505
				}

			}
M
Mr.doob 已提交
2506 2507 2508

		}

M
Mr.doob 已提交
2509 2510
	};

M
Mr.doob 已提交
2511
}
R
Rich Harris 已提交
2512

T
Tristan VALCKE 已提交
2513

2514
export { WebGLRenderer };