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

M
Mr.doob 已提交
34 35 36 37 38
/**
 * @author supereggbert / http://www.paulbrunt.co.uk/
 * @author mrdoob / http://mrdoob.com/
 * @author alteredq / http://alteredqualia.com/
 * @author szimek / https://github.com/szimek/
T
tschw 已提交
39
 * @author tschw
M
Mr.doob 已提交
40 41
 */

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

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

	parameters = parameters || {};

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

51 52 53 54 55 56
		_alpha = parameters.alpha !== undefined ? parameters.alpha : false,
		_depth = parameters.depth !== undefined ? parameters.depth : true,
		_stencil = parameters.stencil !== undefined ? parameters.stencil : true,
		_antialias = parameters.antialias !== undefined ? parameters.antialias : false,
		_premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,
		_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false;
M
Mr.doob 已提交
57

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

60
	var currentRenderList = null;
61

62 63
	var morphInfluences = new Float32Array( 8 );

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

M
Mr.doob 已提交
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
	// public properties

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

	// clearing

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

	// scene graph

	this.sortObjects = true;

T
tschw 已提交
83 84 85 86 87
	// user-defined clipping

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

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

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

94 95
	// physical lights

96
	this.physicallyCorrectLights = false;
97

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

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

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

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

	// internal properties

	var _this = this,

113 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.shading === FlatShading ) {
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

M
Mr.doob 已提交
954 955 956
					var buffer = attribute.buffer;
					var type = attribute.type;
					var bytesPerElement = attribute.bytesPerElement;
957

A
aardgoose 已提交
958
					if ( geometryAttribute.isInterleavedBufferAttribute ) {
959

M
Mr.doob 已提交
960 961 962 963
						var data = geometryAttribute.data;
						var stride = data.stride;
						var offset = geometryAttribute.offset;

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

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

M
Mr.doob 已提交
968
							if ( geometry.maxInstancedCount === undefined ) {
969

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

M
Mr.doob 已提交
972
							}
B
Ben Adams 已提交
973

M
Mr.doob 已提交
974
						} else {
B
Ben Adams 已提交
975

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

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

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

M
Mr.doob 已提交
983
					} else {
B
Ben Adams 已提交
984

A
aardgoose 已提交
985
						if ( geometryAttribute.isInstancedBufferAttribute ) {
B
Ben Adams 已提交
986

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

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

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

M
Mr.doob 已提交
993
							}
B
Ben Adams 已提交
994

M
Mr.doob 已提交
995 996 997 998
						} else {

							state.enableAttribute( programAttribute );

M
Mr.doob 已提交
999
						}
B
Ben Adams 已提交
1000

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

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

1006 1007
				} else if ( materialDefaultAttributeValues !== undefined ) {

T
tschw 已提交
1008
					var value = materialDefaultAttributeValues[ name ];
1009

1010
					if ( value !== undefined ) {
M
Mr.doob 已提交
1011

1012
						switch ( value.length ) {
M
Mr.doob 已提交
1013

1014 1015 1016
							case 2:
								_gl.vertexAttrib2fv( programAttribute, value );
								break;
M
Mr.doob 已提交
1017

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

1022 1023 1024
							case 4:
								_gl.vertexAttrib4fv( programAttribute, value );
								break;
1025

1026 1027
							default:
								_gl.vertexAttrib1fv( programAttribute, value );
1028 1029

						}
M
Mr.doob 已提交
1030 1031 1032 1033 1034 1035 1036 1037

					}

				}

			}

		}
1038

1039
		state.disableUnusedAttributes();
1040

M
Mr.doob 已提交
1041 1042
	}

M
Mr.doob 已提交
1043
	// Compile
M
Mr.doob 已提交
1044

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

M
Mr.doob 已提交
1047
		lights = [];
1048

M
Mr.doob 已提交
1049
		scene.traverse( function ( object ) {
G
gero3 已提交
1050 1051

			if ( object.isLight ) {
M
Mr.doob 已提交
1052 1053 1054

				lights.push( object );

G
gero3 已提交
1055
			}
M
Mr.doob 已提交
1056 1057 1058 1059 1060 1061 1062 1063 1064

		} );

		setupLights( lights, camera );

		scene.traverse( function ( object ) {

			if ( object.material ) {

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

G
gero3 已提交
1067
					for ( var i = 0; i < object.material.length; i ++ ) {
M
Mr.doob 已提交
1068 1069 1070

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

G
gero3 已提交
1071
					}
M
Mr.doob 已提交
1072

G
gero3 已提交
1073
				} else {
M
Mr.doob 已提交
1074 1075 1076

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

G
gero3 已提交
1077
				}
M
Mr.doob 已提交
1078

G
gero3 已提交
1079
			}
M
Mr.doob 已提交
1080 1081

		} );
G
gero3 已提交
1082 1083

	};
1084

M
Mr.doob 已提交
1085 1086
	// Rendering

1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100
	this.animate = function ( callback ) {

		function onFrame() {

			callback();

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

		}

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

	};

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

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

1105
			console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );
M
Mr.doob 已提交
1106 1107 1108 1109
			return;

		}

1110 1111
		if ( _isContextLost ) return;

M
Mr.doob 已提交
1112 1113
		// reset caching for this frame

1114
		_currentGeometryProgram = '';
1115
		_currentMaterialId = - 1;
1116
		_currentCamera = null;
M
Mr.doob 已提交
1117 1118 1119

		// update scene graph

1120
		if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
M
Mr.doob 已提交
1121 1122 1123

		// update camera matrices and frustum

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

1126 1127 1128 1129 1130 1131
		if ( vr.enabled ) {

			camera = vr.getCamera( camera );

		}

M
Mr.doob 已提交
1132 1133 1134
		_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
		_frustum.setFromMatrix( _projScreenMatrix );

M
Mr.doob 已提交
1135
		lights.length = 0;
M
Mr.doob 已提交
1136 1137 1138
		sprites.length = 0;
		lensFlares.length = 0;

T
tschw 已提交
1139
		_localClippingEnabled = this.localClippingEnabled;
M
Mr.doob 已提交
1140
		_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );
T
tschw 已提交
1141

1142 1143 1144
		currentRenderList = renderLists.get( scene, camera );
		currentRenderList.init();

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

1147
		currentRenderList.finish();
1148

M
Mr.doob 已提交
1149
		if ( _this.sortObjects === true ) {
1150

1151
			currentRenderList.sort();
M
Mr.doob 已提交
1152

1153 1154
		}

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

T
tschw 已提交
1157
		if ( _clippingEnabled ) _clipping.beginShadows();
T
tschw 已提交
1158

1159 1160
		setupShadows( lights );

M
Mr.doob 已提交
1161
		shadowMap.render( scene, camera );
M
Mr.doob 已提交
1162

1163 1164
		setupLights( lights, camera );

T
tschw 已提交
1165
		if ( _clippingEnabled ) _clipping.endShadows();
T
tschw 已提交
1166

M
Mr.doob 已提交
1167 1168
		//

M
Mr.doob 已提交
1169
		_infoRender.frame ++;
1170 1171 1172 1173
		_infoRender.calls = 0;
		_infoRender.vertices = 0;
		_infoRender.faces = 0;
		_infoRender.points = 0;
M
Mr.doob 已提交
1174

1175 1176 1177 1178 1179 1180
		if ( renderTarget === undefined ) {

			renderTarget = null;

		}

M
Mr.doob 已提交
1181 1182
		this.setRenderTarget( renderTarget );

M
Mr.doob 已提交
1183 1184
		//

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

1187
		// render scene
M
Mr.doob 已提交
1188

1189 1190
		var opaqueObjects = currentRenderList.opaque;
		var transparentObjects = currentRenderList.transparent;
M
Mr.doob 已提交
1191

1192
		if ( scene.overrideMaterial ) {
M
Mr.doob 已提交
1193

1194
			var overrideMaterial = scene.overrideMaterial;
1195

1196 1197
			if ( opaqueObjects.length ) renderObjects( opaqueObjects, scene, camera, overrideMaterial );
			if ( transparentObjects.length ) renderObjects( transparentObjects, scene, camera, overrideMaterial );
M
Mr.doob 已提交
1198

1199
		} else {
M
Mr.doob 已提交
1200

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

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

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

1207
			if ( transparentObjects.length ) renderObjects( transparentObjects, scene, camera );
M
Mr.doob 已提交
1208 1209 1210 1211 1212

		}

		// custom render plugins (post pass)

M
Mr.doob 已提交
1213
		spritePlugin.render( scene, camera );
1214
		lensFlarePlugin.render( scene, camera, _currentViewport );
M
Mr.doob 已提交
1215 1216 1217

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

M
Mr.doob 已提交
1218 1219
		if ( renderTarget ) {

1220
			textures.updateRenderTargetMipmap( renderTarget );
M
Mr.doob 已提交
1221 1222 1223

		}

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

1226 1227 1228
		state.buffers.depth.setTest( true );
		state.buffers.depth.setMask( true );
		state.buffers.color.setMask( true );
M
Mr.doob 已提交
1229

M
Mr.doob 已提交
1230 1231 1232 1233 1234
		if ( vr.enabled ) {

			vr.submitFrame();

		}
M
Mr.doob 已提交
1235

M
Mr.doob 已提交
1236 1237 1238
		// _gl.finish();

	};
M
Mr.doob 已提交
1239

1240
	/*
M
Mr.doob 已提交
1241 1242
	// TODO Duplicated code (Frustum)

1243 1244
	var _sphere = new Sphere();

T
tschw 已提交
1245 1246 1247 1248 1249 1250 1251
	function isObjectViewable( object ) {

		var geometry = object.geometry;

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

M
Mr.doob 已提交
1252
		_sphere.copy( geometry.boundingSphere ).
1253
		applyMatrix4( object.matrixWorld );
M
Mr.doob 已提交
1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269

		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 已提交
1270 1271

		if ( ! _frustum.intersectsSphere( sphere ) ) return false;
T
tschw 已提交
1272 1273 1274 1275

		var numPlanes = _clipping.numPlanes;

		if ( numPlanes === 0 ) return true;
T
tschw 已提交
1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287

		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 已提交
1288
		} while ( ++ i !== numPlanes );
T
tschw 已提交
1289 1290 1291 1292

		return true;

	}
1293
	*/
T
tschw 已提交
1294

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

M
Mr.doob 已提交
1297
		if ( ! object.visible ) return;
M
Mr.doob 已提交
1298

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

1301
		if ( visible ) {
1302

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

1305
				lights.push( object );
M
Mr.doob 已提交
1306

1307
			} else if ( object.isSprite ) {
M
Mr.doob 已提交
1308

1309
				if ( ! object.frustumCulled || _frustum.intersectsSprite( object ) ) {
1310

1311
					sprites.push( object );
M
Mr.doob 已提交
1312

1313
				}
M
Mr.doob 已提交
1314

1315
			} else if ( object.isLensFlare ) {
M
Mr.doob 已提交
1316

1317
				lensFlares.push( object );
M
Mr.doob 已提交
1318

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

1321
				if ( sortObjects ) {
M
Mr.doob 已提交
1322

1323 1324
					_vector3.setFromMatrixPosition( object.matrixWorld )
						.applyMatrix4( _projScreenMatrix );
M
Mr.doob 已提交
1325

1326
				}
M
Mr.doob 已提交
1327

1328
				currentRenderList.push( object, null, object.material, _vector3.z, null );
1329

1330
			} else if ( object.isMesh || object.isLine || object.isPoints ) {
1331

1332
				if ( object.isSkinnedMesh ) {
1333

1334
					object.skeleton.update();
1335

1336
				}
1337

1338
				if ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) {
1339

1340 1341 1342 1343 1344 1345
					if ( sortObjects ) {

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

					}
1346

1347 1348
					var geometry = objects.update( object );
					var material = object.material;
1349

1350
					if ( Array.isArray( material ) ) {
1351

1352
						var groups = geometry.groups;
1353

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

1356 1357
							var group = groups[ i ];
							var groupMaterial = material[ group.materialIndex ];
1358

1359
							if ( groupMaterial && groupMaterial.visible ) {
1360

1361 1362 1363
								currentRenderList.push( object, geometry, groupMaterial, _vector3.z, group );

							}
M
Mr.doob 已提交
1364

M
Mr.doob 已提交
1365
						}
M
Mr.doob 已提交
1366

1367
					} else if ( material.visible ) {
1368

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

1371
					}
M
Mr.doob 已提交
1372

1373
				}
M
Mr.doob 已提交
1374

1375
			}
M
Mr.doob 已提交
1376

M
Mr.doob 已提交
1377
		}
M
Mr.doob 已提交
1378

M
Mr.doob 已提交
1379
		var children = object.children;
M
Mr.doob 已提交
1380

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

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

1385
		}
1386

1387
	}
M
Mr.doob 已提交
1388

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

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

1393
			var renderItem = renderList[ i ];
1394

1395 1396 1397 1398
			var object = renderItem.object;
			var geometry = renderItem.geometry;
			var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;
			var group = renderItem.group;
1399

1400
			if ( camera.isArrayCamera ) {
M
Mr.doob 已提交
1401

1402 1403
				_currentArrayCamera = camera;

1404
				var cameras = camera.cameras;
1405

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

1408
					var camera2 = cameras[ j ];
M
Mr.doob 已提交
1409

1410
					if ( object.layers.test( camera2.layers ) ) {
1411

1412
						var bounds = camera2.bounds;
M
Mr.doob 已提交
1413

1414 1415 1416 1417 1418
						var x = bounds.x * _width;
						var y = bounds.y * _height;
						var width = bounds.z * _width;
						var height = bounds.w * _height;

1419 1420
						state.viewport( _currentViewport.set( x, y, width, height ).multiplyScalar( _pixelRatio ) );
						state.scissor( _currentScissor.set( x, y, width, height ).multiplyScalar( _pixelRatio ) );
1421
						state.setScissorTest( true );
1422 1423 1424 1425

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

					}
M
Mr.doob 已提交
1426

1427
				}
1428

1429
			} else {
M
Mr.doob 已提交
1430

1431 1432
				_currentArrayCamera = null;

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

1435
			}
M
Mr.doob 已提交
1436

1437
		}
M
Mr.doob 已提交
1438

1439
	}
G
gero3 已提交
1440

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

1443 1444
		object.onBeforeRender( _this, scene, camera, geometry, material, group );

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

M
Mr.doob 已提交
1466 1467
	}

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

1470
		var materialProperties = properties.get( material );
G
gero3 已提交
1471

T
tschw 已提交
1472
		var parameters = programCache.getParameters(
1473
			material, _lights, fog, _clipping.numPlanes, _clipping.numIntersection, object );
T
tschw 已提交
1474

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

1477
		var program = materialProperties.program;
T
tschw 已提交
1478
		var programChange = true;
1479

1480
		if ( program === undefined ) {
B
Ben Adams 已提交
1481

M
Mr.doob 已提交
1482 1483
			// new material
			material.addEventListener( 'dispose', onMaterialDispose );
B
Ben Adams 已提交
1484

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

M
Mr.doob 已提交
1487
			// changed glsl or parameters
1488
			releaseMaterialProgramReference( material );
B
Ben Adams 已提交
1489

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

T
tschw 已提交
1492
			// same glsl and uniform list
T
tschw 已提交
1493 1494
			return;

T
tschw 已提交
1495
		} else {
B
Ben Adams 已提交
1496

T
tschw 已提交
1497 1498
			// only rebuild uniform list
			programChange = false;
B
Ben Adams 已提交
1499 1500 1501

		}

1502
		if ( programChange ) {
B
Ben Adams 已提交
1503

1504
			if ( parameters.shaderID ) {
B
Ben Adams 已提交
1505

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

1508
				materialProperties.shader = {
1509
					name: material.type,
1510
					uniforms: UniformsUtils.clone( shader.uniforms ),
1511 1512 1513
					vertexShader: shader.vertexShader,
					fragmentShader: shader.fragmentShader
				};
B
Ben Adams 已提交
1514

1515
			} else {
B
Ben Adams 已提交
1516

1517
				materialProperties.shader = {
1518 1519 1520 1521 1522
					name: material.type,
					uniforms: material.uniforms,
					vertexShader: material.vertexShader,
					fragmentShader: material.fragmentShader
				};
G
gero3 已提交
1523

1524
			}
G
gero3 已提交
1525

1526
			material.onBeforeCompile( materialProperties.shader );
G
gero3 已提交
1527

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

1530 1531
			materialProperties.program = program;
			material.program = program;
1532 1533 1534

		}

1535
		var programAttributes = program.getAttributes();
M
Mr.doob 已提交
1536 1537 1538 1539 1540

		if ( material.morphTargets ) {

			material.numSupportedMorphTargets = 0;

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

1543
				if ( programAttributes[ 'morphTarget' + i ] >= 0 ) {
M
Mr.doob 已提交
1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556

					material.numSupportedMorphTargets ++;

				}

			}

		}

		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

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

1559
				if ( programAttributes[ 'morphNormal' + i ] >= 0 ) {
M
Mr.doob 已提交
1560 1561 1562 1563 1564 1565 1566 1567 1568

					material.numSupportedMorphNormals ++;

				}

			}

		}

1569
		var uniforms = materialProperties.shader.uniforms;
T
tschw 已提交
1570

1571
		if ( ! material.isShaderMaterial &&
1572 1573
			! material.isRawShaderMaterial ||
			material.clipping === true ) {
T
tschw 已提交
1574

T
tschw 已提交
1575
			materialProperties.numClippingPlanes = _clipping.numPlanes;
1576
			materialProperties.numIntersection = _clipping.numIntersection;
T
tschw 已提交
1577
			uniforms.clippingPlanes = _clipping.uniform;
T
tschw 已提交
1578 1579 1580

		}

1581
		materialProperties.fog = fog;
1582

1583
		// store the light setup it was created for
1584

1585
		materialProperties.lightsHash = _lights.hash;
1586

M
Mr.doob 已提交
1587
		if ( material.lights ) {
1588 1589 1590 1591 1592 1593

			// 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;
1594
			uniforms.rectAreaLights.value = _lights.rectArea;
M
Mr.doob 已提交
1595
			uniforms.pointLights.value = _lights.point;
1596 1597
			uniforms.hemisphereLights.value = _lights.hemi;

1598 1599 1600 1601 1602 1603
			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;
1604
			// TODO (abelnation): add area lights shadow info to uniforms
1605

1606 1607
		}

T
tschw 已提交
1608 1609
		var progUniforms = materialProperties.program.getUniforms(),
			uniformsList =
1610
				WebGLUniforms.seqWithValue( progUniforms.seq, uniforms );
A
arose 已提交
1611

T
tschw 已提交
1612
		materialProperties.uniformsList = uniformsList;
A
arose 已提交
1613

M
Mr.doob 已提交
1614
	}
M
Mr.doob 已提交
1615

1616
	function setProgram( camera, fog, material, object ) {
M
Mr.doob 已提交
1617 1618 1619

		_usedTextureUnits = 0;

1620
		var materialProperties = properties.get( material );
1621

T
tschw 已提交
1622 1623 1624 1625 1626
		if ( _clippingEnabled ) {

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

				var useCache =
1627 1628
					camera === _currentCamera &&
					material.id === _currentMaterialId;
T
tschw 已提交
1629 1630 1631 1632

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

			}

		}

1641
		if ( material.needsUpdate === false ) {
1642

1643
			if ( materialProperties.program === undefined ) {
1644

1645
				material.needsUpdate = true;
1646

1647
			} else if ( material.fog && materialProperties.fog !== fog ) {
1648

M
Mr.doob 已提交
1649
				material.needsUpdate = true;
1650

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

1653
				material.needsUpdate = true;
1654

1655
			} else if ( materialProperties.numClippingPlanes !== undefined &&
1656
				( materialProperties.numClippingPlanes !== _clipping.numPlanes ||
M
Mr.doob 已提交
1657
				materialProperties.numIntersection !== _clipping.numIntersection ) ) {
1658 1659 1660

				material.needsUpdate = true;

1661
			}
1662 1663 1664 1665

		}

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

1667
			initMaterial( material, fog, object );
M
Mr.doob 已提交
1668 1669 1670 1671
			material.needsUpdate = false;

		}

1672
		var refreshProgram = false;
M
Mr.doob 已提交
1673
		var refreshMaterial = false;
1674
		var refreshLights = false;
M
Mr.doob 已提交
1675

1676
		var program = materialProperties.program,
1677
			p_uniforms = program.getUniforms(),
1678
			m_uniforms = materialProperties.shader.uniforms;
M
Mr.doob 已提交
1679

1680
		if ( state.useProgram( program.program ) ) {
M
Mr.doob 已提交
1681

1682
			refreshProgram = true;
M
Mr.doob 已提交
1683
			refreshMaterial = true;
1684
			refreshLights = true;
M
Mr.doob 已提交
1685 1686 1687 1688 1689 1690

		}

		if ( material.id !== _currentMaterialId ) {

			_currentMaterialId = material.id;
1691

M
Mr.doob 已提交
1692 1693 1694 1695
			refreshMaterial = true;

		}

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

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

G
gero3 已提交
1700
			if ( capabilities.logarithmicDepthBuffer ) {
1701

T
tschw 已提交
1702
				p_uniforms.setValue( _gl, 'logDepthBufFC',
1703
					2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
1704 1705 1706

			}

1707
			// Avoid unneeded uniform updates per ArrayCamera's sub-camera
1708

1709
			if ( _currentCamera !== ( _currentArrayCamera || camera ) ) {
1710

1711
				_currentCamera = ( _currentArrayCamera || camera );
1712 1713 1714 1715 1716 1717

				// 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 已提交
1718
				refreshLights = true;		// remains set until update done
1719 1720

			}
M
Mr.doob 已提交
1721

1722 1723 1724
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)

1725
			if ( material.isShaderMaterial ||
1726 1727 1728
				material.isMeshPhongMaterial ||
				material.isMeshStandardMaterial ||
				material.envMap ) {
1729

T
tschw 已提交
1730 1731 1732
				var uCamPos = p_uniforms.map.cameraPosition;

				if ( uCamPos !== undefined ) {
1733

T
tschw 已提交
1734
					uCamPos.setValue( _gl,
1735
						_vector3.setFromMatrixPosition( camera.matrixWorld ) );
1736 1737 1738 1739 1740

				}

			}

1741
			if ( material.isMeshPhongMaterial ||
1742 1743 1744 1745
				material.isMeshLambertMaterial ||
				material.isMeshBasicMaterial ||
				material.isMeshStandardMaterial ||
				material.isShaderMaterial ||
1746
				material.skinning ) {
1747

T
tschw 已提交
1748
				p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );
1749 1750 1751

			}

M
Mr.doob 已提交
1752 1753 1754 1755 1756 1757
		}

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

1758
		if ( material.skinning ) {
M
Mr.doob 已提交
1759

T
tschw 已提交
1760 1761
			p_uniforms.setOptional( _gl, object, 'bindMatrix' );
			p_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );
1762

T
tschw 已提交
1763
			var skeleton = object.skeleton;
1764

T
tschw 已提交
1765
			if ( skeleton ) {
1766

1767 1768
				var bones = skeleton.bones;

1769
				if ( capabilities.floatVertexTextures ) {
M
Mr.doob 已提交
1770

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

T
tschw 已提交
1799
				} else {
M
Mr.doob 已提交
1800

T
tschw 已提交
1801
					p_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );
M
Mr.doob 已提交
1802 1803 1804 1805 1806 1807 1808 1809 1810

				}

			}

		}

		if ( refreshMaterial ) {

1811 1812 1813
			p_uniforms.setValue( _gl, 'toneMappingExposure', _this.toneMappingExposure );
			p_uniforms.setValue( _gl, 'toneMappingWhitePoint', _this.toneMappingWhitePoint );

M
Mr.doob 已提交
1814
			if ( material.lights ) {
M
Mr.doob 已提交
1815

1816
				// the current material requires lighting info
M
Mr.doob 已提交
1817

T
tschw 已提交
1818 1819 1820 1821 1822 1823
				// 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 已提交
1824

T
tschw 已提交
1825
				markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
G
gero3 已提交
1826

T
tschw 已提交
1827
			}
G
gero3 已提交
1828

T
tschw 已提交
1829
			// refresh uniforms common to several materials
G
gero3 已提交
1830

T
tschw 已提交
1831
			if ( fog && material.fog ) {
G
gero3 已提交
1832

T
tschw 已提交
1833
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
1834 1835 1836

			}

1837
			if ( material.isMeshBasicMaterial ||
1838 1839 1840
				material.isMeshLambertMaterial ||
				material.isMeshPhongMaterial ||
				material.isMeshStandardMaterial ||
1841
				material.isMeshNormalMaterial ||
1842
				material.isMeshDepthMaterial ) {
M
Mr.doob 已提交
1843 1844 1845 1846 1847 1848 1849

				refreshUniformsCommon( m_uniforms, material );

			}

			// refresh single material specific uniforms

1850
			if ( material.isLineBasicMaterial ) {
M
Mr.doob 已提交
1851 1852 1853

				refreshUniformsLine( m_uniforms, material );

1854
			} else if ( material.isLineDashedMaterial ) {
M
Mr.doob 已提交
1855 1856 1857 1858

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

1859
			} else if ( material.isPointsMaterial ) {
M
Mr.doob 已提交
1860

M
Mr.doob 已提交
1861
				refreshUniformsPoints( m_uniforms, material );
M
Mr.doob 已提交
1862

1863
			} else if ( material.isMeshLambertMaterial ) {
1864 1865 1866

				refreshUniformsLambert( m_uniforms, material );

T
Takahiro 已提交
1867 1868 1869 1870
			} else if ( material.isMeshToonMaterial ) {

				refreshUniformsToon( m_uniforms, material );

1871 1872 1873 1874
			} else if ( material.isMeshPhongMaterial ) {

				refreshUniformsPhong( m_uniforms, material );

1875
			} else if ( material.isMeshPhysicalMaterial ) {
W
WestLangley 已提交
1876 1877 1878

				refreshUniformsPhysical( m_uniforms, material );

1879
			} else if ( material.isMeshStandardMaterial ) {
W
WestLangley 已提交
1880

1881
				refreshUniformsStandard( m_uniforms, material );
W
WestLangley 已提交
1882

1883
			} else if ( material.isMeshDepthMaterial ) {
M
Mr.doob 已提交
1884

1885 1886 1887 1888 1889 1890 1891 1892
				if ( material.displacementMap ) {

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

				}

1893
			} else if ( material.isMeshNormalMaterial ) {
M
Mr.doob 已提交
1894

1895
				refreshUniformsNormal( m_uniforms, material );
M
Mr.doob 已提交
1896 1897 1898

			}

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

		}

M
Mr.doob 已提交
1910

T
tschw 已提交
1911
		// common matrices
M
Mr.doob 已提交
1912

M
Mr.doob 已提交
1913 1914
		p_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix );
		p_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix );
T
tschw 已提交
1915
		p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );
A
arose 已提交
1916

T
tschw 已提交
1917
		return program;
A
arose 已提交
1918 1919 1920

	}

M
Mr.doob 已提交
1921 1922
	// Uniforms (refresh uniforms objects)

M
Mr.doob 已提交
1923
	function refreshUniformsCommon( uniforms, material ) {
M
Mr.doob 已提交
1924 1925 1926

		uniforms.opacity.value = material.opacity;

1927
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
1928

1929
		if ( material.emissive ) {
M
Mr.doob 已提交
1930

1931
			uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );
M
Mr.doob 已提交
1932 1933 1934

		}

1935 1936 1937
		uniforms.map.value = material.map;
		uniforms.specularMap.value = material.specularMap;
		uniforms.alphaMap.value = material.alphaMap;
M
Mr.doob 已提交
1938

1939 1940 1941 1942 1943 1944 1945
		if ( material.lightMap ) {

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

		}

1946
		if ( material.aoMap ) {
1947

1948 1949
			uniforms.aoMap.value = material.aoMap;
			uniforms.aoMapIntensity.value = material.aoMapIntensity;
1950 1951 1952

		}

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

		var uvScaleMap;

		if ( material.map ) {

			uvScaleMap = material.map;

		} else if ( material.specularMap ) {

			uvScaleMap = material.specularMap;

1971 1972 1973 1974
		} else if ( material.displacementMap ) {

			uvScaleMap = material.displacementMap;

M
Mr.doob 已提交
1975 1976 1977 1978 1979 1980 1981 1982
		} else if ( material.normalMap ) {

			uvScaleMap = material.normalMap;

		} else if ( material.bumpMap ) {

			uvScaleMap = material.bumpMap;

1983 1984 1985 1986 1987 1988 1989 1990
		} else if ( material.roughnessMap ) {

			uvScaleMap = material.roughnessMap;

		} else if ( material.metalnessMap ) {

			uvScaleMap = material.metalnessMap;

1991 1992 1993 1994
		} else if ( material.alphaMap ) {

			uvScaleMap = material.alphaMap;

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

			uvScaleMap = material.emissiveMap;

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

		if ( uvScaleMap !== undefined ) {

2003
			// backwards compatibility
2004
			if ( uvScaleMap.isWebGLRenderTarget ) {
M
Mr.doob 已提交
2005 2006 2007 2008 2009

				uvScaleMap = uvScaleMap.texture;

			}

M
Mr.doob 已提交
2010 2011 2012 2013 2014 2015 2016 2017
			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;
2018 2019 2020 2021 2022

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

2025
		uniforms.reflectivity.value = material.reflectivity;
M
Mr.doob 已提交
2026 2027
		uniforms.refractionRatio.value = material.refractionRatio;

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

M
Mr.doob 已提交
2030
	function refreshUniformsLine( uniforms, material ) {
M
Mr.doob 已提交
2031 2032 2033 2034

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

M
Mr.doob 已提交
2035
	}
M
Mr.doob 已提交
2036

M
Mr.doob 已提交
2037
	function refreshUniformsDash( uniforms, material ) {
M
Mr.doob 已提交
2038 2039 2040 2041 2042

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

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

M
Mr.doob 已提交
2045
	function refreshUniformsPoints( uniforms, material ) {
M
Mr.doob 已提交
2046

2047
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
2048
		uniforms.opacity.value = material.opacity;
2049
		uniforms.size.value = material.size * _pixelRatio;
2050
		uniforms.scale.value = _height * 0.5;
M
Mr.doob 已提交
2051 2052 2053

		uniforms.map.value = material.map;

2054 2055 2056 2057 2058 2059 2060 2061 2062
		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 已提交
2063
	}
M
Mr.doob 已提交
2064

M
Mr.doob 已提交
2065
	function refreshUniformsFog( uniforms, fog ) {
M
Mr.doob 已提交
2066 2067 2068

		uniforms.fogColor.value = fog.color;

2069
		if ( fog.isFog ) {
M
Mr.doob 已提交
2070 2071 2072 2073

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

2074
		} else if ( fog.isFogExp2 ) {
M
Mr.doob 已提交
2075 2076 2077 2078 2079

			uniforms.fogDensity.value = fog.density;

		}

M
Mr.doob 已提交
2080
	}
M
Mr.doob 已提交
2081

M
Mr.doob 已提交
2082
	function refreshUniformsLambert( uniforms, material ) {
2083 2084 2085 2086 2087 2088 2089 2090 2091

		if ( material.emissiveMap ) {

			uniforms.emissiveMap.value = material.emissiveMap;

		}

	}

M
Mr.doob 已提交
2092
	function refreshUniformsPhong( uniforms, material ) {
M
Mr.doob 已提交
2093

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

2097
		if ( material.emissiveMap ) {
2098

2099
			uniforms.emissiveMap.value = material.emissiveMap;
2100

2101
		}
M
Mr.doob 已提交
2102

2103 2104 2105 2106
		if ( material.bumpMap ) {

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

2108
		}
M
Mr.doob 已提交
2109

2110 2111 2112 2113 2114 2115
		if ( material.normalMap ) {

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

		}
M
Mr.doob 已提交
2116

2117 2118 2119 2120 2121
		if ( material.displacementMap ) {

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

2123
		}
2124

T
Takahiro 已提交
2125 2126 2127 2128 2129 2130
	}

	function refreshUniformsToon( uniforms, material ) {

		refreshUniformsPhong( uniforms, material );

T
Takahiro 已提交
2131
		if ( material.gradientMap ) {
T
Takahiro 已提交
2132

T
Takahiro 已提交
2133
			uniforms.gradientMap.value = material.gradientMap;
T
Takahiro 已提交
2134 2135 2136

		}

2137 2138
	}

M
Mr.doob 已提交
2139
	function refreshUniformsStandard( uniforms, material ) {
W
WestLangley 已提交
2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192

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

2195 2196 2197
		uniforms.clearCoat.value = material.clearCoat;
		uniforms.clearCoatRoughness.value = material.clearCoatRoughness;

W
WestLangley 已提交
2198 2199 2200 2201
		refreshUniformsStandard( uniforms, material );

	}

2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227
	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;

		}

	}

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

M
Mr.doob 已提交
2230
	function markUniformsLightsNeedsUpdate( uniforms, value ) {
2231

M
Mr.doob 已提交
2232
		uniforms.ambientLightColor.needsUpdate = value;
2233

B
Ben Houston 已提交
2234 2235 2236
		uniforms.directionalLights.needsUpdate = value;
		uniforms.pointLights.needsUpdate = value;
		uniforms.spotLights.needsUpdate = value;
2237
		uniforms.rectAreaLights.needsUpdate = value;
B
Ben Houston 已提交
2238
		uniforms.hemisphereLights.needsUpdate = value;
2239

M
Mr.doob 已提交
2240
	}
2241

T
tschw 已提交
2242
	// Lighting
M
Mr.doob 已提交
2243

M
Mr.doob 已提交
2244
	function setupShadows( lights ) {
2245 2246 2247 2248 2249 2250 2251 2252 2253

		var lightShadowsLength = 0;

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

			var light = lights[ i ];

			if ( light.castShadow ) {

M
Mr.doob 已提交
2254 2255
				_lights.shadows[ lightShadowsLength ] = light;
				lightShadowsLength ++;
2256 2257 2258 2259 2260 2261 2262 2263 2264

			}

		}

		_lights.shadows.length = lightShadowsLength;

	}

M
Mr.doob 已提交
2265
	function setupLights( lights, camera ) {
M
Mr.doob 已提交
2266

M
Mr.doob 已提交
2267
		var l, ll, light, shadow,
2268 2269 2270 2271 2272
			r = 0, g = 0, b = 0,
			color,
			intensity,
			distance,
			shadowMap,
M
Mr.doob 已提交
2273

2274
			viewMatrix = camera.matrixWorldInverse,
M
Mr.doob 已提交
2275

M
Mr.doob 已提交
2276 2277 2278 2279 2280
			directionalLength = 0,
			pointLength = 0,
			spotLength = 0,
			rectAreaLength = 0,
			hemiLength = 0;
M
Mr.doob 已提交
2281 2282 2283 2284 2285 2286 2287 2288 2289

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

			light = lights[ l ];

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

2290
			shadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null;
2291

2292
			if ( light.isAmbientLight ) {
M
Mr.doob 已提交
2293

2294 2295 2296
				r += color.r * intensity;
				g += color.g * intensity;
				b += color.b * intensity;
M
Mr.doob 已提交
2297

2298
			} else if ( light.isDirectionalLight ) {
M
Mr.doob 已提交
2299

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

2302
				uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
M
Mr.doob 已提交
2303
				uniforms.direction.setFromMatrixPosition( light.matrixWorld );
2304
				_vector3.setFromMatrixPosition( light.target.matrixWorld );
M
Mr.doob 已提交
2305 2306 2307
				uniforms.direction.sub( _vector3 );
				uniforms.direction.transformDirection( viewMatrix );

2308
				uniforms.shadow = light.castShadow;
M
Mr.doob 已提交
2309

2310
				if ( light.castShadow ) {
M
Mr.doob 已提交
2311

M
Mr.doob 已提交
2312 2313 2314 2315 2316
					shadow = light.shadow;

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

2318 2319
				}

2320
				_lights.directionalShadowMap[ directionalLength ] = shadowMap;
2321
				_lights.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;
M
Mr.doob 已提交
2322 2323 2324
				_lights.directional[ directionalLength ] = uniforms;

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

2326
			} else if ( light.isSpotLight ) {
M
Mr.doob 已提交
2327

M
Mr.doob 已提交
2328
				var uniforms = lightCache.get( light );
M
Mr.doob 已提交
2329 2330 2331

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

M
Mr.doob 已提交
2333 2334 2335 2336 2337 2338 2339 2340
				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 );

2341 2342
				uniforms.coneCos = Math.cos( light.angle );
				uniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );
M
Mr.doob 已提交
2343
				uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;
M
Mr.doob 已提交
2344

2345
				uniforms.shadow = light.castShadow;
M
Mr.doob 已提交
2346

2347 2348
				if ( light.castShadow ) {

M
Mr.doob 已提交
2349 2350 2351 2352 2353
					shadow = light.shadow;

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

2355 2356
				}

2357
				_lights.spotShadowMap[ spotLength ] = shadowMap;
2358
				_lights.spotShadowMatrix[ spotLength ] = light.shadow.matrix;
M
Mr.doob 已提交
2359 2360 2361
				_lights.spot[ spotLength ] = uniforms;

				spotLength ++;
2362

2363 2364 2365 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
			} 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 已提交
2393 2394 2395
				_lights.rectArea[ rectAreaLength ] = uniforms;

				rectAreaLength ++;
2396

2397
			} else if ( light.isPointLight ) {
M
Mr.doob 已提交
2398

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

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

M
Mr.doob 已提交
2404 2405
				uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
				uniforms.distance = light.distance;
M
Mr.doob 已提交
2406 2407
				uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;

2408
				uniforms.shadow = light.castShadow;
2409

M
Mr.doob 已提交
2410
				if ( light.castShadow ) {
2411

M
Mr.doob 已提交
2412 2413 2414 2415 2416
					shadow = light.shadow;

					uniforms.shadowBias = shadow.bias;
					uniforms.shadowRadius = shadow.radius;
					uniforms.shadowMapSize = shadow.mapSize;
2417 2418

				}
2419

2420
				_lights.pointShadowMap[ pointLength ] = shadowMap;
J
jaxry 已提交
2421
				_lights.pointShadowMatrix[ pointLength ] = light.shadow.matrix;
M
Mr.doob 已提交
2422 2423 2424
				_lights.point[ pointLength ] = uniforms;

				pointLength ++;
2425

2426
			} else if ( light.isHemisphereLight ) {
M
Mr.doob 已提交
2427

M
Mr.doob 已提交
2428
				var uniforms = lightCache.get( light );
M
Mr.doob 已提交
2429 2430 2431 2432

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

M
Mr.doob 已提交
2434 2435
				uniforms.skyColor.copy( light.color ).multiplyScalar( intensity );
				uniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );
M
Mr.doob 已提交
2436

M
Mr.doob 已提交
2437 2438 2439
				_lights.hemi[ hemiLength ] = uniforms;

				hemiLength ++;
M
Mr.doob 已提交
2440 2441 2442 2443 2444

			}

		}

M
Mr.doob 已提交
2445 2446 2447
		_lights.ambient[ 0 ] = r;
		_lights.ambient[ 1 ] = g;
		_lights.ambient[ 2 ] = b;
M
Mr.doob 已提交
2448

M
Mr.doob 已提交
2449 2450
		_lights.directional.length = directionalLength;
		_lights.spot.length = spotLength;
2451
		_lights.rectArea.length = rectAreaLength;
2452
		_lights.point.length = pointLength;
M
Mr.doob 已提交
2453
		_lights.hemi.length = hemiLength;
2454

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

M
Mr.doob 已提交
2458
	}
M
Mr.doob 已提交
2459 2460 2461 2462 2463

	// GL state setting

	this.setFaceCulling = function ( cullFace, frontFaceDirection ) {

T
tschw 已提交
2464
		state.setCullFace( cullFace );
R
Rich Harris 已提交
2465
		state.setFlipSided( frontFaceDirection === FrontFaceDirectionCW );
M
Mr.doob 已提交
2466 2467 2468 2469 2470

	};

	// Textures

T
tschw 已提交
2471 2472 2473 2474 2475 2476
	function allocTextureUnit() {

		var textureUnit = _usedTextureUnits;

		if ( textureUnit >= capabilities.maxTextures ) {

M
Mugen87 已提交
2477
			console.warn( 'THREE.WebGLRenderer: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );
T
tschw 已提交
2478 2479 2480 2481 2482 2483 2484 2485 2486

		}

		_usedTextureUnits += 1;

		return textureUnit;

	}

2487
	this.allocTextureUnit = allocTextureUnit;
T
tschw 已提交
2488

2489
	// this.setTexture2D = setTexture2D;
M
Mr.doob 已提交
2490
	this.setTexture2D = ( function () {
T
tschw 已提交
2491

2492
		var warned = false;
T
tschw 已提交
2493

2494
		// backwards compatibility: peel texture.texture
W
WestLangley 已提交
2495
		return function setTexture2D( texture, slot ) {
T
tschw 已提交
2496

T
Takahiro 已提交
2497
			if ( texture && texture.isWebGLRenderTarget ) {
T
tschw 已提交
2498

2499
				if ( ! warned ) {
T
tschw 已提交
2500

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

2504
				}
T
tschw 已提交
2505

2506
				texture = texture.texture;
T
tschw 已提交
2507

2508
			}
T
tschw 已提交
2509

2510
			textures.setTexture2D( texture, slot );
T
tschw 已提交
2511

2512
		};
T
tschw 已提交
2513

2514
	}() );
T
tschw 已提交
2515

M
Mr.doob 已提交
2516
	this.setTexture = ( function () {
2517 2518 2519

		var warned = false;

W
WestLangley 已提交
2520
		return function setTexture( texture, slot ) {
2521 2522 2523 2524 2525 2526 2527 2528

			if ( ! warned ) {

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

			}

2529
			textures.setTexture2D( texture, slot );
2530 2531 2532 2533 2534

		};

	}() );

M
Mr.doob 已提交
2535
	this.setTextureCube = ( function () {
2536 2537 2538

		var warned = false;

W
WestLangley 已提交
2539
		return function setTextureCube( texture, slot ) {
2540 2541

			// backwards compatibility: peel texture.texture
T
Takahiro 已提交
2542
			if ( texture && texture.isWebGLRenderTargetCube ) {
2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556

				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 已提交
2557
			if ( ( texture && texture.isCubeTexture ) ||
2558
				( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {
2559 2560 2561 2562

				// CompressedTexture can have Array in image :/

				// this function alone should take care of cube textures
2563
				textures.setTextureCube( texture, slot );
2564 2565 2566 2567 2568

			} else {

				// assumed: texture property of THREE.WebGLRenderTargetCube

2569
				textures.setTextureCubeDynamic( texture, slot );
2570 2571 2572 2573 2574 2575

			}

		};

	}() );
T
tschw 已提交
2576

2577
	this.getRenderTarget = function () {
2578 2579 2580

		return _currentRenderTarget;

M
Michael Herzog 已提交
2581
	};
2582

2583
	this.setRenderTarget = function ( renderTarget ) {
M
Mr.doob 已提交
2584

2585 2586
		_currentRenderTarget = renderTarget;

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

2589
			textures.setupRenderTarget( renderTarget );
M
Mr.doob 已提交
2590 2591 2592

		}

M
Mr.doob 已提交
2593
		var framebuffer = null;
M
Mr.doob 已提交
2594
		var isCube = false;
M
Mr.doob 已提交
2595 2596 2597

		if ( renderTarget ) {

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

M
Mr.doob 已提交
2600
			if ( renderTarget.isWebGLRenderTargetCube ) {
M
Mr.doob 已提交
2601

M
Mr.doob 已提交
2602
				framebuffer = __webglFramebuffer[ renderTarget.activeCubeFace ];
M
Mr.doob 已提交
2603
				isCube = true;
M
Mr.doob 已提交
2604 2605 2606

			} else {

M
Mr.doob 已提交
2607
				framebuffer = __webglFramebuffer;
M
Mr.doob 已提交
2608 2609 2610

			}

M
Mr.doob 已提交
2611
			_currentViewport.copy( renderTarget.viewport );
2612 2613
			_currentScissor.copy( renderTarget.scissor );
			_currentScissorTest = renderTarget.scissorTest;
2614

M
Mr.doob 已提交
2615 2616
		} else {

M
Mr.doob 已提交
2617
			_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );
2618
			_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );
2619
			_currentScissorTest = _scissorTest;
2620

M
Mr.doob 已提交
2621 2622
		}

M
Mr.doob 已提交
2623
		if ( _currentFramebuffer !== framebuffer ) {
M
Mr.doob 已提交
2624 2625 2626 2627 2628 2629

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

		}

M
Mr.doob 已提交
2630
		state.viewport( _currentViewport );
2631 2632
		state.scissor( _currentScissor );
		state.setScissorTest( _currentScissorTest );
2633

M
Mr.doob 已提交
2634 2635 2636
		if ( isCube ) {

			var textureProperties = properties.get( renderTarget.texture );
2637
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );
M
Mr.doob 已提交
2638 2639 2640

		}

M
Mr.doob 已提交
2641 2642
	};

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

0
06wj 已提交
2645
		if ( ! ( renderTarget && renderTarget.isWebGLRenderTarget ) ) {
2646

2647
			console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
G
gero3 已提交
2648
			return;
2649

G
gero3 已提交
2650
		}
2651

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

M
Mr.doob 已提交
2654
		if ( framebuffer ) {
2655

G
gero3 已提交
2656
			var restore = false;
2657

M
Mr.doob 已提交
2658
			if ( framebuffer !== _currentFramebuffer ) {
2659

M
Mr.doob 已提交
2660
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
2661

G
gero3 已提交
2662
				restore = true;
2663

G
gero3 已提交
2664
			}
2665

M
Mr.doob 已提交
2666
			try {
2667

M
Mr.doob 已提交
2668
				var texture = renderTarget.texture;
M
Mr.doob 已提交
2669 2670
				var textureFormat = texture.format;
				var textureType = texture.type;
2671

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

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

M
Mr.doob 已提交
2677
				}
2678

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

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

M
Mr.doob 已提交
2686
				}
2687

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

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

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

M
Mr.doob 已提交
2694
						_gl.readPixels( x, y, width, height, paramThreeToGL( textureFormat ), paramThreeToGL( textureType ), buffer );
2695 2696

					}
2697

M
Mr.doob 已提交
2698
				} else {
M
Mr.doob 已提交
2699

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

				}
M
Mr.doob 已提交
2703

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

M
Mr.doob 已提交
2706 2707 2708
				if ( restore ) {

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

M
Mr.doob 已提交
2710 2711 2712
				}

			}
M
Mr.doob 已提交
2713 2714 2715

		}

M
Mr.doob 已提交
2716 2717
	};

M
Mr.doob 已提交
2718 2719
	// Map three.js constants to WebGL constants

M
Mr.doob 已提交
2720
	function paramThreeToGL( p ) {
M
Mr.doob 已提交
2721

2722 2723
		var extension;

R
Rich Harris 已提交
2724 2725 2726
		if ( p === RepeatWrapping ) return _gl.REPEAT;
		if ( p === ClampToEdgeWrapping ) return _gl.CLAMP_TO_EDGE;
		if ( p === MirroredRepeatWrapping ) return _gl.MIRRORED_REPEAT;
M
Mr.doob 已提交
2727

R
Rich Harris 已提交
2728 2729 2730
		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 已提交
2731

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

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

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

2748
		if ( p === HalfFloatType ) {
2749

2750
			extension = extensions.get( 'OES_texture_half_float' );
2751

2752
			if ( extension !== null ) return extension.HALF_FLOAT_OES;
2753 2754 2755

		}

R
Rich Harris 已提交
2756 2757 2758 2759 2760 2761
		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;
2762
		if ( p === DepthStencilFormat ) return _gl.DEPTH_STENCIL;
M
Mr.doob 已提交
2763

R
Rich Harris 已提交
2764 2765 2766
		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 已提交
2767

R
Rich Harris 已提交
2768 2769 2770 2771 2772 2773 2774 2775
		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 已提交
2776

R
Rich Harris 已提交
2777 2778 2779
		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 已提交
2780

2781 2782
		if ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format ||
			p === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) {
M
Mr.doob 已提交
2783

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

2786 2787 2788 2789 2790 2791 2792 2793
			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 已提交
2794 2795 2796

		}

2797
		if ( p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format ||
2798
			p === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format ) {
2799

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

2802 2803 2804 2805 2806 2807 2808 2809
			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 已提交
2810 2811 2812

		}

2813
		if ( p === RGB_ETC1_Format ) {
2814

2815
			extension = extensions.get( 'WEBGL_compressed_texture_etc1' );
2816

2817
			if ( extension !== null ) return extension.COMPRESSED_RGB_ETC1_WEBGL;
2818 2819 2820

		}

2821 2822 2823
		if ( p === MinEquation || p === MaxEquation ) {

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

2825
			if ( extension !== null ) {
2826

2827 2828 2829 2830
				if ( p === MinEquation ) return extension.MIN_EXT;
				if ( p === MaxEquation ) return extension.MAX_EXT;

			}
2831 2832 2833

		}

2834
		if ( p === UnsignedInt248Type ) {
2835

2836
			extension = extensions.get( 'WEBGL_depth_texture' );
2837

2838
			if ( extension !== null ) return extension.UNSIGNED_INT_24_8_WEBGL;
2839 2840 2841

		}

M
Mr.doob 已提交
2842 2843
		return 0;

M
Mr.doob 已提交
2844
	}
M
Mr.doob 已提交
2845

M
Mr.doob 已提交
2846
}
R
Rich Harris 已提交
2847

T
Tristan VALCKE 已提交
2848

2849
export { WebGLRenderer };