WebGLRenderer.js 66.4 KB
Newer Older
1
import { REVISION, MaxEquation, MinEquation, RGB_ETC1_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT5_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT1_Format, RGB_S3TC_DXT1_Format, SrcAlphaSaturateFactor, OneMinusDstColorFactor, DstColorFactor, OneMinusDstAlphaFactor, DstAlphaFactor, OneMinusSrcAlphaFactor, SrcAlphaFactor, OneMinusSrcColorFactor, SrcColorFactor, OneFactor, ZeroFactor, ReverseSubtractEquation, SubtractEquation, AddEquation, DepthFormat, DepthStencilFormat, LuminanceAlphaFormat, LuminanceFormat, RGBAFormat, RGBFormat, AlphaFormat, HalfFloatType, FloatType, UnsignedIntType, IntType, UnsignedShortType, ShortType, ByteType, UnsignedInt248Type, UnsignedShort565Type, UnsignedShort5551Type, UnsignedShort4444Type, UnsignedByteType, LinearMipMapLinearFilter, LinearMipMapNearestFilter, LinearFilter, NearestMipMapLinearFilter, NearestMipMapNearestFilter, NearestFilter, MirroredRepeatWrapping, ClampToEdgeWrapping, RepeatWrapping, FrontFaceDirectionCW, NoBlending, TriangleFanDrawMode, TriangleStripDrawMode, TrianglesDrawMode, NoColors, FlatShading, LinearToneMapping } from '../constants';
2
import { _Math } from '../math/Math';
R
Rich Harris 已提交
3
import { Matrix4 } from '../math/Matrix4';
4
import { DataTexture } from '../textures/DataTexture';
R
Rich Harris 已提交
5
import { WebGLUniforms } from './webgl/WebGLUniforms';
M
Mr.doob 已提交
6
import { UniformsLib } from './shaders/UniformsLib';
7
import { UniformsUtils } from './shaders/UniformsUtils';
R
Rich Harris 已提交
8 9 10 11
import { ShaderLib } from './shaders/ShaderLib';
import { LensFlarePlugin } from './webgl/plugins/LensFlarePlugin';
import { SpritePlugin } from './webgl/plugins/SpritePlugin';
import { WebGLShadowMap } from './webgl/WebGLShadowMap';
12
import { WebGLAttributes } from './webgl/WebGLAttributes';
13
import { WebGLBackground } from './webgl/WebGLBackground';
14
import { WebGLRenderLists } from './webgl/WebGLRenderLists';
R
Rich Harris 已提交
15 16
import { WebGLIndexedBufferRenderer } from './webgl/WebGLIndexedBufferRenderer';
import { WebGLBufferRenderer } from './webgl/WebGLBufferRenderer';
17
import { WebGLGeometries } from './webgl/WebGLGeometries';
R
Rich Harris 已提交
18 19
import { WebGLLights } from './webgl/WebGLLights';
import { WebGLObjects } from './webgl/WebGLObjects';
20
import { WebGLPrograms } from './webgl/WebGLPrograms';
R
Rich Harris 已提交
21 22 23 24
import { WebGLTextures } from './webgl/WebGLTextures';
import { WebGLProperties } from './webgl/WebGLProperties';
import { WebGLState } from './webgl/WebGLState';
import { WebGLCapabilities } from './webgl/WebGLCapabilities';
25
import { WebVRManager } from './webvr/WebVRManager';
R
Rich Harris 已提交
26 27 28
import { BufferGeometry } from '../core/BufferGeometry';
import { WebGLExtensions } from './webgl/WebGLExtensions';
import { Vector3 } from '../math/Vector3';
M
Mr.doob 已提交
29
// import { Sphere } from '../math/Sphere';
R
Rich Harris 已提交
30 31 32 33
import { WebGLClipping } from './webgl/WebGLClipping';
import { Frustum } from '../math/Frustum';
import { Vector4 } from '../math/Vector4';

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

M
Mr.doob 已提交
58
	var lights = [];
M
Mr.doob 已提交
59

60
	var currentRenderList = null;
61

62 63
	var morphInfluences = new Float32Array( 8 );

M
Mr.doob 已提交
64 65 66
	var sprites = [];
	var lensFlares = [];

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
		// internal state cache
M
Mr.doob 已提交
114

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

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

124 125
		_currentScissor = new Vector4(),
		_currentScissorTest = null,
126

127
		_currentViewport = new Vector4(),
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

140 141
		_scissor = new Vector4( 0, 0, _width, _height ),
		_scissorTest = false,
142

143
		_viewport = new Vector4( 0, 0, _width, _height ),
144

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

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

149
		// clipping
T
tschw 已提交
150

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

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

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

A
aardgoose 已提交
159
		_vector3 = new Vector3(),
160
		_matrix4 = new Matrix4(),
A
aardgoose 已提交
161
		_matrix42 = new Matrix4(),
M
Mr.doob 已提交
162

163
		// light arrays cache
M
Mr.doob 已提交
164

165
		_lights = {
M
Mr.doob 已提交
166

167
			hash: '',
168

M
Mr.doob 已提交
169 170 171 172 173 174 175 176 177 178 179 180
			ambient: [ 0, 0, 0 ],
			directional: [],
			directionalShadowMap: [],
			directionalShadowMatrix: [],
			spot: [],
			spotShadowMap: [],
			spotShadowMatrix: [],
			rectArea: [],
			point: [],
			pointShadowMap: [],
			pointShadowMatrix: [],
			hemi: [],
181

182
			shadows: []
M
Mr.doob 已提交
183

184
		},
185

186
		// info
M
Mr.doob 已提交
187

M
Mr.doob 已提交
188 189 190 191 192
		_infoMemory = {
			geometries: 0,
			textures: 0
		},

193
		_infoRender = {
194

195
			frame: 0,
196 197 198 199
			calls: 0,
			vertices: 0,
			faces: 0,
			points: 0
200

201
		};
M
Mr.doob 已提交
202

M
Mr.doob 已提交
203
	this.info = {
204

M
Mr.doob 已提交
205
		render: _infoRender,
M
Mr.doob 已提交
206
		memory: _infoMemory,
207
		programs: null
M
Mr.doob 已提交
208 209

	};
210

211

M
Mr.doob 已提交
212 213 214 215
	// initialize

	var _gl;

M
Mr.doob 已提交
216 217
	try {

218
		var contextAttributes = {
M
Mr.doob 已提交
219 220 221 222 223 224 225 226
			alpha: _alpha,
			depth: _depth,
			stencil: _stencil,
			antialias: _antialias,
			premultipliedAlpha: _premultipliedAlpha,
			preserveDrawingBuffer: _preserveDrawingBuffer
		};

227
		_gl = _context || _canvas.getContext( 'webgl', contextAttributes ) || _canvas.getContext( 'experimental-webgl', contextAttributes );
M
Mr.doob 已提交
228 229 230

		if ( _gl === null ) {

G
gero3 已提交
231
			if ( _canvas.getContext( 'webgl' ) !== null ) {
232 233 234 235 236 237 238 239

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

			} else {

				throw 'Error creating WebGL context.';

			}
M
Mr.doob 已提交
240 241 242

		}

243 244 245 246 247 248 249 250 251 252 253 254
		// Some experimental-webgl implementations do not have getShaderPrecisionFormat

		if ( _gl.getShaderPrecisionFormat === undefined ) {

			_gl.getShaderPrecisionFormat = function () {

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

			};

		}

D
dubejf 已提交
255
		_canvas.addEventListener( 'webglcontextlost', onContextLost, false );
256

M
Mr.doob 已提交
257 258
	} catch ( error ) {

259
		console.error( 'THREE.WebGLRenderer: ' + error );
M
Mr.doob 已提交
260 261 262

	}

R
Rich Harris 已提交
263
	var extensions = new WebGLExtensions( _gl );
264

265
	extensions.get( 'WEBGL_depth_texture' );
266 267
	extensions.get( 'OES_texture_float' );
	extensions.get( 'OES_texture_float_linear' );
268 269
	extensions.get( 'OES_texture_half_float' );
	extensions.get( 'OES_texture_half_float_linear' );
270
	extensions.get( 'OES_standard_derivatives' );
B
Ben Adams 已提交
271
	extensions.get( 'ANGLE_instanced_arrays' );
272

273 274
	if ( extensions.get( 'OES_element_index_uint' ) ) {

R
Rich Harris 已提交
275
		BufferGeometry.MaxIndex = 4294967296;
276 277 278

	}

R
Rich Harris 已提交
279
	var capabilities = new WebGLCapabilities( _gl, extensions, parameters );
M
Mr.doob 已提交
280

R
Rich Harris 已提交
281
	var state = new WebGLState( _gl, extensions, paramThreeToGL );
282

R
Rich Harris 已提交
283
	var properties = new WebGLProperties();
M
Mr.doob 已提交
284
	var textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, _infoMemory );
M
Mr.doob 已提交
285
	var attributes = new WebGLAttributes( _gl );
M
Mr.doob 已提交
286
	var geometries = new WebGLGeometries( _gl, attributes, _infoMemory );
287
	var objects = new WebGLObjects( _gl, geometries, _infoRender );
R
Rich Harris 已提交
288 289
	var programCache = new WebGLPrograms( this, capabilities );
	var lightCache = new WebGLLights();
290
	var renderLists = new WebGLRenderLists();
291 292

	var background = new WebGLBackground( this, state, objects, _premultipliedAlpha );
293
	var vr = new WebVRManager( this );
294

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

R
Rich Harris 已提交
297 298
	var bufferRenderer = new WebGLBufferRenderer( _gl, extensions, _infoRender );
	var indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );
299

M
Mr.doob 已提交
300 301
	//

302 303
	function getTargetPixelRatio() {

304
		return _currentRenderTarget === null ? _pixelRatio : 1;
305 306 307

	}

308
	function setDefaultGLState() {
M
Mr.doob 已提交
309

M
Mr.doob 已提交
310
		state.init();
M
Mr.doob 已提交
311

312 313
		state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );
		state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );
M
Mr.doob 已提交
314

315
	}
316

317
	function resetGLState() {
318 319 320 321

		_currentProgram = null;
		_currentCamera = null;

322
		_currentGeometryProgram = '';
323 324
		_currentMaterialId = - 1;

M
Mr.doob 已提交
325 326
		state.reset();

327
	}
M
Mr.doob 已提交
328 329 330 331

	setDefaultGLState();

	this.context = _gl;
M
Mr.doob 已提交
332
	this.capabilities = capabilities;
333
	this.extensions = extensions;
334
	this.properties = properties;
A
aardgoose 已提交
335
	this.renderLists = renderLists;
M
Mr.doob 已提交
336
	this.state = state;
337
	this.vr = vr;
M
Mr.doob 已提交
338

M
Mr.doob 已提交
339 340
	// shadow map

R
Rich Harris 已提交
341
	var shadowMap = new WebGLShadowMap( this, _lights, objects, capabilities );
M
Mr.doob 已提交
342

343
	this.shadowMap = shadowMap;
M
Mr.doob 已提交
344

M
Mr.doob 已提交
345

M
Mr.doob 已提交
346 347
	// Plugins

R
Rich Harris 已提交
348 349
	var spritePlugin = new SpritePlugin( this, sprites );
	var lensFlarePlugin = new LensFlarePlugin( this, lensFlares );
M
Mr.doob 已提交
350

M
Mr.doob 已提交
351 352 353 354 355 356 357 358
	// API

	this.getContext = function () {

		return _gl;

	};

359 360 361 362 363 364
	this.getContextAttributes = function () {

		return _gl.getContextAttributes();

	};

365 366
	this.forceContextLoss = function () {

M
Michael Bond 已提交
367 368
		var extension = extensions.get( 'WEBGL_lose_context' );
		if ( extension ) extension.loseContext();
369 370 371

	};

372
	this.getMaxAnisotropy = function () {
373

374
		return capabilities.getMaxAnisotropy();
375

376
	};
M
Mr.doob 已提交
377 378 379

	this.getPrecision = function () {

G
gero3 已提交
380
		return capabilities.precision;
M
Mr.doob 已提交
381 382 383

	};

384 385
	this.getPixelRatio = function () {

386
		return _pixelRatio;
387 388 389 390 391

	};

	this.setPixelRatio = function ( value ) {

392 393 394 395
		if ( value === undefined ) return;

		_pixelRatio = value;

M
Mr.doob 已提交
396
		this.setSize( _width, _height, false );
397 398 399

	};

400 401 402
	this.getSize = function () {

		return {
403 404
			width: _width,
			height: _height
405 406 407 408
		};

	};

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

411 412 413
		_width = width;
		_height = height;

414 415
		_canvas.width = width * _pixelRatio;
		_canvas.height = height * _pixelRatio;
416

417
		if ( updateStyle !== false ) {
418

G
gero3 已提交
419 420
			_canvas.style.width = width + 'px';
			_canvas.style.height = height + 'px';
421

G
gero3 已提交
422
		}
M
Mr.doob 已提交
423

424
		this.setViewport( 0, 0, width, height );
M
Mr.doob 已提交
425 426 427 428 429

	};

	this.setViewport = function ( x, y, width, height ) {

430
		_viewport.set( x, _height - y - height, width, height )
431
		state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );
432

M
Mr.doob 已提交
433 434
	};

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

437
		_scissor.set( x, _height - y - height, width, height )
438
		state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );
439

M
Mr.doob 已提交
440 441
	};

442 443
	this.setScissorTest = function ( boolean ) {

444
		state.setScissorTest( _scissorTest = boolean );
M
Mr.doob 已提交
445 446 447 448 449

	};

	// Clearing

450 451 452 453
	this.getClearColor = background.getClearColor;
	this.setClearColor = background.setClearColor;
	this.getClearAlpha = background.getClearAlpha;
	this.setClearAlpha = background.setClearAlpha;
M
Mr.doob 已提交
454 455 456 457 458 459 460 461 462 463

	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 );
464 465 466 467 468

	};

	this.clearColor = function () {

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

	};

	this.clearDepth = function () {

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

	};

	this.clearStencil = function () {

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

	};

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

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

	};

M
Mr.doob 已提交
492 493
	// Reset

494
	this.resetGLState = resetGLState;
M
Mr.doob 已提交
495

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

		_canvas.removeEventListener( 'webglcontextlost', onContextLost, false );

500 501
		renderLists.dispose();

D
dubejf 已提交
502 503
	};

M
Mr.doob 已提交
504
	// Events
M
Mr.doob 已提交
505

D
dubejf 已提交
506 507 508 509 510 511 512 513
	function onContextLost( event ) {

		event.preventDefault();

		resetGLState();
		setDefaultGLState();

		properties.clear();
514
		objects.clear();
D
dubejf 已提交
515

M
Mr.doob 已提交
516
	}
D
dubejf 已提交
517

518
	function onMaterialDispose( event ) {
M
Mr.doob 已提交
519 520 521 522 523 524 525

		var material = event.target;

		material.removeEventListener( 'dispose', onMaterialDispose );

		deallocateMaterial( material );

526
	}
M
Mr.doob 已提交
527 528 529

	// Buffer deallocation

530
	function deallocateMaterial( material ) {
M
Mr.doob 已提交
531

532 533
		releaseMaterialProgramReference( material );

534
		properties.remove( material );
535

536
	}
537 538


539
	function releaseMaterialProgramReference( material ) {
540

541
		var programInfo = properties.get( material ).program;
M
Mr.doob 已提交
542 543 544

		material.program = undefined;

545
		if ( programInfo !== undefined ) {
M
Mr.doob 已提交
546

547
			programCache.releaseProgram( programInfo );
M
Mr.doob 已提交
548

M
Mr.doob 已提交
549 550
		}

551
	}
M
Mr.doob 已提交
552 553 554

	// Buffer rendering

M
Mr.doob 已提交
555 556 557 558 559 560 561 562 563 564
	function renderObjectImmediate( object, program, material ) {

		object.render( function ( object ) {

			_this.renderBufferImmediate( object, program, material );

		} );

	}

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

567
		state.initAttributes();
568

569
		var buffers = properties.get( object );
570

571 572 573 574
		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 已提交
575

576
		var programAttributes = program.getAttributes();
577

M
Mr.doob 已提交
578 579
		if ( object.hasPositions ) {

580
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );
M
Mr.doob 已提交
581
			_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );
582

583 584
			state.enableAttribute( programAttributes.position );
			_gl.vertexAttribPointer( programAttributes.position, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
585 586 587 588 589

		}

		if ( object.hasNormals ) {

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

592
			if ( ! material.isMeshPhongMaterial &&
593
				! material.isMeshStandardMaterial &&
594
				! material.isMeshNormalMaterial &&
595
				material.shading === FlatShading ) {
M
Mr.doob 已提交
596

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

599
					var array = object.normalArray;
M
Mr.doob 已提交
600

601 602 603
					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 已提交
604

605 606 607
					array[ i + 0 ] = nx;
					array[ i + 1 ] = ny;
					array[ i + 2 ] = nz;
M
Mr.doob 已提交
608

609 610 611
					array[ i + 3 ] = nx;
					array[ i + 4 ] = ny;
					array[ i + 5 ] = nz;
M
Mr.doob 已提交
612

613 614 615
					array[ i + 6 ] = nx;
					array[ i + 7 ] = ny;
					array[ i + 8 ] = nz;
M
Mr.doob 已提交
616 617 618 619 620 621

				}

			}

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

623
			state.enableAttribute( programAttributes.normal );
624

625
			_gl.vertexAttribPointer( programAttributes.normal, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
626 627 628 629 630

		}

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

631
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );
M
Mr.doob 已提交
632
			_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );
633

634
			state.enableAttribute( programAttributes.uv );
635

636
			_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
637 638 639

		}

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

642
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );
M
Mr.doob 已提交
643
			_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );
644

645
			state.enableAttribute( programAttributes.color );
646

647
			_gl.vertexAttribPointer( programAttributes.color, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
648 649 650

		}

651
		state.disableUnusedAttributes();
652

M
Mr.doob 已提交
653 654 655 656 657 658
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );

		object.count = 0;

	};

M
Mr.doob 已提交
659 660 661 662 663 664
	function absNumericalSort( a, b ) {

		return Math.abs( b[ 0 ] ) - Math.abs( a[ 0 ] );

	}

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

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

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

M
Mr.doob 已提交
672
		var updateBuffers = false;
M
Mr.doob 已提交
673 674 675 676 677 678 679 680 681 682 683 684 685 686

		if ( geometryProgram !== _currentGeometryProgram ) {

			_currentGeometryProgram = geometryProgram;
			updateBuffers = true;

		}

		// morph targets

		var morphTargetInfluences = object.morphTargetInfluences;

		if ( morphTargetInfluences !== undefined ) {

M
Mr.doob 已提交
687 688
			// TODO Remove allocations

M
Mr.doob 已提交
689 690 691 692 693 694 695 696 697
			var activeInfluences = [];

			for ( var i = 0, l = morphTargetInfluences.length; i < l; i ++ ) {

				var influence = morphTargetInfluences[ i ];
				activeInfluences.push( [ influence, i ] );

			}

698
			activeInfluences.sort( absNumericalSort );
M
Mr.doob 已提交
699 700 701 702 703 704 705

			if ( activeInfluences.length > 8 ) {

				activeInfluences.length = 8;

			}

706 707
			var morphAttributes = geometry.morphAttributes;

M
Mr.doob 已提交
708 709 710 711 712 713 714
			for ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {

				var influence = activeInfluences[ i ];
				morphInfluences[ i ] = influence[ 0 ];

				if ( influence[ 0 ] !== 0 ) {

715
					var index = influence[ 1 ];
M
Mr.doob 已提交
716

717 718
					if ( material.morphTargets === true && morphAttributes.position ) geometry.addAttribute( 'morphTarget' + i, morphAttributes.position[ index ] );
					if ( material.morphNormals === true && morphAttributes.normal ) geometry.addAttribute( 'morphNormal' + i, morphAttributes.normal[ index ] );
M
Mr.doob 已提交
719 720 721

				} else {

722 723
					if ( material.morphTargets === true ) geometry.removeAttribute( 'morphTarget' + i );
					if ( material.morphNormals === true ) geometry.removeAttribute( 'morphNormal' + i );
M
Mr.doob 已提交
724 725 726 727 728

				}

			}

729 730 731 732 733 734
			for ( var i = activeInfluences.length, il = morphInfluences.length; i < il; i ++ ) {

				morphInfluences[ i ] = 0.0;

			}

M
Mr.doob 已提交
735
			program.getUniforms().setValue( _gl, 'morphTargetInfluences', morphInfluences );
M
Mr.doob 已提交
736 737 738 739 740

			updateBuffers = true;

		}

741 742
		//

743
		var index = geometry.index;
744
		var position = geometry.attributes.position;
745
		var rangeFactor = 1;
746

747 748
		if ( material.wireframe === true ) {

749
			index = geometries.getWireframeAttribute( geometry );
750
			rangeFactor = 2;
751 752 753

		}

M
Mr.doob 已提交
754
		var attribute;
M
Mr.doob 已提交
755
		var renderer = bufferRenderer;
756

757
		if ( index !== null ) {
758

M
Mr.doob 已提交
759
			attribute = attributes.get( index );
760

761
			renderer = indexedBufferRenderer;
M
Mr.doob 已提交
762
			renderer.setIndex( attribute );
763

764
		}
M
Mr.doob 已提交
765

766
		if ( updateBuffers ) {
M
Mr.doob 已提交
767

768
			setupVertexAttributes( material, program, geometry );
M
Mr.doob 已提交
769

770
			if ( index !== null ) {
771

M
Mr.doob 已提交
772
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, attribute.buffer );
773 774 775

			}

776
		}
777

778 779
		//

780
		var dataCount = 0;
781

M
Mr.doob 已提交
782
		if ( index !== null ) {
783

M
Mr.doob 已提交
784
			dataCount = index.count;
785

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

M
Mr.doob 已提交
788
			dataCount = position.count;
789

M
Mr.doob 已提交
790
		}
791

M
Mr.doob 已提交
792 793
		var rangeStart = geometry.drawRange.start * rangeFactor;
		var rangeCount = geometry.drawRange.count * rangeFactor;
794

M
Mr.doob 已提交
795 796
		var groupStart = group !== null ? group.start * rangeFactor : 0;
		var groupCount = group !== null ? group.count * rangeFactor : Infinity;
797

M
Mr.doob 已提交
798 799
		var drawStart = Math.max( rangeStart, groupStart );
		var drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1;
M
Mr.doob 已提交
800 801 802

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

803 804
		if ( drawCount === 0 ) return;

M
Mr.doob 已提交
805
		//
806

807
		if ( object.isMesh ) {
808

809
			if ( material.wireframe === true ) {
810

811
				state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );
812
				renderer.setMode( _gl.LINES );
813

814
			} else {
M
Mr.doob 已提交
815 816

				switch ( object.drawMode ) {
817

R
Rich Harris 已提交
818
					case TrianglesDrawMode:
B
Ben Adams 已提交
819 820 821
						renderer.setMode( _gl.TRIANGLES );
						break;

R
Rich Harris 已提交
822
					case TriangleStripDrawMode:
B
Ben Adams 已提交
823 824 825
						renderer.setMode( _gl.TRIANGLE_STRIP );
						break;

R
Rich Harris 已提交
826
					case TriangleFanDrawMode:
B
Ben Adams 已提交
827 828 829 830
						renderer.setMode( _gl.TRIANGLE_FAN );
						break;

				}
831

832
			}
833

834

835
		} else if ( object.isLine ) {
836

837
			var lineWidth = material.linewidth;
838

839
			if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material
840

841
			state.setLineWidth( lineWidth * getTargetPixelRatio() );
842

843
			if ( object.isLineSegments ) {
844

845
				renderer.setMode( _gl.LINES );
846

847 848 849 850
			} else if ( object.isLineLoop ) {

				renderer.setMode( _gl.LINE_LOOP );

851
			} else {
852

853
				renderer.setMode( _gl.LINE_STRIP );
854 855

			}
M
Mr.doob 已提交
856

857
		} else if ( object.isPoints ) {
858 859

			renderer.setMode( _gl.POINTS );
860 861

		}
862

T
Takahiro 已提交
863
		if ( geometry && geometry.isInstancedBufferGeometry ) {
M
Mr.doob 已提交
864 865 866

			if ( geometry.maxInstancedCount > 0 ) {

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

J
jfranc 已提交
869
			}
870 871 872

		} else {

M
Mr.doob 已提交
873
			renderer.render( drawStart, drawCount );
874

M
Mr.doob 已提交
875 876 877 878
		}

	};

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

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

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

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

M
Mr.doob 已提交
888 889 890
			}

		}
B
Ben Adams 已提交
891

892 893
		if ( startIndex === undefined ) startIndex = 0;

894 895
		state.initAttributes();

896
		var geometryAttributes = geometry.attributes;
897

898
		var programAttributes = program.getAttributes();
899

900
		var materialDefaultAttributeValues = material.defaultAttributeValues;
901

902
		for ( var name in programAttributes ) {
903

904
			var programAttribute = programAttributes[ name ];
M
Mr.doob 已提交
905

M
Mr.doob 已提交
906
			if ( programAttribute >= 0 ) {
M
Mr.doob 已提交
907

908
				var geometryAttribute = geometryAttributes[ name ];
909

M
Mr.doob 已提交
910
				if ( geometryAttribute !== undefined ) {
M
Mr.doob 已提交
911

912
					var normalized = geometryAttribute.normalized;
913
					var size = geometryAttribute.itemSize;
914

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

M
Mr.doob 已提交
917 918 919
					var buffer = attribute.buffer;
					var type = attribute.type;
					var bytesPerElement = attribute.bytesPerElement;
920

A
aardgoose 已提交
921
					if ( geometryAttribute.isInterleavedBufferAttribute ) {
922

M
Mr.doob 已提交
923 924 925 926
						var data = geometryAttribute.data;
						var stride = data.stride;
						var offset = geometryAttribute.offset;

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

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

M
Mr.doob 已提交
931
							if ( geometry.maxInstancedCount === undefined ) {
932

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

M
Mr.doob 已提交
935
							}
B
Ben Adams 已提交
936

M
Mr.doob 已提交
937
						} else {
B
Ben Adams 已提交
938

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

M
Mr.doob 已提交
941
						}
B
Ben Adams 已提交
942

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

M
Mr.doob 已提交
946
					} else {
B
Ben Adams 已提交
947

A
aardgoose 已提交
948
						if ( geometryAttribute.isInstancedBufferAttribute ) {
B
Ben Adams 已提交
949

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

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

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

M
Mr.doob 已提交
956
							}
B
Ben Adams 已提交
957

M
Mr.doob 已提交
958 959 960 961
						} else {

							state.enableAttribute( programAttribute );

M
Mr.doob 已提交
962
						}
B
Ben Adams 已提交
963

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

B
Ben Adams 已提交
967
					}
M
Mr.doob 已提交
968

969 970
				} else if ( materialDefaultAttributeValues !== undefined ) {

T
tschw 已提交
971
					var value = materialDefaultAttributeValues[ name ];
972

973
					if ( value !== undefined ) {
M
Mr.doob 已提交
974

975
						switch ( value.length ) {
M
Mr.doob 已提交
976

977 978 979
							case 2:
								_gl.vertexAttrib2fv( programAttribute, value );
								break;
M
Mr.doob 已提交
980

981 982 983
							case 3:
								_gl.vertexAttrib3fv( programAttribute, value );
								break;
M
Mr.doob 已提交
984

985 986 987
							case 4:
								_gl.vertexAttrib4fv( programAttribute, value );
								break;
988

989 990
							default:
								_gl.vertexAttrib1fv( programAttribute, value );
991 992

						}
M
Mr.doob 已提交
993 994 995 996 997 998 999 1000

					}

				}

			}

		}
1001

1002
		state.disableUnusedAttributes();
1003

M
Mr.doob 已提交
1004 1005
	}

M
Mr.doob 已提交
1006
	// Compile
M
Mr.doob 已提交
1007

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

M
Mr.doob 已提交
1010
		lights = [];
1011

M
Mr.doob 已提交
1012
		scene.traverse( function ( object ) {
G
gero3 已提交
1013 1014

			if ( object.isLight ) {
M
Mr.doob 已提交
1015 1016 1017

				lights.push( object );

G
gero3 已提交
1018
			}
M
Mr.doob 已提交
1019 1020 1021 1022 1023 1024 1025 1026 1027

		} );

		setupLights( lights, camera );

		scene.traverse( function ( object ) {

			if ( object.material ) {

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

G
gero3 已提交
1030
					for ( var i = 0; i < object.material.length; i ++ ) {
M
Mr.doob 已提交
1031 1032 1033

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

G
gero3 已提交
1034
					}
M
Mr.doob 已提交
1035

G
gero3 已提交
1036
				} else {
M
Mr.doob 已提交
1037 1038 1039

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

G
gero3 已提交
1040
				}
M
Mr.doob 已提交
1041

G
gero3 已提交
1042
			}
M
Mr.doob 已提交
1043 1044

		} );
G
gero3 已提交
1045 1046

	};
1047

M
Mr.doob 已提交
1048 1049
	// Rendering

1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063
	this.animate = function ( callback ) {

		function onFrame() {

			callback();

			( vr.getDevice() || window ).requestAnimationFrame( onFrame );

		}

		( vr.getDevice() || window ).requestAnimationFrame( onFrame );

	};

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

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

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

		}

		// reset caching for this frame

1075
		_currentGeometryProgram = '';
1076
		_currentMaterialId = - 1;
1077
		_currentCamera = null;
M
Mr.doob 已提交
1078 1079 1080

		// update scene graph

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

		// update camera matrices and frustum

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

1087 1088 1089 1090 1091 1092
		if ( vr.enabled ) {

			camera = vr.getCamera( camera );

		}

M
Mr.doob 已提交
1093 1094 1095
		_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
		_frustum.setFromMatrix( _projScreenMatrix );

M
Mr.doob 已提交
1096
		lights.length = 0;
M
Mr.doob 已提交
1097 1098 1099
		sprites.length = 0;
		lensFlares.length = 0;

T
tschw 已提交
1100
		_localClippingEnabled = this.localClippingEnabled;
M
Mr.doob 已提交
1101
		_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );
T
tschw 已提交
1102

1103 1104 1105
		currentRenderList = renderLists.get( scene, camera );
		currentRenderList.init();

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

1108
		currentRenderList.finish();
1109

M
Mr.doob 已提交
1110
		if ( _this.sortObjects === true ) {
1111

1112
			currentRenderList.sort();
M
Mr.doob 已提交
1113

1114 1115
		}

M
Mr.doob 已提交
1116
		//
M
Mr.doob 已提交
1117

T
tschw 已提交
1118
		if ( _clippingEnabled ) _clipping.beginShadows();
T
tschw 已提交
1119

1120 1121
		setupShadows( lights );

M
Mr.doob 已提交
1122
		shadowMap.render( scene, camera );
M
Mr.doob 已提交
1123

1124 1125
		setupLights( lights, camera );

T
tschw 已提交
1126
		if ( _clippingEnabled ) _clipping.endShadows();
T
tschw 已提交
1127

M
Mr.doob 已提交
1128 1129
		//

M
Mr.doob 已提交
1130
		_infoRender.frame ++;
1131 1132 1133 1134
		_infoRender.calls = 0;
		_infoRender.vertices = 0;
		_infoRender.faces = 0;
		_infoRender.points = 0;
M
Mr.doob 已提交
1135

1136 1137 1138 1139 1140 1141
		if ( renderTarget === undefined ) {

			renderTarget = null;

		}

M
Mr.doob 已提交
1142 1143
		this.setRenderTarget( renderTarget );

M
Mr.doob 已提交
1144 1145
		//

1146
		background.render( scene, camera, forceClear );
M
Mr.doob 已提交
1147

1148
		// render scene
M
Mr.doob 已提交
1149

1150 1151
		var opaqueObjects = currentRenderList.opaque;
		var transparentObjects = currentRenderList.transparent;
M
Mr.doob 已提交
1152

1153
		if ( scene.overrideMaterial ) {
M
Mr.doob 已提交
1154

1155
			var overrideMaterial = scene.overrideMaterial;
1156

1157 1158
			if ( opaqueObjects.length ) renderObjects( opaqueObjects, scene, camera, overrideMaterial );
			if ( transparentObjects.length ) renderObjects( transparentObjects, scene, camera, overrideMaterial );
M
Mr.doob 已提交
1159

1160
		} else {
M
Mr.doob 已提交
1161

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

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

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

1168
			if ( transparentObjects.length ) renderObjects( transparentObjects, scene, camera );
M
Mr.doob 已提交
1169 1170 1171 1172 1173

		}

		// custom render plugins (post pass)

M
Mr.doob 已提交
1174
		spritePlugin.render( scene, camera );
1175
		lensFlarePlugin.render( scene, camera, _currentViewport );
M
Mr.doob 已提交
1176 1177 1178

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

M
Mr.doob 已提交
1179 1180
		if ( renderTarget ) {

1181
			textures.updateRenderTargetMipmap( renderTarget );
M
Mr.doob 已提交
1182 1183 1184

		}

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

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

M
Mr.doob 已提交
1191
		if ( camera.isArrayCamera ) {
1192 1193 1194 1195 1196

			_this.setScissorTest( false );

		}

M
Mr.doob 已提交
1197 1198 1199 1200 1201
		if ( vr.enabled ) {

			vr.submitFrame();

		}
M
Mr.doob 已提交
1202

M
Mr.doob 已提交
1203 1204 1205
		// _gl.finish();

	};
M
Mr.doob 已提交
1206

1207
	/*
M
Mr.doob 已提交
1208 1209
	// TODO Duplicated code (Frustum)

1210 1211
	var _sphere = new Sphere();

T
tschw 已提交
1212 1213 1214 1215 1216 1217 1218
	function isObjectViewable( object ) {

		var geometry = object.geometry;

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

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

		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 已提交
1237 1238

		if ( ! _frustum.intersectsSphere( sphere ) ) return false;
T
tschw 已提交
1239 1240 1241 1242

		var numPlanes = _clipping.numPlanes;

		if ( numPlanes === 0 ) return true;
T
tschw 已提交
1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254

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

		return true;

	}
1260
	*/
T
tschw 已提交
1261

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

M
Mr.doob 已提交
1264
		if ( ! object.visible ) return;
M
Mr.doob 已提交
1265

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

1268
		if ( visible ) {
1269

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

1272
				lights.push( object );
M
Mr.doob 已提交
1273

1274
			} else if ( object.isSprite ) {
M
Mr.doob 已提交
1275

1276
				if ( ! object.frustumCulled || _frustum.intersectsSprite( object ) ) {
1277

1278
					sprites.push( object );
M
Mr.doob 已提交
1279

1280
				}
M
Mr.doob 已提交
1281

1282
			} else if ( object.isLensFlare ) {
M
Mr.doob 已提交
1283

1284
				lensFlares.push( object );
M
Mr.doob 已提交
1285

1286
			} else if ( object.isImmediateRenderObject ) {
M
Mr.doob 已提交
1287

1288
				if ( sortObjects ) {
M
Mr.doob 已提交
1289

1290 1291
					_vector3.setFromMatrixPosition( object.matrixWorld )
						.applyMatrix4( _projScreenMatrix );
M
Mr.doob 已提交
1292

1293
				}
M
Mr.doob 已提交
1294

1295
				currentRenderList.push( object, null, object.material, _vector3.z, null );
1296

1297
			} else if ( object.isMesh || object.isLine || object.isPoints ) {
1298

1299
				if ( object.isSkinnedMesh ) {
1300

1301
					object.skeleton.update();
1302

1303
				}
1304

1305
				if ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) {
1306

1307 1308 1309 1310 1311 1312
					if ( sortObjects ) {

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

					}
1313

1314 1315
					var geometry = objects.update( object );
					var material = object.material;
1316

1317
					if ( Array.isArray( material ) ) {
1318

1319
						var groups = geometry.groups;
1320

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

1323 1324
							var group = groups[ i ];
							var groupMaterial = material[ group.materialIndex ];
1325

1326
							if ( groupMaterial && groupMaterial.visible ) {
1327

1328 1329 1330
								currentRenderList.push( object, geometry, groupMaterial, _vector3.z, group );

							}
M
Mr.doob 已提交
1331

M
Mr.doob 已提交
1332
						}
M
Mr.doob 已提交
1333

1334
					} else if ( material.visible ) {
1335

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

1338
					}
M
Mr.doob 已提交
1339

1340
				}
M
Mr.doob 已提交
1341

1342
			}
M
Mr.doob 已提交
1343

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

M
Mr.doob 已提交
1346
		var children = object.children;
M
Mr.doob 已提交
1347

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

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

1352
		}
1353

1354
	}
M
Mr.doob 已提交
1355

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

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

1360
			var renderItem = renderList[ i ];
1361

1362 1363 1364 1365
			var object = renderItem.object;
			var geometry = renderItem.geometry;
			var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;
			var group = renderItem.group;
1366

1367
			if ( camera.isArrayCamera ) {
M
Mr.doob 已提交
1368

1369 1370
				_currentArrayCamera = camera;

1371
				var cameras = camera.cameras;
1372

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

1375 1376
					var camera2 = cameras[ j ];
					var bounds = camera2.bounds;
M
Mr.doob 已提交
1377

1378 1379 1380 1381
					var x = bounds.x * _width;
					var y = bounds.y * _height;
					var width = bounds.z * _width;
					var height = bounds.w * _height;
1382

1383 1384 1385
					_this.setViewport( x, y, width, height );
					_this.setScissor( x, y, width, height );
					_this.setScissorTest( true );
M
Mr.doob 已提交
1386

1387
					renderObject( object, scene, camera2, geometry, material, group );
M
Mr.doob 已提交
1388

1389
				}
1390

1391
			} else {
M
Mr.doob 已提交
1392

1393 1394
				_currentArrayCamera = null;

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

1397
			}
M
Mr.doob 已提交
1398

1399
		}
M
Mr.doob 已提交
1400

1401
	}
G
gero3 已提交
1402

M
Mr.doob 已提交
1403 1404 1405 1406 1407
	function renderObject( object, scene, camera, geometry, material, group ) {

		object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
		object.normalMatrix.getNormalMatrix( object.modelViewMatrix );

M
Mr.doob 已提交
1408 1409
		object.onBeforeRender( _this, scene, camera, geometry, material, group );

M
Mr.doob 已提交
1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425
		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 已提交
1426 1427
		object.onAfterRender( _this, scene, camera, geometry, material, group );

M
Mr.doob 已提交
1428 1429
	}

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

1432
		var materialProperties = properties.get( material );
G
gero3 已提交
1433

T
tschw 已提交
1434
		var parameters = programCache.getParameters(
1435
			material, _lights, fog, _clipping.numPlanes, _clipping.numIntersection, object );
T
tschw 已提交
1436

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

1439
		var program = materialProperties.program;
T
tschw 已提交
1440
		var programChange = true;
1441

1442
		if ( program === undefined ) {
B
Ben Adams 已提交
1443

M
Mr.doob 已提交
1444 1445
			// new material
			material.addEventListener( 'dispose', onMaterialDispose );
B
Ben Adams 已提交
1446

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

M
Mr.doob 已提交
1449
			// changed glsl or parameters
1450
			releaseMaterialProgramReference( material );
B
Ben Adams 已提交
1451

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

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

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

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

		}

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

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

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

1470
				materialProperties.shader = {
1471
					name: material.type,
1472
					uniforms: UniformsUtils.clone( shader.uniforms ),
1473 1474 1475
					vertexShader: shader.vertexShader,
					fragmentShader: shader.fragmentShader
				};
B
Ben Adams 已提交
1476

1477
			} else {
B
Ben Adams 已提交
1478

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

1486
			}
G
gero3 已提交
1487

1488
			material.onBeforeCompile( materialProperties.shader );
G
gero3 已提交
1489

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

1492 1493
			materialProperties.program = program;
			material.program = program;
1494 1495 1496

		}

1497
		var programAttributes = program.getAttributes();
M
Mr.doob 已提交
1498 1499 1500 1501 1502

		if ( material.morphTargets ) {

			material.numSupportedMorphTargets = 0;

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

1505
				if ( programAttributes[ 'morphTarget' + i ] >= 0 ) {
M
Mr.doob 已提交
1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518

					material.numSupportedMorphTargets ++;

				}

			}

		}

		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

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

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

					material.numSupportedMorphNormals ++;

				}

			}

		}

1531
		var uniforms = materialProperties.shader.uniforms;
T
tschw 已提交
1532

1533
		if ( ! material.isShaderMaterial &&
1534 1535
			! material.isRawShaderMaterial ||
			material.clipping === true ) {
T
tschw 已提交
1536

T
tschw 已提交
1537
			materialProperties.numClippingPlanes = _clipping.numPlanes;
1538
			materialProperties.numIntersection = _clipping.numIntersection;
T
tschw 已提交
1539
			uniforms.clippingPlanes = _clipping.uniform;
T
tschw 已提交
1540 1541 1542

		}

1543
		materialProperties.fog = fog;
1544

1545
		// store the light setup it was created for
1546

1547
		materialProperties.lightsHash = _lights.hash;
1548

M
Mr.doob 已提交
1549
		if ( material.lights ) {
1550 1551 1552 1553 1554 1555

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

			uniforms.ambientLightColor.value = _lights.ambient;
			uniforms.directionalLights.value = _lights.directional;
			uniforms.spotLights.value = _lights.spot;
1556
			uniforms.rectAreaLights.value = _lights.rectArea;
M
Mr.doob 已提交
1557
			uniforms.pointLights.value = _lights.point;
1558 1559
			uniforms.hemisphereLights.value = _lights.hemi;

1560 1561 1562 1563 1564 1565
			uniforms.directionalShadowMap.value = _lights.directionalShadowMap;
			uniforms.directionalShadowMatrix.value = _lights.directionalShadowMatrix;
			uniforms.spotShadowMap.value = _lights.spotShadowMap;
			uniforms.spotShadowMatrix.value = _lights.spotShadowMatrix;
			uniforms.pointShadowMap.value = _lights.pointShadowMap;
			uniforms.pointShadowMatrix.value = _lights.pointShadowMatrix;
1566
			// TODO (abelnation): add area lights shadow info to uniforms
1567

1568 1569
		}

T
tschw 已提交
1570 1571
		var progUniforms = materialProperties.program.getUniforms(),
			uniformsList =
1572
				WebGLUniforms.seqWithValue( progUniforms.seq, uniforms );
A
arose 已提交
1573

T
tschw 已提交
1574
		materialProperties.uniformsList = uniformsList;
A
arose 已提交
1575

M
Mr.doob 已提交
1576
	}
M
Mr.doob 已提交
1577

1578
	function setProgram( camera, fog, material, object ) {
M
Mr.doob 已提交
1579 1580 1581

		_usedTextureUnits = 0;

1582
		var materialProperties = properties.get( material );
1583

T
tschw 已提交
1584 1585 1586 1587 1588
		if ( _clippingEnabled ) {

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

				var useCache =
1589 1590
					camera === _currentCamera &&
					material.id === _currentMaterialId;
T
tschw 已提交
1591 1592 1593 1594

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

			}

		}

1603
		if ( material.needsUpdate === false ) {
1604

1605
			if ( materialProperties.program === undefined ) {
1606

1607
				material.needsUpdate = true;
1608

1609
			} else if ( material.fog && materialProperties.fog !== fog ) {
1610

M
Mr.doob 已提交
1611
				material.needsUpdate = true;
1612

1613
			} else if ( material.lights && materialProperties.lightsHash !== _lights.hash ) {
1614

1615
				material.needsUpdate = true;
1616

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

				material.needsUpdate = true;

1623
			}
1624 1625 1626 1627

		}

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

1629
			initMaterial( material, fog, object );
M
Mr.doob 已提交
1630 1631 1632 1633
			material.needsUpdate = false;

		}

1634
		var refreshProgram = false;
M
Mr.doob 已提交
1635
		var refreshMaterial = false;
1636
		var refreshLights = false;
M
Mr.doob 已提交
1637

1638
		var program = materialProperties.program,
1639
			p_uniforms = program.getUniforms(),
1640
			m_uniforms = materialProperties.shader.uniforms;
M
Mr.doob 已提交
1641

1642
		if ( program.id !== _currentProgram ) {
M
Mr.doob 已提交
1643

1644 1645
			_gl.useProgram( program.program );
			_currentProgram = program.id;
M
Mr.doob 已提交
1646

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

		}

		if ( material.id !== _currentMaterialId ) {

			_currentMaterialId = material.id;
1656

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

		}

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

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

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

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

			}

1672
			// Avoid unneeded uniform updates per ArrayCamera's sub-camera
1673

1674
			if ( _currentCamera !== ( _currentArrayCamera || camera ) ) {
1675

1676
				_currentCamera = ( _currentArrayCamera || camera );
1677 1678 1679 1680 1681 1682

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

			}
M
Mr.doob 已提交
1686

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

1690
			if ( material.isShaderMaterial ||
1691 1692 1693
				material.isMeshPhongMaterial ||
				material.isMeshStandardMaterial ||
				material.envMap ) {
1694

T
tschw 已提交
1695 1696 1697
				var uCamPos = p_uniforms.map.cameraPosition;

				if ( uCamPos !== undefined ) {
1698

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

				}

			}

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

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

			}

M
Mr.doob 已提交
1717 1718 1719 1720 1721 1722
		}

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

1723
		if ( material.skinning ) {
M
Mr.doob 已提交
1724

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

T
tschw 已提交
1728
			var skeleton = object.skeleton;
1729

T
tschw 已提交
1730
			if ( skeleton ) {
1731

1732 1733
				var bones = skeleton.bones;

1734
				if ( capabilities.floatVertexTextures ) {
M
Mr.doob 已提交
1735

1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760
					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 已提交
1761 1762
					p_uniforms.setValue( _gl, 'boneTexture', skeleton.boneTexture );
					p_uniforms.setValue( _gl, 'boneTextureSize', skeleton.boneTextureSize );
M
Mr.doob 已提交
1763

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

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

				}

			}

		}

		if ( refreshMaterial ) {

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

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

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

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

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

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

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

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

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

			}

1802
			if ( material.isMeshBasicMaterial ||
1803 1804 1805
				material.isMeshLambertMaterial ||
				material.isMeshPhongMaterial ||
				material.isMeshStandardMaterial ||
1806
				material.isMeshNormalMaterial ||
1807
				material.isMeshDepthMaterial ) {
M
Mr.doob 已提交
1808 1809 1810 1811 1812 1813 1814

				refreshUniformsCommon( m_uniforms, material );

			}

			// refresh single material specific uniforms

1815
			if ( material.isLineBasicMaterial ) {
M
Mr.doob 已提交
1816 1817 1818

				refreshUniformsLine( m_uniforms, material );

1819
			} else if ( material.isLineDashedMaterial ) {
M
Mr.doob 已提交
1820 1821 1822 1823

				refreshUniformsLine( m_uniforms, material );
				refreshUniformsDash( m_uniforms, material );

1824
			} else if ( material.isPointsMaterial ) {
M
Mr.doob 已提交
1825

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

1828
			} else if ( material.isMeshLambertMaterial ) {
1829 1830 1831

				refreshUniformsLambert( m_uniforms, material );

T
Takahiro 已提交
1832 1833 1834 1835
			} else if ( material.isMeshToonMaterial ) {

				refreshUniformsToon( m_uniforms, material );

1836 1837 1838 1839
			} else if ( material.isMeshPhongMaterial ) {

				refreshUniformsPhong( m_uniforms, material );

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

				refreshUniformsPhysical( m_uniforms, material );

1844
			} else if ( material.isMeshStandardMaterial ) {
W
WestLangley 已提交
1845

1846
				refreshUniformsStandard( m_uniforms, material );
W
WestLangley 已提交
1847

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

1850 1851 1852 1853 1854 1855 1856 1857
				if ( material.displacementMap ) {

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

				}

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

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

			}

M
Mr.doob 已提交
1864 1865 1866 1867 1868 1869
			// 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 已提交
1870
			WebGLUniforms.upload(
1871
				_gl, materialProperties.uniformsList, m_uniforms, _this );
A
arose 已提交
1872 1873 1874

		}

M
Mr.doob 已提交
1875

T
tschw 已提交
1876
		// common matrices
M
Mr.doob 已提交
1877

M
Mr.doob 已提交
1878 1879
		p_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix );
		p_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix );
T
tschw 已提交
1880
		p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );
A
arose 已提交
1881

T
tschw 已提交
1882
		return program;
A
arose 已提交
1883 1884 1885

	}

M
Mr.doob 已提交
1886 1887
	// Uniforms (refresh uniforms objects)

M
Mr.doob 已提交
1888
	function refreshUniformsCommon( uniforms, material ) {
M
Mr.doob 已提交
1889 1890 1891

		uniforms.opacity.value = material.opacity;

1892
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
1893

1894
		if ( material.emissive ) {
M
Mr.doob 已提交
1895

1896
			uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );
M
Mr.doob 已提交
1897 1898 1899

		}

1900 1901 1902
		uniforms.map.value = material.map;
		uniforms.specularMap.value = material.specularMap;
		uniforms.alphaMap.value = material.alphaMap;
M
Mr.doob 已提交
1903

1904 1905 1906 1907 1908 1909 1910
		if ( material.lightMap ) {

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

		}

1911
		if ( material.aoMap ) {
1912

1913 1914
			uniforms.aoMap.value = material.aoMap;
			uniforms.aoMapIntensity.value = material.aoMapIntensity;
1915 1916 1917

		}

M
Mr.doob 已提交
1918
		// uv repeat and offset setting priorities
M
Mr.doob 已提交
1919 1920 1921 1922 1923
		// 1. color map
		// 2. specular map
		// 3. normal map
		// 4. bump map
		// 5. alpha map
1924
		// 6. emissive map
M
Mr.doob 已提交
1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935

		var uvScaleMap;

		if ( material.map ) {

			uvScaleMap = material.map;

		} else if ( material.specularMap ) {

			uvScaleMap = material.specularMap;

1936 1937 1938 1939
		} else if ( material.displacementMap ) {

			uvScaleMap = material.displacementMap;

M
Mr.doob 已提交
1940 1941 1942 1943 1944 1945 1946 1947
		} else if ( material.normalMap ) {

			uvScaleMap = material.normalMap;

		} else if ( material.bumpMap ) {

			uvScaleMap = material.bumpMap;

1948 1949 1950 1951 1952 1953 1954 1955
		} else if ( material.roughnessMap ) {

			uvScaleMap = material.roughnessMap;

		} else if ( material.metalnessMap ) {

			uvScaleMap = material.metalnessMap;

1956 1957 1958 1959
		} else if ( material.alphaMap ) {

			uvScaleMap = material.alphaMap;

1960 1961 1962 1963
		} else if ( material.emissiveMap ) {

			uvScaleMap = material.emissiveMap;

M
Mr.doob 已提交
1964 1965 1966 1967
		}

		if ( uvScaleMap !== undefined ) {

1968
			// backwards compatibility
1969
			if ( uvScaleMap.isWebGLRenderTarget ) {
M
Mr.doob 已提交
1970 1971 1972 1973 1974

				uvScaleMap = uvScaleMap.texture;

			}

M
Mr.doob 已提交
1975 1976 1977 1978 1979 1980 1981 1982
			var offset = uvScaleMap.offset;
			var repeat = uvScaleMap.repeat;

			uniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );

		}

		uniforms.envMap.value = material.envMap;
1983 1984 1985 1986 1987

		// 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
T
Takahiro 已提交
1988
		uniforms.flipEnvMap.value = ( ! ( material.envMap && material.envMap.isCubeTexture ) ) ? 1 : - 1;
M
Mr.doob 已提交
1989

1990
		uniforms.reflectivity.value = material.reflectivity;
M
Mr.doob 已提交
1991 1992
		uniforms.refractionRatio.value = material.refractionRatio;

M
Mr.doob 已提交
1993
	}
M
Mr.doob 已提交
1994

M
Mr.doob 已提交
1995
	function refreshUniformsLine( uniforms, material ) {
M
Mr.doob 已提交
1996 1997 1998 1999

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

M
Mr.doob 已提交
2000
	}
M
Mr.doob 已提交
2001

M
Mr.doob 已提交
2002
	function refreshUniformsDash( uniforms, material ) {
M
Mr.doob 已提交
2003 2004 2005 2006 2007

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

M
Mr.doob 已提交
2008
	}
M
Mr.doob 已提交
2009

M
Mr.doob 已提交
2010
	function refreshUniformsPoints( uniforms, material ) {
M
Mr.doob 已提交
2011

2012
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
2013
		uniforms.opacity.value = material.opacity;
2014
		uniforms.size.value = material.size * _pixelRatio;
2015
		uniforms.scale.value = _height * 0.5;
M
Mr.doob 已提交
2016 2017 2018

		uniforms.map.value = material.map;

2019 2020 2021 2022 2023 2024 2025 2026 2027
		if ( material.map !== null ) {

			var offset = material.map.offset;
			var repeat = material.map.repeat;

			uniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );

		}

M
Mr.doob 已提交
2028
	}
M
Mr.doob 已提交
2029

M
Mr.doob 已提交
2030
	function refreshUniformsFog( uniforms, fog ) {
M
Mr.doob 已提交
2031 2032 2033

		uniforms.fogColor.value = fog.color;

2034
		if ( fog.isFog ) {
M
Mr.doob 已提交
2035 2036 2037 2038

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

2039
		} else if ( fog.isFogExp2 ) {
M
Mr.doob 已提交
2040 2041 2042 2043 2044

			uniforms.fogDensity.value = fog.density;

		}

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

M
Mr.doob 已提交
2047
	function refreshUniformsLambert( uniforms, material ) {
2048 2049 2050 2051 2052 2053 2054 2055 2056

		if ( material.emissiveMap ) {

			uniforms.emissiveMap.value = material.emissiveMap;

		}

	}

M
Mr.doob 已提交
2057
	function refreshUniformsPhong( uniforms, material ) {
M
Mr.doob 已提交
2058

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

2062
		if ( material.emissiveMap ) {
2063

2064
			uniforms.emissiveMap.value = material.emissiveMap;
2065

2066
		}
M
Mr.doob 已提交
2067

2068 2069 2070 2071
		if ( material.bumpMap ) {

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

2073
		}
M
Mr.doob 已提交
2074

2075 2076 2077 2078 2079 2080
		if ( material.normalMap ) {

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

		}
M
Mr.doob 已提交
2081

2082 2083 2084 2085 2086
		if ( material.displacementMap ) {

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

2088
		}
2089

T
Takahiro 已提交
2090 2091 2092 2093 2094 2095
	}

	function refreshUniformsToon( uniforms, material ) {

		refreshUniformsPhong( uniforms, material );

T
Takahiro 已提交
2096
		if ( material.gradientMap ) {
T
Takahiro 已提交
2097

T
Takahiro 已提交
2098
			uniforms.gradientMap.value = material.gradientMap;
T
Takahiro 已提交
2099 2100 2101

		}

2102 2103
	}

M
Mr.doob 已提交
2104
	function refreshUniformsStandard( uniforms, material ) {
W
WestLangley 已提交
2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 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

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

2160 2161 2162
		uniforms.clearCoat.value = material.clearCoat;
		uniforms.clearCoatRoughness.value = material.clearCoatRoughness;

W
WestLangley 已提交
2163 2164 2165 2166
		refreshUniformsStandard( uniforms, material );

	}

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

		}

	}

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

M
Mr.doob 已提交
2195
	function markUniformsLightsNeedsUpdate( uniforms, value ) {
2196

M
Mr.doob 已提交
2197
		uniforms.ambientLightColor.needsUpdate = value;
2198

B
Ben Houston 已提交
2199 2200 2201
		uniforms.directionalLights.needsUpdate = value;
		uniforms.pointLights.needsUpdate = value;
		uniforms.spotLights.needsUpdate = value;
2202
		uniforms.rectAreaLights.needsUpdate = value;
B
Ben Houston 已提交
2203
		uniforms.hemisphereLights.needsUpdate = value;
2204

M
Mr.doob 已提交
2205
	}
2206

T
tschw 已提交
2207
	// Lighting
M
Mr.doob 已提交
2208

M
Mr.doob 已提交
2209
	function setupShadows( lights ) {
2210 2211 2212 2213 2214 2215 2216 2217 2218

		var lightShadowsLength = 0;

		for ( var i = 0, l = lights.length; i < l; i ++ ) {

			var light = lights[ i ];

			if ( light.castShadow ) {

M
Mr.doob 已提交
2219 2220
				_lights.shadows[ lightShadowsLength ] = light;
				lightShadowsLength ++;
2221 2222 2223 2224 2225 2226 2227 2228 2229

			}

		}

		_lights.shadows.length = lightShadowsLength;

	}

M
Mr.doob 已提交
2230
	function setupLights( lights, camera ) {
M
Mr.doob 已提交
2231

M
Mr.doob 已提交
2232
		var l, ll, light, shadow,
2233 2234 2235 2236 2237
			r = 0, g = 0, b = 0,
			color,
			intensity,
			distance,
			shadowMap,
M
Mr.doob 已提交
2238

2239
			viewMatrix = camera.matrixWorldInverse,
M
Mr.doob 已提交
2240

M
Mr.doob 已提交
2241 2242 2243 2244 2245
			directionalLength = 0,
			pointLength = 0,
			spotLength = 0,
			rectAreaLength = 0,
			hemiLength = 0;
M
Mr.doob 已提交
2246 2247 2248 2249 2250 2251 2252 2253 2254

		for ( l = 0, ll = lights.length; l < ll; l ++ ) {

			light = lights[ l ];

			color = light.color;
			intensity = light.intensity;
			distance = light.distance;

2255
			shadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null;
2256

2257
			if ( light.isAmbientLight ) {
M
Mr.doob 已提交
2258

2259 2260 2261
				r += color.r * intensity;
				g += color.g * intensity;
				b += color.b * intensity;
M
Mr.doob 已提交
2262

2263
			} else if ( light.isDirectionalLight ) {
M
Mr.doob 已提交
2264

M
Mr.doob 已提交
2265
				var uniforms = lightCache.get( light );
M
Mr.doob 已提交
2266

2267
				uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
M
Mr.doob 已提交
2268
				uniforms.direction.setFromMatrixPosition( light.matrixWorld );
2269
				_vector3.setFromMatrixPosition( light.target.matrixWorld );
M
Mr.doob 已提交
2270 2271 2272
				uniforms.direction.sub( _vector3 );
				uniforms.direction.transformDirection( viewMatrix );

2273
				uniforms.shadow = light.castShadow;
M
Mr.doob 已提交
2274

2275
				if ( light.castShadow ) {
M
Mr.doob 已提交
2276

M
Mr.doob 已提交
2277 2278 2279 2280 2281
					shadow = light.shadow;

					uniforms.shadowBias = shadow.bias;
					uniforms.shadowRadius = shadow.radius;
					uniforms.shadowMapSize = shadow.mapSize;
2282

2283 2284
				}

2285
				_lights.directionalShadowMap[ directionalLength ] = shadowMap;
2286
				_lights.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;
M
Mr.doob 已提交
2287 2288 2289
				_lights.directional[ directionalLength ] = uniforms;

				directionalLength ++;
M
Mr.doob 已提交
2290

2291
			} else if ( light.isSpotLight ) {
M
Mr.doob 已提交
2292

M
Mr.doob 已提交
2293
				var uniforms = lightCache.get( light );
M
Mr.doob 已提交
2294 2295 2296

				uniforms.position.setFromMatrixPosition( light.matrixWorld );
				uniforms.position.applyMatrix4( viewMatrix );
M
Mr.doob 已提交
2297

M
Mr.doob 已提交
2298 2299 2300 2301 2302 2303 2304 2305
				uniforms.color.copy( color ).multiplyScalar( intensity );
				uniforms.distance = distance;

				uniforms.direction.setFromMatrixPosition( light.matrixWorld );
				_vector3.setFromMatrixPosition( light.target.matrixWorld );
				uniforms.direction.sub( _vector3 );
				uniforms.direction.transformDirection( viewMatrix );

2306 2307
				uniforms.coneCos = Math.cos( light.angle );
				uniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );
M
Mr.doob 已提交
2308
				uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;
M
Mr.doob 已提交
2309

2310
				uniforms.shadow = light.castShadow;
M
Mr.doob 已提交
2311

2312 2313
				if ( light.castShadow ) {

M
Mr.doob 已提交
2314 2315 2316 2317 2318
					shadow = light.shadow;

					uniforms.shadowBias = shadow.bias;
					uniforms.shadowRadius = shadow.radius;
					uniforms.shadowMapSize = shadow.mapSize;
2319

2320 2321
				}

2322
				_lights.spotShadowMap[ spotLength ] = shadowMap;
2323
				_lights.spotShadowMatrix[ spotLength ] = light.shadow.matrix;
M
Mr.doob 已提交
2324 2325 2326
				_lights.spot[ spotLength ] = uniforms;

				spotLength ++;
2327

2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357
			} else if ( light.isRectAreaLight ) {

				var uniforms = lightCache.get( light );

				// (a) intensity controls irradiance of entire light
				uniforms.color
					.copy( color )
					.multiplyScalar( intensity / ( light.width * light.height ) );

				// (b) intensity controls the radiance per light area
				// uniforms.color.copy( color ).multiplyScalar( intensity );

				uniforms.position.setFromMatrixPosition( light.matrixWorld );
				uniforms.position.applyMatrix4( viewMatrix );

				// extract local rotation of light to derive width/height half vectors
				_matrix42.identity();
				_matrix4.copy( light.matrixWorld );
				_matrix4.premultiply( viewMatrix );
				_matrix42.extractRotation( _matrix4 );

				uniforms.halfWidth.set( light.width * 0.5,                0.0, 0.0 );
				uniforms.halfHeight.set(              0.0, light.height * 0.5, 0.0 );

				uniforms.halfWidth.applyMatrix4( _matrix42 );
				uniforms.halfHeight.applyMatrix4( _matrix42 );

				// TODO (abelnation): RectAreaLight distance?
				// uniforms.distance = distance;

M
Mr.doob 已提交
2358 2359 2360
				_lights.rectArea[ rectAreaLength ] = uniforms;

				rectAreaLength ++;
2361

2362
			} else if ( light.isPointLight ) {
M
Mr.doob 已提交
2363

M
Mr.doob 已提交
2364
				var uniforms = lightCache.get( light );
M
Mr.doob 已提交
2365

M
Mr.doob 已提交
2366 2367
				uniforms.position.setFromMatrixPosition( light.matrixWorld );
				uniforms.position.applyMatrix4( viewMatrix );
M
Mr.doob 已提交
2368

M
Mr.doob 已提交
2369 2370
				uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
				uniforms.distance = light.distance;
M
Mr.doob 已提交
2371 2372
				uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;

2373
				uniforms.shadow = light.castShadow;
2374

M
Mr.doob 已提交
2375
				if ( light.castShadow ) {
2376

M
Mr.doob 已提交
2377 2378 2379 2380 2381
					shadow = light.shadow;

					uniforms.shadowBias = shadow.bias;
					uniforms.shadowRadius = shadow.radius;
					uniforms.shadowMapSize = shadow.mapSize;
2382 2383

				}
2384

2385
				_lights.pointShadowMap[ pointLength ] = shadowMap;
J
jaxry 已提交
2386
				_lights.pointShadowMatrix[ pointLength ] = light.shadow.matrix;
M
Mr.doob 已提交
2387 2388 2389
				_lights.point[ pointLength ] = uniforms;

				pointLength ++;
2390

2391
			} else if ( light.isHemisphereLight ) {
M
Mr.doob 已提交
2392

M
Mr.doob 已提交
2393
				var uniforms = lightCache.get( light );
M
Mr.doob 已提交
2394 2395 2396 2397

				uniforms.direction.setFromMatrixPosition( light.matrixWorld );
				uniforms.direction.transformDirection( viewMatrix );
				uniforms.direction.normalize();
M
Mr.doob 已提交
2398

M
Mr.doob 已提交
2399 2400
				uniforms.skyColor.copy( light.color ).multiplyScalar( intensity );
				uniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );
M
Mr.doob 已提交
2401

M
Mr.doob 已提交
2402 2403 2404
				_lights.hemi[ hemiLength ] = uniforms;

				hemiLength ++;
M
Mr.doob 已提交
2405 2406 2407 2408 2409

			}

		}

M
Mr.doob 已提交
2410 2411 2412
		_lights.ambient[ 0 ] = r;
		_lights.ambient[ 1 ] = g;
		_lights.ambient[ 2 ] = b;
M
Mr.doob 已提交
2413

M
Mr.doob 已提交
2414 2415
		_lights.directional.length = directionalLength;
		_lights.spot.length = spotLength;
2416
		_lights.rectArea.length = rectAreaLength;
2417
		_lights.point.length = pointLength;
M
Mr.doob 已提交
2418
		_lights.hemi.length = hemiLength;
2419

2420 2421
		// TODO (sam-g-steel) why aren't we using join
		_lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + rectAreaLength + ',' + hemiLength + ',' + _lights.shadows.length;
2422

M
Mr.doob 已提交
2423
	}
M
Mr.doob 已提交
2424 2425 2426 2427 2428

	// GL state setting

	this.setFaceCulling = function ( cullFace, frontFaceDirection ) {

T
tschw 已提交
2429
		state.setCullFace( cullFace );
R
Rich Harris 已提交
2430
		state.setFlipSided( frontFaceDirection === FrontFaceDirectionCW );
M
Mr.doob 已提交
2431 2432 2433 2434 2435

	};

	// Textures

T
tschw 已提交
2436 2437 2438 2439 2440 2441
	function allocTextureUnit() {

		var textureUnit = _usedTextureUnits;

		if ( textureUnit >= capabilities.maxTextures ) {

M
Mugen87 已提交
2442
			console.warn( 'THREE.WebGLRenderer: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );
T
tschw 已提交
2443 2444 2445 2446 2447 2448 2449 2450 2451

		}

		_usedTextureUnits += 1;

		return textureUnit;

	}

2452
	this.allocTextureUnit = allocTextureUnit;
T
tschw 已提交
2453

2454
	// this.setTexture2D = setTexture2D;
M
Mr.doob 已提交
2455
	this.setTexture2D = ( function () {
T
tschw 已提交
2456

2457
		var warned = false;
T
tschw 已提交
2458

2459
		// backwards compatibility: peel texture.texture
W
WestLangley 已提交
2460
		return function setTexture2D( texture, slot ) {
T
tschw 已提交
2461

T
Takahiro 已提交
2462
			if ( texture && texture.isWebGLRenderTarget ) {
T
tschw 已提交
2463

2464
				if ( ! warned ) {
T
tschw 已提交
2465

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

2469
				}
T
tschw 已提交
2470

2471
				texture = texture.texture;
T
tschw 已提交
2472

2473
			}
T
tschw 已提交
2474

2475
			textures.setTexture2D( texture, slot );
T
tschw 已提交
2476

2477
		};
T
tschw 已提交
2478

2479
	}() );
T
tschw 已提交
2480

M
Mr.doob 已提交
2481
	this.setTexture = ( function () {
2482 2483 2484

		var warned = false;

W
WestLangley 已提交
2485
		return function setTexture( texture, slot ) {
2486 2487 2488 2489 2490 2491 2492 2493

			if ( ! warned ) {

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

			}

2494
			textures.setTexture2D( texture, slot );
2495 2496 2497 2498 2499

		};

	}() );

M
Mr.doob 已提交
2500
	this.setTextureCube = ( function () {
2501 2502 2503

		var warned = false;

W
WestLangley 已提交
2504
		return function setTextureCube( texture, slot ) {
2505 2506

			// backwards compatibility: peel texture.texture
T
Takahiro 已提交
2507
			if ( texture && texture.isWebGLRenderTargetCube ) {
2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521

				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 已提交
2522
			if ( ( texture && texture.isCubeTexture ) ||
2523
				( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {
2524 2525 2526 2527

				// CompressedTexture can have Array in image :/

				// this function alone should take care of cube textures
2528
				textures.setTextureCube( texture, slot );
2529 2530 2531 2532 2533

			} else {

				// assumed: texture property of THREE.WebGLRenderTargetCube

2534
				textures.setTextureCubeDynamic( texture, slot );
2535 2536 2537 2538 2539 2540

			}

		};

	}() );
T
tschw 已提交
2541

2542
	this.getRenderTarget = function () {
2543 2544 2545

		return _currentRenderTarget;

M
Michael Herzog 已提交
2546
	};
2547

2548
	this.setRenderTarget = function ( renderTarget ) {
M
Mr.doob 已提交
2549

2550 2551
		_currentRenderTarget = renderTarget;

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

2554
			textures.setupRenderTarget( renderTarget );
M
Mr.doob 已提交
2555 2556 2557

		}

T
Takahiro 已提交
2558
		var isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );
2559
		var framebuffer;
M
Mr.doob 已提交
2560 2561 2562

		if ( renderTarget ) {

2563
			var renderTargetProperties = properties.get( renderTarget );
F
Fordy 已提交
2564

M
Mr.doob 已提交
2565 2566
			if ( isCube ) {

2567
				framebuffer = renderTargetProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];
M
Mr.doob 已提交
2568 2569 2570

			} else {

2571
				framebuffer = renderTargetProperties.__webglFramebuffer;
M
Mr.doob 已提交
2572 2573 2574

			}

2575 2576
			_currentScissor.copy( renderTarget.scissor );
			_currentScissorTest = renderTarget.scissorTest;
2577

2578
			_currentViewport.copy( renderTarget.viewport );
M
Mr.doob 已提交
2579 2580 2581 2582 2583

		} else {

			framebuffer = null;

2584
			_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );
2585
			_currentScissorTest = _scissorTest;
2586

2587
			_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );
M
Mr.doob 已提交
2588 2589 2590

		}

M
Mr.doob 已提交
2591
		if ( _currentFramebuffer !== framebuffer ) {
M
Mr.doob 已提交
2592 2593 2594 2595 2596 2597

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

		}

2598 2599
		state.scissor( _currentScissor );
		state.setScissorTest( _currentScissorTest );
2600

0
06wj 已提交
2601
		state.viewport( _currentViewport );
2602

M
Mr.doob 已提交
2603 2604 2605
		if ( isCube ) {

			var textureProperties = properties.get( renderTarget.texture );
2606
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );
M
Mr.doob 已提交
2607 2608 2609

		}

M
Mr.doob 已提交
2610 2611
	};

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

0
06wj 已提交
2614
		if ( ! ( renderTarget && renderTarget.isWebGLRenderTarget ) ) {
2615

2616
			console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
G
gero3 已提交
2617
			return;
2618

G
gero3 已提交
2619
		}
2620

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

M
Mr.doob 已提交
2623
		if ( framebuffer ) {
2624

G
gero3 已提交
2625
			var restore = false;
2626

M
Mr.doob 已提交
2627
			if ( framebuffer !== _currentFramebuffer ) {
2628

M
Mr.doob 已提交
2629
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
2630

G
gero3 已提交
2631
				restore = true;
2632

G
gero3 已提交
2633
			}
2634

M
Mr.doob 已提交
2635
			try {
2636

M
Mr.doob 已提交
2637
				var texture = renderTarget.texture;
M
Mr.doob 已提交
2638 2639
				var textureFormat = texture.format;
				var textureType = texture.type;
2640

M
Mr.doob 已提交
2641
				if ( textureFormat !== RGBAFormat && paramThreeToGL( textureFormat ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {
2642

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

M
Mr.doob 已提交
2646
				}
2647

M
Mr.doob 已提交
2648
				if ( textureType !== UnsignedByteType && paramThreeToGL( textureType ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE ) && // IE11, Edge and Chrome Mac < 52 (#9513)
2649 2650
					! ( 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' ) ) ) {
2651

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

M
Mr.doob 已提交
2655
				}
2656

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

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

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

M
Mr.doob 已提交
2663
						_gl.readPixels( x, y, width, height, paramThreeToGL( textureFormat ), paramThreeToGL( textureType ), buffer );
2664 2665

					}
2666

M
Mr.doob 已提交
2667
				} else {
M
Mr.doob 已提交
2668

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

				}
M
Mr.doob 已提交
2672

M
Mr.doob 已提交
2673
			} finally {
M
Mr.doob 已提交
2674

M
Mr.doob 已提交
2675 2676 2677
				if ( restore ) {

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

M
Mr.doob 已提交
2679 2680 2681
				}

			}
M
Mr.doob 已提交
2682 2683 2684

		}

M
Mr.doob 已提交
2685 2686
	};

M
Mr.doob 已提交
2687 2688
	// Map three.js constants to WebGL constants

M
Mr.doob 已提交
2689
	function paramThreeToGL( p ) {
M
Mr.doob 已提交
2690

2691 2692
		var extension;

R
Rich Harris 已提交
2693 2694 2695
		if ( p === RepeatWrapping ) return _gl.REPEAT;
		if ( p === ClampToEdgeWrapping ) return _gl.CLAMP_TO_EDGE;
		if ( p === MirroredRepeatWrapping ) return _gl.MIRRORED_REPEAT;
M
Mr.doob 已提交
2696

R
Rich Harris 已提交
2697 2698 2699
		if ( p === NearestFilter ) return _gl.NEAREST;
		if ( p === NearestMipMapNearestFilter ) return _gl.NEAREST_MIPMAP_NEAREST;
		if ( p === NearestMipMapLinearFilter ) return _gl.NEAREST_MIPMAP_LINEAR;
M
Mr.doob 已提交
2700

R
Rich Harris 已提交
2701 2702 2703
		if ( p === LinearFilter ) return _gl.LINEAR;
		if ( p === LinearMipMapNearestFilter ) return _gl.LINEAR_MIPMAP_NEAREST;
		if ( p === LinearMipMapLinearFilter ) return _gl.LINEAR_MIPMAP_LINEAR;
M
Mr.doob 已提交
2704

R
Rich Harris 已提交
2705 2706 2707 2708
		if ( p === UnsignedByteType ) return _gl.UNSIGNED_BYTE;
		if ( p === UnsignedShort4444Type ) return _gl.UNSIGNED_SHORT_4_4_4_4;
		if ( p === UnsignedShort5551Type ) return _gl.UNSIGNED_SHORT_5_5_5_1;
		if ( p === UnsignedShort565Type ) return _gl.UNSIGNED_SHORT_5_6_5;
M
Mr.doob 已提交
2709

R
Rich Harris 已提交
2710 2711 2712 2713 2714 2715
		if ( p === ByteType ) return _gl.BYTE;
		if ( p === ShortType ) return _gl.SHORT;
		if ( p === UnsignedShortType ) return _gl.UNSIGNED_SHORT;
		if ( p === IntType ) return _gl.INT;
		if ( p === UnsignedIntType ) return _gl.UNSIGNED_INT;
		if ( p === FloatType ) return _gl.FLOAT;
M
Mr.doob 已提交
2716

2717
		if ( p === HalfFloatType ) {
2718

2719
			extension = extensions.get( 'OES_texture_half_float' );
2720

2721
			if ( extension !== null ) return extension.HALF_FLOAT_OES;
2722 2723 2724

		}

R
Rich Harris 已提交
2725 2726 2727 2728 2729 2730
		if ( p === AlphaFormat ) return _gl.ALPHA;
		if ( p === RGBFormat ) return _gl.RGB;
		if ( p === RGBAFormat ) return _gl.RGBA;
		if ( p === LuminanceFormat ) return _gl.LUMINANCE;
		if ( p === LuminanceAlphaFormat ) return _gl.LUMINANCE_ALPHA;
		if ( p === DepthFormat ) return _gl.DEPTH_COMPONENT;
2731
		if ( p === DepthStencilFormat ) return _gl.DEPTH_STENCIL;
M
Mr.doob 已提交
2732

R
Rich Harris 已提交
2733 2734 2735
		if ( p === AddEquation ) return _gl.FUNC_ADD;
		if ( p === SubtractEquation ) return _gl.FUNC_SUBTRACT;
		if ( p === ReverseSubtractEquation ) return _gl.FUNC_REVERSE_SUBTRACT;
M
Mr.doob 已提交
2736

R
Rich Harris 已提交
2737 2738 2739 2740 2741 2742 2743 2744
		if ( p === ZeroFactor ) return _gl.ZERO;
		if ( p === OneFactor ) return _gl.ONE;
		if ( p === SrcColorFactor ) return _gl.SRC_COLOR;
		if ( p === OneMinusSrcColorFactor ) return _gl.ONE_MINUS_SRC_COLOR;
		if ( p === SrcAlphaFactor ) return _gl.SRC_ALPHA;
		if ( p === OneMinusSrcAlphaFactor ) return _gl.ONE_MINUS_SRC_ALPHA;
		if ( p === DstAlphaFactor ) return _gl.DST_ALPHA;
		if ( p === OneMinusDstAlphaFactor ) return _gl.ONE_MINUS_DST_ALPHA;
M
Mr.doob 已提交
2745

R
Rich Harris 已提交
2746 2747 2748
		if ( p === DstColorFactor ) return _gl.DST_COLOR;
		if ( p === OneMinusDstColorFactor ) return _gl.ONE_MINUS_DST_COLOR;
		if ( p === SrcAlphaSaturateFactor ) return _gl.SRC_ALPHA_SATURATE;
M
Mr.doob 已提交
2749

2750 2751
		if ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format ||
			p === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) {
M
Mr.doob 已提交
2752

2753
			extension = extensions.get( 'WEBGL_compressed_texture_s3tc' );
2754

2755 2756 2757 2758 2759 2760 2761 2762
			if ( extension !== null ) {

				if ( p === RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT;
				if ( p === RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT;
				if ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT;
				if ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT;

			}
M
Mr.doob 已提交
2763 2764 2765

		}

2766
		if ( p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format ||
2767
			p === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format ) {
2768

2769
			extension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );
P
Pierre Lepers 已提交
2770

2771 2772 2773 2774 2775 2776 2777 2778
			if ( extension !== null ) {

				if ( p === RGB_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
				if ( p === RGB_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
				if ( p === RGBA_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
				if ( p === RGBA_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;

			}
P
Pierre Lepers 已提交
2779 2780 2781

		}

2782
		if ( p === RGB_ETC1_Format ) {
2783

2784
			extension = extensions.get( 'WEBGL_compressed_texture_etc1' );
2785

2786
			if ( extension !== null ) return extension.COMPRESSED_RGB_ETC1_WEBGL;
2787 2788 2789

		}

2790 2791 2792
		if ( p === MinEquation || p === MaxEquation ) {

			extension = extensions.get( 'EXT_blend_minmax' );
2793

2794
			if ( extension !== null ) {
2795

2796 2797 2798 2799
				if ( p === MinEquation ) return extension.MIN_EXT;
				if ( p === MaxEquation ) return extension.MAX_EXT;

			}
2800 2801 2802

		}

2803
		if ( p === UnsignedInt248Type ) {
2804

2805
			extension = extensions.get( 'WEBGL_depth_texture' );
2806

2807
			if ( extension !== null ) return extension.UNSIGNED_INT_24_8_WEBGL;
2808 2809 2810

		}

M
Mr.doob 已提交
2811 2812
		return 0;

M
Mr.doob 已提交
2813
	}
M
Mr.doob 已提交
2814

M
Mr.doob 已提交
2815
}
R
Rich Harris 已提交
2816

T
Tristan VALCKE 已提交
2817

2818
export { WebGLRenderer };