WebGLRenderer.js 67.5 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, 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 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
		_matrix4 = new Matrix4(),
A
aardgoose 已提交
160
		_matrix42 = new Matrix4(),
M
Mr.doob 已提交
161

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

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

166
			hash: '',
167

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

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

183
		},
184

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

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

192
		_infoRender = {
193

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

200
		};
M
Mr.doob 已提交
201

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

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

	};
209

210

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

	var _gl;

M
Mr.doob 已提交
215 216
	try {

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

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

		if ( _gl === null ) {

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

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

			} else {

				throw 'Error creating WebGL context.';

			}
M
Mr.doob 已提交
239 240 241

		}

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

		if ( _gl.getShaderPrecisionFormat === undefined ) {

			_gl.getShaderPrecisionFormat = function () {

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

			};

		}

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

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

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

	}

263 264 265
	var extensions, capabilities, state;
	var properties, textures, attributes, geometries, objects;
	var programCache, lightCache, renderLists;
266

267
	var background, bufferRenderer, indexedBufferRenderer;
268

269
	function initGLContext() {
270

271 272 273 274 275 276 277 278
		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' );
279

280
		if ( extensions.get( 'OES_element_index_uint' ) ) {
M
Mr.doob 已提交
281

282
			BufferGeometry.MaxIndex = 4294967296;
283

284
		}
285

286
		capabilities = new WebGLCapabilities( _gl, extensions, parameters );
287

288 289 290
		state = new WebGLState( _gl, extensions, paramThreeToGL );
		state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );
		state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );
291

292 293 294 295 296 297 298 299
		properties = new WebGLProperties();
		textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, _infoMemory );
		attributes = new WebGLAttributes( _gl );
		geometries = new WebGLGeometries( _gl, attributes, _infoMemory );
		objects = new WebGLObjects( _gl, geometries, _infoRender );
		programCache = new WebGLPrograms( _this, capabilities );
		lightCache = new WebGLLights();
		renderLists = new WebGLRenderLists();
300

301
		background = new WebGLBackground( _this, state, objects, _premultipliedAlpha );
M
Mr.doob 已提交
302

303 304
		bufferRenderer = new WebGLBufferRenderer( _gl, extensions, _infoRender );
		indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );
305

306
		_this.info.programs = programCache.programs;
307 308 309

	}

310
	initGLContext();
311

312
	var vr = new WebVRManager( _this );
313

314
	//
315

316
	function getTargetPixelRatio() {
317

318
		return _currentRenderTarget === null ? _pixelRatio : 1;
M
Mr.doob 已提交
319

320
	}
M
Mr.doob 已提交
321 322

	this.context = _gl;
M
Mr.doob 已提交
323
	this.capabilities = capabilities;
324
	this.extensions = extensions;
325
	this.properties = properties;
A
aardgoose 已提交
326
	this.renderLists = renderLists;
M
Mr.doob 已提交
327
	this.state = state;
328
	this.vr = vr;
M
Mr.doob 已提交
329

M
Mr.doob 已提交
330 331
	// shadow map

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

334
	this.shadowMap = shadowMap;
M
Mr.doob 已提交
335

M
Mr.doob 已提交
336

M
Mr.doob 已提交
337 338
	// Plugins

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

M
Mr.doob 已提交
342 343 344 345 346 347 348 349
	// API

	this.getContext = function () {

		return _gl;

	};

350 351 352 353 354 355
	this.getContextAttributes = function () {

		return _gl.getContextAttributes();

	};

356 357
	this.forceContextLoss = function () {

M
Michael Bond 已提交
358 359
		var extension = extensions.get( 'WEBGL_lose_context' );
		if ( extension ) extension.loseContext();
360 361 362

	};

363 364 365 366 367 368 369
	this.forceContextRestore = function () {

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

	};

370
	this.getMaxAnisotropy = function () {
371

372
		return capabilities.getMaxAnisotropy();
373

374
	};
M
Mr.doob 已提交
375 376 377

	this.getPrecision = function () {

G
gero3 已提交
378
		return capabilities.precision;
M
Mr.doob 已提交
379 380 381

	};

382 383
	this.getPixelRatio = function () {

384
		return _pixelRatio;
385 386 387 388 389

	};

	this.setPixelRatio = function ( value ) {

390 391 392 393
		if ( value === undefined ) return;

		_pixelRatio = value;

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

	};

398 399 400
	this.getSize = function () {

		return {
401 402
			width: _width,
			height: _height
403 404 405 406
		};

	};

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

409 410 411 412 413 414 415 416 417
		var device = vr.getDevice();

		if ( device && device.isPresenting ) {

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

		}

418 419 420
		_width = width;
		_height = height;

421 422
		_canvas.width = width * _pixelRatio;
		_canvas.height = height * _pixelRatio;
423

424
		if ( updateStyle !== false ) {
425

G
gero3 已提交
426 427
			_canvas.style.width = width + 'px';
			_canvas.style.height = height + 'px';
428

G
gero3 已提交
429
		}
M
Mr.doob 已提交
430

431
		this.setViewport( 0, 0, width, height );
M
Mr.doob 已提交
432 433 434

	};

M
Mr.doob 已提交
435 436 437 438 439 440 441 442 443
	this.getDrawingBufferSize = function () {

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

	};

444 445 446 447 448 449 450 451 452 453 454 455 456 457
	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 已提交
458 459
	this.setViewport = function ( x, y, width, height ) {

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

M
Mr.doob 已提交
463 464
	};

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

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

M
Mr.doob 已提交
470 471
	};

472 473
	this.setScissorTest = function ( boolean ) {

474
		state.setScissorTest( _scissorTest = boolean );
M
Mr.doob 已提交
475 476 477 478 479

	};

	// Clearing

480 481 482 483
	this.getClearColor = background.getClearColor;
	this.setClearColor = background.setClearColor;
	this.getClearAlpha = background.getClearAlpha;
	this.setClearAlpha = background.setClearAlpha;
M
Mr.doob 已提交
484 485 486 487 488 489 490 491 492 493

	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 );
494 495 496 497 498

	};

	this.clearColor = function () {

M
Mr.doob 已提交
499
		this.clear( true, false, false );
500 501 502 503 504

	};

	this.clearDepth = function () {

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

	};

	this.clearStencil = function () {

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

	};

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

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

	};

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

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

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

529 530
		renderLists.dispose();

D
dubejf 已提交
531 532
	};

M
Mr.doob 已提交
533
	// Events
M
Mr.doob 已提交
534

D
dubejf 已提交
535 536 537 538
	function onContextLost( event ) {

		event.preventDefault();

539 540
		console.log( 'THREE.WebGLRenderer: Context Lost.' );

541 542 543 544 545
		_isContextLost = true;

	}

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

547
		console.log( 'THREE.WebGLRenderer: Context Restored.' );
548 549

		_isContextLost = false;
D
dubejf 已提交
550

551 552
		initGLContext();

M
Mr.doob 已提交
553
	}
D
dubejf 已提交
554

555
	function onMaterialDispose( event ) {
M
Mr.doob 已提交
556 557 558 559 560 561 562

		var material = event.target;

		material.removeEventListener( 'dispose', onMaterialDispose );

		deallocateMaterial( material );

563
	}
M
Mr.doob 已提交
564 565 566

	// Buffer deallocation

567
	function deallocateMaterial( material ) {
M
Mr.doob 已提交
568

569 570
		releaseMaterialProgramReference( material );

571
		properties.remove( material );
572

573
	}
574 575


576
	function releaseMaterialProgramReference( material ) {
577

578
		var programInfo = properties.get( material ).program;
M
Mr.doob 已提交
579 580 581

		material.program = undefined;

582
		if ( programInfo !== undefined ) {
M
Mr.doob 已提交
583

584
			programCache.releaseProgram( programInfo );
M
Mr.doob 已提交
585

M
Mr.doob 已提交
586 587
		}

588
	}
M
Mr.doob 已提交
589 590 591

	// Buffer rendering

M
Mr.doob 已提交
592 593 594 595 596 597 598 599 600 601
	function renderObjectImmediate( object, program, material ) {

		object.render( function ( object ) {

			_this.renderBufferImmediate( object, program, material );

		} );

	}

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

604
		state.initAttributes();
605

606
		var buffers = properties.get( object );
607

608 609 610 611
		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 已提交
612

613
		var programAttributes = program.getAttributes();
614

M
Mr.doob 已提交
615 616
		if ( object.hasPositions ) {

617
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );
M
Mr.doob 已提交
618
			_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );
619

620 621
			state.enableAttribute( programAttributes.position );
			_gl.vertexAttribPointer( programAttributes.position, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
622 623 624 625 626

		}

		if ( object.hasNormals ) {

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

629
			if ( ! material.isMeshPhongMaterial &&
630
				! material.isMeshStandardMaterial &&
631
				! material.isMeshNormalMaterial &&
632
				material.flatShading === true ) {
M
Mr.doob 已提交
633

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

636
					var array = object.normalArray;
M
Mr.doob 已提交
637

638 639 640
					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 已提交
641

642 643 644
					array[ i + 0 ] = nx;
					array[ i + 1 ] = ny;
					array[ i + 2 ] = nz;
M
Mr.doob 已提交
645

646 647 648
					array[ i + 3 ] = nx;
					array[ i + 4 ] = ny;
					array[ i + 5 ] = nz;
M
Mr.doob 已提交
649

650 651 652
					array[ i + 6 ] = nx;
					array[ i + 7 ] = ny;
					array[ i + 8 ] = nz;
M
Mr.doob 已提交
653 654 655 656 657 658

				}

			}

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

660
			state.enableAttribute( programAttributes.normal );
661

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

		}

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

668
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );
M
Mr.doob 已提交
669
			_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );
670

671
			state.enableAttribute( programAttributes.uv );
672

673
			_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
674 675 676

		}

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

679
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );
M
Mr.doob 已提交
680
			_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );
681

682
			state.enableAttribute( programAttributes.color );
683

684
			_gl.vertexAttribPointer( programAttributes.color, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
685 686 687

		}

688
		state.disableUnusedAttributes();
689

M
Mr.doob 已提交
690 691 692 693 694 695
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );

		object.count = 0;

	};

M
Mr.doob 已提交
696 697 698 699 700 701
	function absNumericalSort( a, b ) {

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

	}

702
	this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {
703

704
		state.setMaterial( material );
M
Mr.doob 已提交
705

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

M
Mr.doob 已提交
709
		var updateBuffers = false;
M
Mr.doob 已提交
710 711 712 713 714 715 716 717 718 719 720 721 722 723

		if ( geometryProgram !== _currentGeometryProgram ) {

			_currentGeometryProgram = geometryProgram;
			updateBuffers = true;

		}

		// morph targets

		var morphTargetInfluences = object.morphTargetInfluences;

		if ( morphTargetInfluences !== undefined ) {

M
Mr.doob 已提交
724 725
			// TODO Remove allocations

M
Mr.doob 已提交
726 727 728 729 730 731 732 733 734
			var activeInfluences = [];

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

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

			}

735
			activeInfluences.sort( absNumericalSort );
M
Mr.doob 已提交
736 737 738 739 740 741 742

			if ( activeInfluences.length > 8 ) {

				activeInfluences.length = 8;

			}

743 744
			var morphAttributes = geometry.morphAttributes;

M
Mr.doob 已提交
745 746 747 748 749 750 751
			for ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {

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

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

752
					var index = influence[ 1 ];
M
Mr.doob 已提交
753

754 755
					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 已提交
756 757 758

				} else {

759 760
					if ( material.morphTargets === true ) geometry.removeAttribute( 'morphTarget' + i );
					if ( material.morphNormals === true ) geometry.removeAttribute( 'morphNormal' + i );
M
Mr.doob 已提交
761 762 763 764 765

				}

			}

766 767 768 769 770 771
			for ( var i = activeInfluences.length, il = morphInfluences.length; i < il; i ++ ) {

				morphInfluences[ i ] = 0.0;

			}

M
Mr.doob 已提交
772
			program.getUniforms().setValue( _gl, 'morphTargetInfluences', morphInfluences );
M
Mr.doob 已提交
773 774 775 776 777

			updateBuffers = true;

		}

778 779
		//

780
		var index = geometry.index;
781
		var position = geometry.attributes.position;
782
		var rangeFactor = 1;
783

784 785
		if ( material.wireframe === true ) {

786
			index = geometries.getWireframeAttribute( geometry );
787
			rangeFactor = 2;
788 789 790

		}

M
Mr.doob 已提交
791
		var attribute;
M
Mr.doob 已提交
792
		var renderer = bufferRenderer;
793

794
		if ( index !== null ) {
795

M
Mr.doob 已提交
796
			attribute = attributes.get( index );
797

798
			renderer = indexedBufferRenderer;
M
Mr.doob 已提交
799
			renderer.setIndex( attribute );
800

801
		}
M
Mr.doob 已提交
802

803
		if ( updateBuffers ) {
M
Mr.doob 已提交
804

805
			setupVertexAttributes( material, program, geometry );
M
Mr.doob 已提交
806

807
			if ( index !== null ) {
808

M
Mr.doob 已提交
809
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, attribute.buffer );
810 811 812

			}

813
		}
814

815 816
		//

817
		var dataCount = 0;
818

M
Mr.doob 已提交
819
		if ( index !== null ) {
820

M
Mr.doob 已提交
821
			dataCount = index.count;
822

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

M
Mr.doob 已提交
825
			dataCount = position.count;
826

M
Mr.doob 已提交
827
		}
828

M
Mr.doob 已提交
829 830
		var rangeStart = geometry.drawRange.start * rangeFactor;
		var rangeCount = geometry.drawRange.count * rangeFactor;
831

M
Mr.doob 已提交
832 833
		var groupStart = group !== null ? group.start * rangeFactor : 0;
		var groupCount = group !== null ? group.count * rangeFactor : Infinity;
834

M
Mr.doob 已提交
835 836
		var drawStart = Math.max( rangeStart, groupStart );
		var drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1;
M
Mr.doob 已提交
837 838 839

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

840 841
		if ( drawCount === 0 ) return;

M
Mr.doob 已提交
842
		//
843

844
		if ( object.isMesh ) {
845

846
			if ( material.wireframe === true ) {
847

848
				state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );
849
				renderer.setMode( _gl.LINES );
850

851
			} else {
M
Mr.doob 已提交
852 853

				switch ( object.drawMode ) {
854

R
Rich Harris 已提交
855
					case TrianglesDrawMode:
B
Ben Adams 已提交
856 857 858
						renderer.setMode( _gl.TRIANGLES );
						break;

R
Rich Harris 已提交
859
					case TriangleStripDrawMode:
B
Ben Adams 已提交
860 861 862
						renderer.setMode( _gl.TRIANGLE_STRIP );
						break;

R
Rich Harris 已提交
863
					case TriangleFanDrawMode:
B
Ben Adams 已提交
864 865 866 867
						renderer.setMode( _gl.TRIANGLE_FAN );
						break;

				}
868

869
			}
870

871

872
		} else if ( object.isLine ) {
873

874
			var lineWidth = material.linewidth;
875

876
			if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material
877

878
			state.setLineWidth( lineWidth * getTargetPixelRatio() );
879

880
			if ( object.isLineSegments ) {
881

882
				renderer.setMode( _gl.LINES );
883

884 885 886 887
			} else if ( object.isLineLoop ) {

				renderer.setMode( _gl.LINE_LOOP );

888
			} else {
889

890
				renderer.setMode( _gl.LINE_STRIP );
891 892

			}
M
Mr.doob 已提交
893

894
		} else if ( object.isPoints ) {
895 896

			renderer.setMode( _gl.POINTS );
897 898

		}
899

T
Takahiro 已提交
900
		if ( geometry && geometry.isInstancedBufferGeometry ) {
M
Mr.doob 已提交
901 902 903

			if ( geometry.maxInstancedCount > 0 ) {

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

J
jfranc 已提交
906
			}
907 908 909

		} else {

M
Mr.doob 已提交
910
			renderer.render( drawStart, drawCount );
911

M
Mr.doob 已提交
912 913 914 915
		}

	};

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

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

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

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

M
Mr.doob 已提交
925 926 927
			}

		}
B
Ben Adams 已提交
928

929 930
		if ( startIndex === undefined ) startIndex = 0;

931 932
		state.initAttributes();

933
		var geometryAttributes = geometry.attributes;
934

935
		var programAttributes = program.getAttributes();
936

937
		var materialDefaultAttributeValues = material.defaultAttributeValues;
938

939
		for ( var name in programAttributes ) {
940

941
			var programAttribute = programAttributes[ name ];
M
Mr.doob 已提交
942

M
Mr.doob 已提交
943
			if ( programAttribute >= 0 ) {
M
Mr.doob 已提交
944

945
				var geometryAttribute = geometryAttributes[ name ];
946

M
Mr.doob 已提交
947
				if ( geometryAttribute !== undefined ) {
M
Mr.doob 已提交
948

949
					var normalized = geometryAttribute.normalized;
950
					var size = geometryAttribute.itemSize;
951

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

954 955 956 957
					// TODO Attribute may not be available on context restore

					if ( attribute === undefined ) continue;

M
Mr.doob 已提交
958 959 960
					var buffer = attribute.buffer;
					var type = attribute.type;
					var bytesPerElement = attribute.bytesPerElement;
961

A
aardgoose 已提交
962
					if ( geometryAttribute.isInterleavedBufferAttribute ) {
963

M
Mr.doob 已提交
964 965 966 967
						var data = geometryAttribute.data;
						var stride = data.stride;
						var offset = geometryAttribute.offset;

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

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

M
Mr.doob 已提交
972
							if ( geometry.maxInstancedCount === undefined ) {
973

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

M
Mr.doob 已提交
976
							}
B
Ben Adams 已提交
977

M
Mr.doob 已提交
978
						} else {
B
Ben Adams 已提交
979

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

M
Mr.doob 已提交
982
						}
B
Ben Adams 已提交
983

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

M
Mr.doob 已提交
987
					} else {
B
Ben Adams 已提交
988

A
aardgoose 已提交
989
						if ( geometryAttribute.isInstancedBufferAttribute ) {
B
Ben Adams 已提交
990

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

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

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

M
Mr.doob 已提交
997
							}
B
Ben Adams 已提交
998

M
Mr.doob 已提交
999 1000 1001 1002
						} else {

							state.enableAttribute( programAttribute );

M
Mr.doob 已提交
1003
						}
B
Ben Adams 已提交
1004

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

B
Ben Adams 已提交
1008
					}
M
Mr.doob 已提交
1009

1010 1011
				} else if ( materialDefaultAttributeValues !== undefined ) {

T
tschw 已提交
1012
					var value = materialDefaultAttributeValues[ name ];
1013

1014
					if ( value !== undefined ) {
M
Mr.doob 已提交
1015

1016
						switch ( value.length ) {
M
Mr.doob 已提交
1017

1018 1019 1020
							case 2:
								_gl.vertexAttrib2fv( programAttribute, value );
								break;
M
Mr.doob 已提交
1021

1022 1023 1024
							case 3:
								_gl.vertexAttrib3fv( programAttribute, value );
								break;
M
Mr.doob 已提交
1025

1026 1027 1028
							case 4:
								_gl.vertexAttrib4fv( programAttribute, value );
								break;
1029

1030 1031
							default:
								_gl.vertexAttrib1fv( programAttribute, value );
1032 1033

						}
M
Mr.doob 已提交
1034 1035 1036 1037 1038 1039 1040 1041

					}

				}

			}

		}
1042

1043
		state.disableUnusedAttributes();
1044

M
Mr.doob 已提交
1045 1046
	}

M
Mr.doob 已提交
1047
	// Compile
M
Mr.doob 已提交
1048

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

M
Mr.doob 已提交
1051
		lights = [];
1052

M
Mr.doob 已提交
1053
		scene.traverse( function ( object ) {
G
gero3 已提交
1054 1055

			if ( object.isLight ) {
M
Mr.doob 已提交
1056 1057 1058

				lights.push( object );

G
gero3 已提交
1059
			}
M
Mr.doob 已提交
1060 1061 1062 1063 1064 1065 1066 1067 1068

		} );

		setupLights( lights, camera );

		scene.traverse( function ( object ) {

			if ( object.material ) {

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

G
gero3 已提交
1071
					for ( var i = 0; i < object.material.length; i ++ ) {
M
Mr.doob 已提交
1072 1073 1074

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

G
gero3 已提交
1075
					}
M
Mr.doob 已提交
1076

G
gero3 已提交
1077
				} else {
M
Mr.doob 已提交
1078 1079 1080

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

G
gero3 已提交
1081
				}
M
Mr.doob 已提交
1082

G
gero3 已提交
1083
			}
M
Mr.doob 已提交
1084 1085

		} );
G
gero3 已提交
1086 1087

	};
1088

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

1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104
	this.animate = function ( callback ) {

		function onFrame() {

			callback();

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

		}

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

	};

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

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

1109
			console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );
M
Mr.doob 已提交
1110 1111 1112 1113
			return;

		}

1114 1115
		if ( _isContextLost ) return;

M
Mr.doob 已提交
1116 1117
		// reset caching for this frame

1118
		_currentGeometryProgram = '';
1119
		_currentMaterialId = - 1;
1120
		_currentCamera = null;
M
Mr.doob 已提交
1121 1122 1123

		// update scene graph

1124
		if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
M
Mr.doob 已提交
1125 1126 1127

		// update camera matrices and frustum

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

1130 1131 1132 1133 1134 1135
		if ( vr.enabled ) {

			camera = vr.getCamera( camera );

		}

M
Mr.doob 已提交
1136 1137 1138
		_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
		_frustum.setFromMatrix( _projScreenMatrix );

M
Mr.doob 已提交
1139
		lights.length = 0;
M
Mr.doob 已提交
1140 1141 1142
		sprites.length = 0;
		lensFlares.length = 0;

T
tschw 已提交
1143
		_localClippingEnabled = this.localClippingEnabled;
M
Mr.doob 已提交
1144
		_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );
T
tschw 已提交
1145

1146 1147 1148
		currentRenderList = renderLists.get( scene, camera );
		currentRenderList.init();

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

1151
		currentRenderList.finish();
1152

M
Mr.doob 已提交
1153
		if ( _this.sortObjects === true ) {
1154

1155
			currentRenderList.sort();
M
Mr.doob 已提交
1156

1157 1158
		}

M
Mr.doob 已提交
1159
		//
M
Mr.doob 已提交
1160

T
tschw 已提交
1161
		if ( _clippingEnabled ) _clipping.beginShadows();
T
tschw 已提交
1162

1163 1164
		setupShadows( lights );

M
Mr.doob 已提交
1165
		shadowMap.render( scene, camera );
M
Mr.doob 已提交
1166

1167 1168
		setupLights( lights, camera );

T
tschw 已提交
1169
		if ( _clippingEnabled ) _clipping.endShadows();
T
tschw 已提交
1170

M
Mr.doob 已提交
1171 1172
		//

M
Mr.doob 已提交
1173
		_infoRender.frame ++;
1174 1175 1176 1177
		_infoRender.calls = 0;
		_infoRender.vertices = 0;
		_infoRender.faces = 0;
		_infoRender.points = 0;
M
Mr.doob 已提交
1178

1179 1180 1181 1182 1183 1184
		if ( renderTarget === undefined ) {

			renderTarget = null;

		}

M
Mr.doob 已提交
1185 1186
		this.setRenderTarget( renderTarget );

M
Mr.doob 已提交
1187 1188
		//

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

1191
		// render scene
M
Mr.doob 已提交
1192

1193 1194
		var opaqueObjects = currentRenderList.opaque;
		var transparentObjects = currentRenderList.transparent;
M
Mr.doob 已提交
1195

1196
		if ( scene.overrideMaterial ) {
M
Mr.doob 已提交
1197

1198
			var overrideMaterial = scene.overrideMaterial;
1199

1200 1201
			if ( opaqueObjects.length ) renderObjects( opaqueObjects, scene, camera, overrideMaterial );
			if ( transparentObjects.length ) renderObjects( transparentObjects, scene, camera, overrideMaterial );
M
Mr.doob 已提交
1202

1203
		} else {
M
Mr.doob 已提交
1204

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

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

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

1211
			if ( transparentObjects.length ) renderObjects( transparentObjects, scene, camera );
M
Mr.doob 已提交
1212 1213 1214 1215 1216

		}

		// custom render plugins (post pass)

M
Mr.doob 已提交
1217
		spritePlugin.render( scene, camera );
1218
		lensFlarePlugin.render( scene, camera, _currentViewport );
M
Mr.doob 已提交
1219 1220 1221

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

M
Mr.doob 已提交
1222 1223
		if ( renderTarget ) {

1224
			textures.updateRenderTargetMipmap( renderTarget );
M
Mr.doob 已提交
1225 1226 1227

		}

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

1230 1231 1232
		state.buffers.depth.setTest( true );
		state.buffers.depth.setMask( true );
		state.buffers.color.setMask( true );
M
Mr.doob 已提交
1233

M
Mr.doob 已提交
1234 1235 1236 1237 1238
		if ( vr.enabled ) {

			vr.submitFrame();

		}
M
Mr.doob 已提交
1239

M
Mr.doob 已提交
1240 1241 1242
		// _gl.finish();

	};
M
Mr.doob 已提交
1243

1244
	/*
M
Mr.doob 已提交
1245 1246
	// TODO Duplicated code (Frustum)

1247 1248
	var _sphere = new Sphere();

T
tschw 已提交
1249 1250 1251 1252 1253 1254 1255
	function isObjectViewable( object ) {

		var geometry = object.geometry;

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

M
Mr.doob 已提交
1256
		_sphere.copy( geometry.boundingSphere ).
1257
		applyMatrix4( object.matrixWorld );
M
Mr.doob 已提交
1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273

		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 已提交
1274 1275

		if ( ! _frustum.intersectsSphere( sphere ) ) return false;
T
tschw 已提交
1276 1277 1278 1279

		var numPlanes = _clipping.numPlanes;

		if ( numPlanes === 0 ) return true;
T
tschw 已提交
1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291

		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 已提交
1292
		} while ( ++ i !== numPlanes );
T
tschw 已提交
1293 1294 1295 1296

		return true;

	}
1297
	*/
T
tschw 已提交
1298

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

M
Mr.doob 已提交
1301
		if ( ! object.visible ) return;
M
Mr.doob 已提交
1302

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

1305
		if ( visible ) {
1306

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

1309
				lights.push( object );
M
Mr.doob 已提交
1310

1311
			} else if ( object.isSprite ) {
M
Mr.doob 已提交
1312

1313
				if ( ! object.frustumCulled || _frustum.intersectsSprite( object ) ) {
1314

1315
					sprites.push( object );
M
Mr.doob 已提交
1316

1317
				}
M
Mr.doob 已提交
1318

1319
			} else if ( object.isLensFlare ) {
M
Mr.doob 已提交
1320

1321
				lensFlares.push( object );
M
Mr.doob 已提交
1322

1323
			} else if ( object.isImmediateRenderObject ) {
M
Mr.doob 已提交
1324

1325
				if ( sortObjects ) {
M
Mr.doob 已提交
1326

1327 1328
					_vector3.setFromMatrixPosition( object.matrixWorld )
						.applyMatrix4( _projScreenMatrix );
M
Mr.doob 已提交
1329

1330
				}
M
Mr.doob 已提交
1331

1332
				currentRenderList.push( object, null, object.material, _vector3.z, null );
1333

1334
			} else if ( object.isMesh || object.isLine || object.isPoints ) {
1335

1336
				if ( object.isSkinnedMesh ) {
1337

1338
					object.skeleton.update();
1339

1340
				}
1341

1342
				if ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) {
1343

1344 1345 1346 1347 1348 1349
					if ( sortObjects ) {

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

					}
1350

1351 1352
					var geometry = objects.update( object );
					var material = object.material;
1353

1354
					if ( Array.isArray( material ) ) {
1355

1356
						var groups = geometry.groups;
1357

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

1360 1361
							var group = groups[ i ];
							var groupMaterial = material[ group.materialIndex ];
1362

1363
							if ( groupMaterial && groupMaterial.visible ) {
1364

1365 1366 1367
								currentRenderList.push( object, geometry, groupMaterial, _vector3.z, group );

							}
M
Mr.doob 已提交
1368

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

1371
					} else if ( material.visible ) {
1372

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

1375
					}
M
Mr.doob 已提交
1376

1377
				}
M
Mr.doob 已提交
1378

1379
			}
M
Mr.doob 已提交
1380

M
Mr.doob 已提交
1381
		}
M
Mr.doob 已提交
1382

M
Mr.doob 已提交
1383
		var children = object.children;
M
Mr.doob 已提交
1384

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

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

1389
		}
1390

1391
	}
M
Mr.doob 已提交
1392

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

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

1397
			var renderItem = renderList[ i ];
1398

1399 1400 1401 1402
			var object = renderItem.object;
			var geometry = renderItem.geometry;
			var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;
			var group = renderItem.group;
1403

1404
			if ( camera.isArrayCamera ) {
M
Mr.doob 已提交
1405

1406 1407
				_currentArrayCamera = camera;

1408
				var cameras = camera.cameras;
1409

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

1412
					var camera2 = cameras[ j ];
M
Mr.doob 已提交
1413

1414
					if ( object.layers.test( camera2.layers ) ) {
1415

1416
						var bounds = camera2.bounds;
M
Mr.doob 已提交
1417

1418 1419 1420 1421 1422
						var x = bounds.x * _width;
						var y = bounds.y * _height;
						var width = bounds.z * _width;
						var height = bounds.w * _height;

1423 1424
						state.viewport( _currentViewport.set( x, y, width, height ).multiplyScalar( _pixelRatio ) );
						state.scissor( _currentScissor.set( x, y, width, height ).multiplyScalar( _pixelRatio ) );
1425
						state.setScissorTest( true );
1426 1427 1428 1429

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

					}
M
Mr.doob 已提交
1430

1431
				}
1432

1433
			} else {
M
Mr.doob 已提交
1434

1435 1436
				_currentArrayCamera = null;

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

1439
			}
M
Mr.doob 已提交
1440

1441
		}
M
Mr.doob 已提交
1442

1443
	}
G
gero3 已提交
1444

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

1447 1448
		object.onBeforeRender( _this, scene, camera, geometry, material, group );

M
Mr.doob 已提交
1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467
		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 已提交
1468 1469
		object.onAfterRender( _this, scene, camera, geometry, material, group );

M
Mr.doob 已提交
1470 1471
	}

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

1474
		var materialProperties = properties.get( material );
G
gero3 已提交
1475

T
tschw 已提交
1476
		var parameters = programCache.getParameters(
1477
			material, _lights, fog, _clipping.numPlanes, _clipping.numIntersection, object );
T
tschw 已提交
1478

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

1481
		var program = materialProperties.program;
T
tschw 已提交
1482
		var programChange = true;
1483

1484
		if ( program === undefined ) {
B
Ben Adams 已提交
1485

M
Mr.doob 已提交
1486 1487
			// new material
			material.addEventListener( 'dispose', onMaterialDispose );
B
Ben Adams 已提交
1488

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

M
Mr.doob 已提交
1491
			// changed glsl or parameters
1492
			releaseMaterialProgramReference( material );
B
Ben Adams 已提交
1493

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

T
tschw 已提交
1496
			// same glsl and uniform list
T
tschw 已提交
1497 1498
			return;

T
tschw 已提交
1499
		} else {
B
Ben Adams 已提交
1500

T
tschw 已提交
1501 1502
			// only rebuild uniform list
			programChange = false;
B
Ben Adams 已提交
1503 1504 1505

		}

1506
		if ( programChange ) {
B
Ben Adams 已提交
1507

1508
			if ( parameters.shaderID ) {
B
Ben Adams 已提交
1509

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

1512
				materialProperties.shader = {
1513
					name: material.type,
1514
					uniforms: UniformsUtils.clone( shader.uniforms ),
1515 1516 1517
					vertexShader: shader.vertexShader,
					fragmentShader: shader.fragmentShader
				};
B
Ben Adams 已提交
1518

1519
			} else {
B
Ben Adams 已提交
1520

1521
				materialProperties.shader = {
1522 1523 1524 1525 1526
					name: material.type,
					uniforms: material.uniforms,
					vertexShader: material.vertexShader,
					fragmentShader: material.fragmentShader
				};
G
gero3 已提交
1527

1528
			}
G
gero3 已提交
1529

1530
			material.onBeforeCompile( materialProperties.shader );
G
gero3 已提交
1531

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

1534 1535
			materialProperties.program = program;
			material.program = program;
1536 1537 1538

		}

1539
		var programAttributes = program.getAttributes();
M
Mr.doob 已提交
1540 1541 1542 1543 1544

		if ( material.morphTargets ) {

			material.numSupportedMorphTargets = 0;

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

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

					material.numSupportedMorphTargets ++;

				}

			}

		}

		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

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

1563
				if ( programAttributes[ 'morphNormal' + i ] >= 0 ) {
M
Mr.doob 已提交
1564 1565 1566 1567 1568 1569 1570 1571 1572

					material.numSupportedMorphNormals ++;

				}

			}

		}

1573
		var uniforms = materialProperties.shader.uniforms;
T
tschw 已提交
1574

1575
		if ( ! material.isShaderMaterial &&
1576 1577
			! material.isRawShaderMaterial ||
			material.clipping === true ) {
T
tschw 已提交
1578

T
tschw 已提交
1579
			materialProperties.numClippingPlanes = _clipping.numPlanes;
1580
			materialProperties.numIntersection = _clipping.numIntersection;
T
tschw 已提交
1581
			uniforms.clippingPlanes = _clipping.uniform;
T
tschw 已提交
1582 1583 1584

		}

1585
		materialProperties.fog = fog;
1586

1587
		// store the light setup it was created for
1588

1589
		materialProperties.lightsHash = _lights.hash;
1590

M
Mr.doob 已提交
1591
		if ( material.lights ) {
1592 1593 1594 1595 1596 1597

			// 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;
1598
			uniforms.rectAreaLights.value = _lights.rectArea;
M
Mr.doob 已提交
1599
			uniforms.pointLights.value = _lights.point;
1600 1601
			uniforms.hemisphereLights.value = _lights.hemi;

1602 1603 1604 1605 1606 1607
			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;
1608
			// TODO (abelnation): add area lights shadow info to uniforms
1609

1610 1611
		}

T
tschw 已提交
1612 1613
		var progUniforms = materialProperties.program.getUniforms(),
			uniformsList =
1614
				WebGLUniforms.seqWithValue( progUniforms.seq, uniforms );
A
arose 已提交
1615

T
tschw 已提交
1616
		materialProperties.uniformsList = uniformsList;
A
arose 已提交
1617

M
Mr.doob 已提交
1618
	}
M
Mr.doob 已提交
1619

1620
	function setProgram( camera, fog, material, object ) {
M
Mr.doob 已提交
1621 1622 1623

		_usedTextureUnits = 0;

1624
		var materialProperties = properties.get( material );
1625

T
tschw 已提交
1626 1627 1628 1629 1630
		if ( _clippingEnabled ) {

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

				var useCache =
1631 1632
					camera === _currentCamera &&
					material.id === _currentMaterialId;
T
tschw 已提交
1633 1634 1635 1636

				// we might want to call this function with some ClippingGroup
				// object instead of the material, once it becomes feasible
				// (#8465, #8379)
T
tschw 已提交
1637
				_clipping.setState(
1638 1639
					material.clippingPlanes, material.clipIntersection, material.clipShadows,
					camera, materialProperties, useCache );
T
tschw 已提交
1640 1641 1642 1643 1644

			}

		}

1645
		if ( material.needsUpdate === false ) {
1646

1647
			if ( materialProperties.program === undefined ) {
1648

1649
				material.needsUpdate = true;
1650

1651
			} else if ( material.fog && materialProperties.fog !== fog ) {
1652

M
Mr.doob 已提交
1653
				material.needsUpdate = true;
1654

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

1657
				material.needsUpdate = true;
1658

1659
			} else if ( materialProperties.numClippingPlanes !== undefined &&
1660
				( materialProperties.numClippingPlanes !== _clipping.numPlanes ||
M
Mr.doob 已提交
1661
				materialProperties.numIntersection !== _clipping.numIntersection ) ) {
1662 1663 1664

				material.needsUpdate = true;

1665
			}
1666 1667 1668 1669

		}

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

1671
			initMaterial( material, fog, object );
M
Mr.doob 已提交
1672 1673 1674 1675
			material.needsUpdate = false;

		}

1676
		var refreshProgram = false;
M
Mr.doob 已提交
1677
		var refreshMaterial = false;
1678
		var refreshLights = false;
M
Mr.doob 已提交
1679

1680
		var program = materialProperties.program,
1681
			p_uniforms = program.getUniforms(),
1682
			m_uniforms = materialProperties.shader.uniforms;
M
Mr.doob 已提交
1683

1684
		if ( state.useProgram( program.program ) ) {
M
Mr.doob 已提交
1685

1686
			refreshProgram = true;
M
Mr.doob 已提交
1687
			refreshMaterial = true;
1688
			refreshLights = true;
M
Mr.doob 已提交
1689 1690 1691 1692 1693 1694

		}

		if ( material.id !== _currentMaterialId ) {

			_currentMaterialId = material.id;
1695

M
Mr.doob 已提交
1696 1697 1698 1699
			refreshMaterial = true;

		}

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

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

G
gero3 已提交
1704
			if ( capabilities.logarithmicDepthBuffer ) {
1705

T
tschw 已提交
1706
				p_uniforms.setValue( _gl, 'logDepthBufFC',
1707
					2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
1708 1709 1710

			}

1711
			// Avoid unneeded uniform updates per ArrayCamera's sub-camera
1712

1713
			if ( _currentCamera !== ( _currentArrayCamera || camera ) ) {
1714

1715
				_currentCamera = ( _currentArrayCamera || camera );
1716 1717 1718 1719 1720 1721

				// 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 已提交
1722
				refreshLights = true;		// remains set until update done
1723 1724

			}
M
Mr.doob 已提交
1725

1726 1727 1728
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)

1729
			if ( material.isShaderMaterial ||
1730 1731 1732
				material.isMeshPhongMaterial ||
				material.isMeshStandardMaterial ||
				material.envMap ) {
1733

T
tschw 已提交
1734 1735 1736
				var uCamPos = p_uniforms.map.cameraPosition;

				if ( uCamPos !== undefined ) {
1737

T
tschw 已提交
1738
					uCamPos.setValue( _gl,
1739
						_vector3.setFromMatrixPosition( camera.matrixWorld ) );
1740 1741 1742 1743 1744

				}

			}

1745
			if ( material.isMeshPhongMaterial ||
1746 1747 1748 1749
				material.isMeshLambertMaterial ||
				material.isMeshBasicMaterial ||
				material.isMeshStandardMaterial ||
				material.isShaderMaterial ||
1750
				material.skinning ) {
1751

T
tschw 已提交
1752
				p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );
1753 1754 1755

			}

M
Mr.doob 已提交
1756 1757 1758 1759 1760 1761
		}

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

1762
		if ( material.skinning ) {
M
Mr.doob 已提交
1763

T
tschw 已提交
1764 1765
			p_uniforms.setOptional( _gl, object, 'bindMatrix' );
			p_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );
1766

T
tschw 已提交
1767
			var skeleton = object.skeleton;
1768

T
tschw 已提交
1769
			if ( skeleton ) {
1770

1771 1772
				var bones = skeleton.bones;

1773
				if ( capabilities.floatVertexTextures ) {
M
Mr.doob 已提交
1774

1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799
					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 已提交
1800 1801
					p_uniforms.setValue( _gl, 'boneTexture', skeleton.boneTexture );
					p_uniforms.setValue( _gl, 'boneTextureSize', skeleton.boneTextureSize );
M
Mr.doob 已提交
1802

T
tschw 已提交
1803
				} else {
M
Mr.doob 已提交
1804

T
tschw 已提交
1805
					p_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );
M
Mr.doob 已提交
1806 1807 1808 1809 1810 1811 1812 1813 1814

				}

			}

		}

		if ( refreshMaterial ) {

1815 1816 1817
			p_uniforms.setValue( _gl, 'toneMappingExposure', _this.toneMappingExposure );
			p_uniforms.setValue( _gl, 'toneMappingWhitePoint', _this.toneMappingWhitePoint );

M
Mr.doob 已提交
1818
			if ( material.lights ) {
M
Mr.doob 已提交
1819

1820
				// the current material requires lighting info
M
Mr.doob 已提交
1821

T
tschw 已提交
1822 1823 1824 1825 1826 1827
				// 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 已提交
1828

T
tschw 已提交
1829
				markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
G
gero3 已提交
1830

T
tschw 已提交
1831
			}
G
gero3 已提交
1832

T
tschw 已提交
1833
			// refresh uniforms common to several materials
G
gero3 已提交
1834

T
tschw 已提交
1835
			if ( fog && material.fog ) {
G
gero3 已提交
1836

T
tschw 已提交
1837
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
1838 1839 1840

			}

1841
			if ( material.isMeshBasicMaterial ||
1842 1843 1844
				material.isMeshLambertMaterial ||
				material.isMeshPhongMaterial ||
				material.isMeshStandardMaterial ||
1845
				material.isMeshNormalMaterial ||
1846
				material.isMeshDepthMaterial ) {
M
Mr.doob 已提交
1847 1848 1849 1850 1851 1852 1853

				refreshUniformsCommon( m_uniforms, material );

			}

			// refresh single material specific uniforms

1854
			if ( material.isLineBasicMaterial ) {
M
Mr.doob 已提交
1855 1856 1857

				refreshUniformsLine( m_uniforms, material );

1858
			} else if ( material.isLineDashedMaterial ) {
M
Mr.doob 已提交
1859 1860 1861 1862

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

1863
			} else if ( material.isPointsMaterial ) {
M
Mr.doob 已提交
1864

M
Mr.doob 已提交
1865
				refreshUniformsPoints( m_uniforms, material );
M
Mr.doob 已提交
1866

1867
			} else if ( material.isMeshLambertMaterial ) {
1868 1869 1870

				refreshUniformsLambert( m_uniforms, material );

T
Takahiro 已提交
1871 1872 1873 1874
			} else if ( material.isMeshToonMaterial ) {

				refreshUniformsToon( m_uniforms, material );

1875 1876 1877 1878
			} else if ( material.isMeshPhongMaterial ) {

				refreshUniformsPhong( m_uniforms, material );

1879
			} else if ( material.isMeshPhysicalMaterial ) {
W
WestLangley 已提交
1880 1881 1882

				refreshUniformsPhysical( m_uniforms, material );

1883
			} else if ( material.isMeshStandardMaterial ) {
W
WestLangley 已提交
1884

1885
				refreshUniformsStandard( m_uniforms, material );
W
WestLangley 已提交
1886

1887
			} else if ( material.isMeshDepthMaterial ) {
M
Mr.doob 已提交
1888

1889 1890 1891 1892 1893 1894 1895 1896
				if ( material.displacementMap ) {

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

				}

1897
			} else if ( material.isMeshNormalMaterial ) {
M
Mr.doob 已提交
1898

1899
				refreshUniformsNormal( m_uniforms, material );
M
Mr.doob 已提交
1900 1901 1902

			}

M
Mr.doob 已提交
1903 1904 1905 1906 1907 1908
			// 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 已提交
1909
			WebGLUniforms.upload(
1910
				_gl, materialProperties.uniformsList, m_uniforms, _this );
A
arose 已提交
1911 1912 1913

		}

M
Mr.doob 已提交
1914

T
tschw 已提交
1915
		// common matrices
M
Mr.doob 已提交
1916

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

T
tschw 已提交
1921
		return program;
A
arose 已提交
1922 1923 1924

	}

M
Mr.doob 已提交
1925 1926
	// Uniforms (refresh uniforms objects)

M
Mr.doob 已提交
1927
	function refreshUniformsCommon( uniforms, material ) {
M
Mr.doob 已提交
1928 1929 1930

		uniforms.opacity.value = material.opacity;

1931
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
1932

1933
		if ( material.emissive ) {
M
Mr.doob 已提交
1934

1935
			uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );
M
Mr.doob 已提交
1936 1937 1938

		}

1939 1940 1941
		uniforms.map.value = material.map;
		uniforms.specularMap.value = material.specularMap;
		uniforms.alphaMap.value = material.alphaMap;
M
Mr.doob 已提交
1942

1943 1944 1945 1946 1947 1948 1949
		if ( material.lightMap ) {

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

		}

1950
		if ( material.aoMap ) {
1951

1952 1953
			uniforms.aoMap.value = material.aoMap;
			uniforms.aoMapIntensity.value = material.aoMapIntensity;
1954 1955 1956

		}

M
Mr.doob 已提交
1957
		// uv repeat and offset setting priorities
M
Mr.doob 已提交
1958 1959 1960 1961 1962
		// 1. color map
		// 2. specular map
		// 3. normal map
		// 4. bump map
		// 5. alpha map
1963
		// 6. emissive map
M
Mr.doob 已提交
1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974

		var uvScaleMap;

		if ( material.map ) {

			uvScaleMap = material.map;

		} else if ( material.specularMap ) {

			uvScaleMap = material.specularMap;

1975 1976 1977 1978
		} else if ( material.displacementMap ) {

			uvScaleMap = material.displacementMap;

M
Mr.doob 已提交
1979 1980 1981 1982 1983 1984 1985 1986
		} else if ( material.normalMap ) {

			uvScaleMap = material.normalMap;

		} else if ( material.bumpMap ) {

			uvScaleMap = material.bumpMap;

1987 1988 1989 1990 1991 1992 1993 1994
		} else if ( material.roughnessMap ) {

			uvScaleMap = material.roughnessMap;

		} else if ( material.metalnessMap ) {

			uvScaleMap = material.metalnessMap;

1995 1996 1997 1998
		} else if ( material.alphaMap ) {

			uvScaleMap = material.alphaMap;

1999 2000 2001 2002
		} else if ( material.emissiveMap ) {

			uvScaleMap = material.emissiveMap;

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

		if ( uvScaleMap !== undefined ) {

2007
			// backwards compatibility
2008
			if ( uvScaleMap.isWebGLRenderTarget ) {
M
Mr.doob 已提交
2009 2010 2011 2012 2013

				uvScaleMap = uvScaleMap.texture;

			}

M
Mr.doob 已提交
2014 2015 2016 2017 2018 2019 2020 2021
			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;
2022 2023 2024 2025 2026

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

2029
		uniforms.reflectivity.value = material.reflectivity;
M
Mr.doob 已提交
2030 2031
		uniforms.refractionRatio.value = material.refractionRatio;

M
Mr.doob 已提交
2032
	}
M
Mr.doob 已提交
2033

M
Mr.doob 已提交
2034
	function refreshUniformsLine( uniforms, material ) {
M
Mr.doob 已提交
2035 2036 2037 2038

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

M
Mr.doob 已提交
2039
	}
M
Mr.doob 已提交
2040

M
Mr.doob 已提交
2041
	function refreshUniformsDash( uniforms, material ) {
M
Mr.doob 已提交
2042 2043 2044 2045 2046

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

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

M
Mr.doob 已提交
2049
	function refreshUniformsPoints( uniforms, material ) {
M
Mr.doob 已提交
2050

2051
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
2052
		uniforms.opacity.value = material.opacity;
2053
		uniforms.size.value = material.size * _pixelRatio;
2054
		uniforms.scale.value = _height * 0.5;
M
Mr.doob 已提交
2055 2056 2057

		uniforms.map.value = material.map;

2058 2059 2060 2061 2062 2063 2064 2065 2066
		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 已提交
2067
	}
M
Mr.doob 已提交
2068

M
Mr.doob 已提交
2069
	function refreshUniformsFog( uniforms, fog ) {
M
Mr.doob 已提交
2070 2071 2072

		uniforms.fogColor.value = fog.color;

2073
		if ( fog.isFog ) {
M
Mr.doob 已提交
2074 2075 2076 2077

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

2078
		} else if ( fog.isFogExp2 ) {
M
Mr.doob 已提交
2079 2080 2081 2082 2083

			uniforms.fogDensity.value = fog.density;

		}

M
Mr.doob 已提交
2084
	}
M
Mr.doob 已提交
2085

M
Mr.doob 已提交
2086
	function refreshUniformsLambert( uniforms, material ) {
2087 2088 2089 2090 2091 2092 2093 2094 2095

		if ( material.emissiveMap ) {

			uniforms.emissiveMap.value = material.emissiveMap;

		}

	}

M
Mr.doob 已提交
2096
	function refreshUniformsPhong( uniforms, material ) {
M
Mr.doob 已提交
2097

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

2101
		if ( material.emissiveMap ) {
2102

2103
			uniforms.emissiveMap.value = material.emissiveMap;
2104

2105
		}
M
Mr.doob 已提交
2106

2107 2108 2109 2110
		if ( material.bumpMap ) {

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

2112
		}
M
Mr.doob 已提交
2113

2114 2115 2116 2117 2118 2119
		if ( material.normalMap ) {

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

		}
M
Mr.doob 已提交
2120

2121 2122 2123 2124 2125
		if ( material.displacementMap ) {

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

2127
		}
2128

T
Takahiro 已提交
2129 2130 2131 2132 2133 2134
	}

	function refreshUniformsToon( uniforms, material ) {

		refreshUniformsPhong( uniforms, material );

T
Takahiro 已提交
2135
		if ( material.gradientMap ) {
T
Takahiro 已提交
2136

T
Takahiro 已提交
2137
			uniforms.gradientMap.value = material.gradientMap;
T
Takahiro 已提交
2138 2139 2140

		}

2141 2142
	}

M
Mr.doob 已提交
2143
	function refreshUniformsStandard( uniforms, material ) {
W
WestLangley 已提交
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 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196

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

2199 2200 2201
		uniforms.clearCoat.value = material.clearCoat;
		uniforms.clearCoatRoughness.value = material.clearCoatRoughness;

W
WestLangley 已提交
2202 2203 2204 2205
		refreshUniformsStandard( uniforms, material );

	}

2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231
	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;

		}

	}

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

M
Mr.doob 已提交
2234
	function markUniformsLightsNeedsUpdate( uniforms, value ) {
2235

M
Mr.doob 已提交
2236
		uniforms.ambientLightColor.needsUpdate = value;
2237

B
Ben Houston 已提交
2238 2239 2240
		uniforms.directionalLights.needsUpdate = value;
		uniforms.pointLights.needsUpdate = value;
		uniforms.spotLights.needsUpdate = value;
2241
		uniforms.rectAreaLights.needsUpdate = value;
B
Ben Houston 已提交
2242
		uniforms.hemisphereLights.needsUpdate = value;
2243

M
Mr.doob 已提交
2244
	}
2245

T
tschw 已提交
2246
	// Lighting
M
Mr.doob 已提交
2247

M
Mr.doob 已提交
2248
	function setupShadows( lights ) {
2249 2250 2251 2252 2253 2254 2255 2256 2257

		var lightShadowsLength = 0;

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

			var light = lights[ i ];

			if ( light.castShadow ) {

M
Mr.doob 已提交
2258 2259
				_lights.shadows[ lightShadowsLength ] = light;
				lightShadowsLength ++;
2260 2261 2262 2263 2264 2265 2266 2267 2268

			}

		}

		_lights.shadows.length = lightShadowsLength;

	}

M
Mr.doob 已提交
2269
	function setupLights( lights, camera ) {
M
Mr.doob 已提交
2270

M
Mr.doob 已提交
2271
		var l, ll, light, shadow,
2272 2273 2274 2275 2276
			r = 0, g = 0, b = 0,
			color,
			intensity,
			distance,
			shadowMap,
M
Mr.doob 已提交
2277

2278
			viewMatrix = camera.matrixWorldInverse,
M
Mr.doob 已提交
2279

M
Mr.doob 已提交
2280 2281 2282 2283 2284
			directionalLength = 0,
			pointLength = 0,
			spotLength = 0,
			rectAreaLength = 0,
			hemiLength = 0;
M
Mr.doob 已提交
2285 2286 2287 2288 2289 2290 2291 2292 2293

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

			light = lights[ l ];

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

2294
			shadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null;
2295

2296
			if ( light.isAmbientLight ) {
M
Mr.doob 已提交
2297

2298 2299 2300
				r += color.r * intensity;
				g += color.g * intensity;
				b += color.b * intensity;
M
Mr.doob 已提交
2301

2302
			} else if ( light.isDirectionalLight ) {
M
Mr.doob 已提交
2303

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

2306
				uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
M
Mr.doob 已提交
2307
				uniforms.direction.setFromMatrixPosition( light.matrixWorld );
2308
				_vector3.setFromMatrixPosition( light.target.matrixWorld );
M
Mr.doob 已提交
2309 2310 2311
				uniforms.direction.sub( _vector3 );
				uniforms.direction.transformDirection( viewMatrix );

2312
				uniforms.shadow = light.castShadow;
M
Mr.doob 已提交
2313

2314
				if ( light.castShadow ) {
M
Mr.doob 已提交
2315

M
Mr.doob 已提交
2316 2317 2318 2319 2320
					shadow = light.shadow;

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

2322 2323
				}

2324
				_lights.directionalShadowMap[ directionalLength ] = shadowMap;
2325
				_lights.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;
M
Mr.doob 已提交
2326 2327 2328
				_lights.directional[ directionalLength ] = uniforms;

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

2330
			} else if ( light.isSpotLight ) {
M
Mr.doob 已提交
2331

M
Mr.doob 已提交
2332
				var uniforms = lightCache.get( light );
M
Mr.doob 已提交
2333 2334 2335

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

M
Mr.doob 已提交
2337 2338 2339 2340 2341 2342 2343 2344
				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 );

2345 2346
				uniforms.coneCos = Math.cos( light.angle );
				uniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );
M
Mr.doob 已提交
2347
				uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;
M
Mr.doob 已提交
2348

2349
				uniforms.shadow = light.castShadow;
M
Mr.doob 已提交
2350

2351 2352
				if ( light.castShadow ) {

M
Mr.doob 已提交
2353 2354 2355 2356 2357
					shadow = light.shadow;

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

2359 2360
				}

2361
				_lights.spotShadowMap[ spotLength ] = shadowMap;
2362
				_lights.spotShadowMatrix[ spotLength ] = light.shadow.matrix;
M
Mr.doob 已提交
2363 2364 2365
				_lights.spot[ spotLength ] = uniforms;

				spotLength ++;
2366

2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396
			} 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 已提交
2397 2398 2399
				_lights.rectArea[ rectAreaLength ] = uniforms;

				rectAreaLength ++;
2400

2401
			} else if ( light.isPointLight ) {
M
Mr.doob 已提交
2402

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

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

M
Mr.doob 已提交
2408 2409
				uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
				uniforms.distance = light.distance;
M
Mr.doob 已提交
2410 2411
				uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;

2412
				uniforms.shadow = light.castShadow;
2413

M
Mr.doob 已提交
2414
				if ( light.castShadow ) {
2415

M
Mr.doob 已提交
2416 2417 2418 2419 2420
					shadow = light.shadow;

					uniforms.shadowBias = shadow.bias;
					uniforms.shadowRadius = shadow.radius;
					uniforms.shadowMapSize = shadow.mapSize;
2421 2422
					uniforms.shadowCameraNear = shadow.camera.near;
					uniforms.shadowCameraFar = shadow.camera.far;
2423 2424

				}
2425

2426
				_lights.pointShadowMap[ pointLength ] = shadowMap;
J
jaxry 已提交
2427
				_lights.pointShadowMatrix[ pointLength ] = light.shadow.matrix;
M
Mr.doob 已提交
2428 2429 2430
				_lights.point[ pointLength ] = uniforms;

				pointLength ++;
2431

2432
			} else if ( light.isHemisphereLight ) {
M
Mr.doob 已提交
2433

M
Mr.doob 已提交
2434
				var uniforms = lightCache.get( light );
M
Mr.doob 已提交
2435 2436 2437 2438

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

M
Mr.doob 已提交
2440 2441
				uniforms.skyColor.copy( light.color ).multiplyScalar( intensity );
				uniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );
M
Mr.doob 已提交
2442

M
Mr.doob 已提交
2443 2444 2445
				_lights.hemi[ hemiLength ] = uniforms;

				hemiLength ++;
M
Mr.doob 已提交
2446 2447 2448 2449 2450

			}

		}

M
Mr.doob 已提交
2451 2452 2453
		_lights.ambient[ 0 ] = r;
		_lights.ambient[ 1 ] = g;
		_lights.ambient[ 2 ] = b;
M
Mr.doob 已提交
2454

M
Mr.doob 已提交
2455 2456
		_lights.directional.length = directionalLength;
		_lights.spot.length = spotLength;
2457
		_lights.rectArea.length = rectAreaLength;
2458
		_lights.point.length = pointLength;
M
Mr.doob 已提交
2459
		_lights.hemi.length = hemiLength;
2460

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

M
Mr.doob 已提交
2464
	}
M
Mr.doob 已提交
2465 2466 2467 2468 2469

	// GL state setting

	this.setFaceCulling = function ( cullFace, frontFaceDirection ) {

T
tschw 已提交
2470
		state.setCullFace( cullFace );
R
Rich Harris 已提交
2471
		state.setFlipSided( frontFaceDirection === FrontFaceDirectionCW );
M
Mr.doob 已提交
2472 2473 2474 2475 2476

	};

	// Textures

T
tschw 已提交
2477 2478 2479 2480 2481 2482
	function allocTextureUnit() {

		var textureUnit = _usedTextureUnits;

		if ( textureUnit >= capabilities.maxTextures ) {

M
Mugen87 已提交
2483
			console.warn( 'THREE.WebGLRenderer: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );
T
tschw 已提交
2484 2485 2486 2487 2488 2489 2490 2491 2492

		}

		_usedTextureUnits += 1;

		return textureUnit;

	}

2493
	this.allocTextureUnit = allocTextureUnit;
T
tschw 已提交
2494

2495
	// this.setTexture2D = setTexture2D;
M
Mr.doob 已提交
2496
	this.setTexture2D = ( function () {
T
tschw 已提交
2497

2498
		var warned = false;
T
tschw 已提交
2499

2500
		// backwards compatibility: peel texture.texture
W
WestLangley 已提交
2501
		return function setTexture2D( texture, slot ) {
T
tschw 已提交
2502

T
Takahiro 已提交
2503
			if ( texture && texture.isWebGLRenderTarget ) {
T
tschw 已提交
2504

2505
				if ( ! warned ) {
T
tschw 已提交
2506

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

2510
				}
T
tschw 已提交
2511

2512
				texture = texture.texture;
T
tschw 已提交
2513

2514
			}
T
tschw 已提交
2515

2516
			textures.setTexture2D( texture, slot );
T
tschw 已提交
2517

2518
		};
T
tschw 已提交
2519

2520
	}() );
T
tschw 已提交
2521

M
Mr.doob 已提交
2522
	this.setTexture = ( function () {
2523 2524 2525

		var warned = false;

W
WestLangley 已提交
2526
		return function setTexture( texture, slot ) {
2527 2528 2529 2530 2531 2532 2533 2534

			if ( ! warned ) {

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

			}

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

		};

	}() );

M
Mr.doob 已提交
2541
	this.setTextureCube = ( function () {
2542 2543 2544

		var warned = false;

W
WestLangley 已提交
2545
		return function setTextureCube( texture, slot ) {
2546 2547

			// backwards compatibility: peel texture.texture
T
Takahiro 已提交
2548
			if ( texture && texture.isWebGLRenderTargetCube ) {
2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562

				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 已提交
2563
			if ( ( texture && texture.isCubeTexture ) ||
2564
				( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {
2565 2566 2567 2568

				// CompressedTexture can have Array in image :/

				// this function alone should take care of cube textures
2569
				textures.setTextureCube( texture, slot );
2570 2571 2572 2573 2574

			} else {

				// assumed: texture property of THREE.WebGLRenderTargetCube

2575
				textures.setTextureCubeDynamic( texture, slot );
2576 2577 2578 2579 2580 2581

			}

		};

	}() );
T
tschw 已提交
2582

2583
	this.getRenderTarget = function () {
2584 2585 2586

		return _currentRenderTarget;

M
Michael Herzog 已提交
2587
	};
2588

2589
	this.setRenderTarget = function ( renderTarget ) {
M
Mr.doob 已提交
2590

2591 2592
		_currentRenderTarget = renderTarget;

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

2595
			textures.setupRenderTarget( renderTarget );
M
Mr.doob 已提交
2596 2597 2598

		}

M
Mr.doob 已提交
2599
		var framebuffer = null;
M
Mr.doob 已提交
2600
		var isCube = false;
M
Mr.doob 已提交
2601 2602 2603

		if ( renderTarget ) {

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

M
Mr.doob 已提交
2606
			if ( renderTarget.isWebGLRenderTargetCube ) {
M
Mr.doob 已提交
2607

M
Mr.doob 已提交
2608
				framebuffer = __webglFramebuffer[ renderTarget.activeCubeFace ];
M
Mr.doob 已提交
2609
				isCube = true;
M
Mr.doob 已提交
2610 2611 2612

			} else {

M
Mr.doob 已提交
2613
				framebuffer = __webglFramebuffer;
M
Mr.doob 已提交
2614 2615 2616

			}

M
Mr.doob 已提交
2617
			_currentViewport.copy( renderTarget.viewport );
2618 2619
			_currentScissor.copy( renderTarget.scissor );
			_currentScissorTest = renderTarget.scissorTest;
2620

M
Mr.doob 已提交
2621 2622
		} else {

M
Mr.doob 已提交
2623
			_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );
2624
			_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );
2625
			_currentScissorTest = _scissorTest;
2626

M
Mr.doob 已提交
2627 2628
		}

M
Mr.doob 已提交
2629
		if ( _currentFramebuffer !== framebuffer ) {
M
Mr.doob 已提交
2630 2631 2632 2633 2634 2635

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

		}

M
Mr.doob 已提交
2636
		state.viewport( _currentViewport );
2637 2638
		state.scissor( _currentScissor );
		state.setScissorTest( _currentScissorTest );
2639

M
Mr.doob 已提交
2640 2641 2642
		if ( isCube ) {

			var textureProperties = properties.get( renderTarget.texture );
2643
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );
M
Mr.doob 已提交
2644 2645 2646

		}

M
Mr.doob 已提交
2647 2648
	};

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

0
06wj 已提交
2651
		if ( ! ( renderTarget && renderTarget.isWebGLRenderTarget ) ) {
2652

2653
			console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
G
gero3 已提交
2654
			return;
2655

G
gero3 已提交
2656
		}
2657

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

M
Mr.doob 已提交
2660
		if ( framebuffer ) {
2661

G
gero3 已提交
2662
			var restore = false;
2663

M
Mr.doob 已提交
2664
			if ( framebuffer !== _currentFramebuffer ) {
2665

M
Mr.doob 已提交
2666
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
2667

G
gero3 已提交
2668
				restore = true;
2669

G
gero3 已提交
2670
			}
2671

M
Mr.doob 已提交
2672
			try {
2673

M
Mr.doob 已提交
2674
				var texture = renderTarget.texture;
M
Mr.doob 已提交
2675 2676
				var textureFormat = texture.format;
				var textureType = texture.type;
2677

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

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

M
Mr.doob 已提交
2683
				}
2684

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

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

M
Mr.doob 已提交
2692
				}
2693

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

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

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

M
Mr.doob 已提交
2700
						_gl.readPixels( x, y, width, height, paramThreeToGL( textureFormat ), paramThreeToGL( textureType ), buffer );
2701 2702

					}
2703

M
Mr.doob 已提交
2704
				} else {
M
Mr.doob 已提交
2705

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

				}
M
Mr.doob 已提交
2709

M
Mr.doob 已提交
2710
			} finally {
M
Mr.doob 已提交
2711

M
Mr.doob 已提交
2712 2713 2714
				if ( restore ) {

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

M
Mr.doob 已提交
2716 2717 2718
				}

			}
M
Mr.doob 已提交
2719 2720 2721

		}

M
Mr.doob 已提交
2722 2723
	};

M
Mr.doob 已提交
2724 2725
	// Map three.js constants to WebGL constants

M
Mr.doob 已提交
2726
	function paramThreeToGL( p ) {
M
Mr.doob 已提交
2727

2728 2729
		var extension;

R
Rich Harris 已提交
2730 2731 2732
		if ( p === RepeatWrapping ) return _gl.REPEAT;
		if ( p === ClampToEdgeWrapping ) return _gl.CLAMP_TO_EDGE;
		if ( p === MirroredRepeatWrapping ) return _gl.MIRRORED_REPEAT;
M
Mr.doob 已提交
2733

R
Rich Harris 已提交
2734 2735 2736
		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 已提交
2737

R
Rich Harris 已提交
2738 2739 2740
		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 已提交
2741

R
Rich Harris 已提交
2742 2743 2744 2745
		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 已提交
2746

R
Rich Harris 已提交
2747 2748 2749 2750 2751 2752
		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 已提交
2753

2754
		if ( p === HalfFloatType ) {
2755

2756
			extension = extensions.get( 'OES_texture_half_float' );
2757

2758
			if ( extension !== null ) return extension.HALF_FLOAT_OES;
2759 2760 2761

		}

R
Rich Harris 已提交
2762 2763 2764 2765 2766 2767
		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;
2768
		if ( p === DepthStencilFormat ) return _gl.DEPTH_STENCIL;
M
Mr.doob 已提交
2769

R
Rich Harris 已提交
2770 2771 2772
		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 已提交
2773

R
Rich Harris 已提交
2774 2775 2776 2777 2778 2779 2780 2781
		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 已提交
2782

R
Rich Harris 已提交
2783 2784 2785
		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 已提交
2786

2787 2788
		if ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format ||
			p === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) {
M
Mr.doob 已提交
2789

2790
			extension = extensions.get( 'WEBGL_compressed_texture_s3tc' );
2791

2792 2793 2794 2795 2796 2797 2798 2799
			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 已提交
2800 2801 2802

		}

2803
		if ( p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format ||
2804
			p === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format ) {
2805

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

2808 2809 2810 2811 2812 2813 2814 2815
			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 已提交
2816 2817 2818

		}

2819
		if ( p === RGB_ETC1_Format ) {
2820

2821
			extension = extensions.get( 'WEBGL_compressed_texture_etc1' );
2822

2823
			if ( extension !== null ) return extension.COMPRESSED_RGB_ETC1_WEBGL;
2824 2825 2826

		}

2827 2828 2829
		if ( p === MinEquation || p === MaxEquation ) {

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

2831
			if ( extension !== null ) {
2832

2833 2834 2835 2836
				if ( p === MinEquation ) return extension.MIN_EXT;
				if ( p === MaxEquation ) return extension.MAX_EXT;

			}
2837 2838 2839

		}

2840
		if ( p === UnsignedInt248Type ) {
2841

2842
			extension = extensions.get( 'WEBGL_depth_texture' );
2843

2844
			if ( extension !== null ) return extension.UNSIGNED_INT_24_8_WEBGL;
2845 2846 2847

		}

M
Mr.doob 已提交
2848 2849
		return 0;

M
Mr.doob 已提交
2850
	}
M
Mr.doob 已提交
2851

M
Mr.doob 已提交
2852
}
R
Rich Harris 已提交
2853

T
Tristan VALCKE 已提交
2854

2855
export { WebGLRenderer };