WebGLRenderer.js 67.2 KB
Newer Older
M
Mr.doob 已提交
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, BackSide, DoubleSide, TriangleFanDrawMode, TriangleStripDrawMode, TrianglesDrawMode, NoColors, FlatShading, LinearToneMapping } from '../constants';
R
Rich Harris 已提交
2 3 4 5 6 7 8 9
import { Matrix4 } from '../math/Matrix4';
import { WebGLUniforms } from './webgl/WebGLUniforms';
import { ShaderLib } from './shaders/ShaderLib';
import { LensFlarePlugin } from './webgl/plugins/LensFlarePlugin';
import { SpritePlugin } from './webgl/plugins/SpritePlugin';
import { WebGLShadowMap } from './webgl/WebGLShadowMap';
import { ShaderMaterial } from '../materials/ShaderMaterial';
import { Mesh } from '../objects/Mesh';
10 11
import { BoxBufferGeometry } from '../geometries/BoxBufferGeometry';
import { PlaneBufferGeometry } from '../geometries/PlaneBufferGeometry';
R
Rich Harris 已提交
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
import { MeshBasicMaterial } from '../materials/MeshBasicMaterial';
import { PerspectiveCamera } from '../cameras/PerspectiveCamera';
import { OrthographicCamera } from '../cameras/OrthographicCamera';
import { WebGLIndexedBufferRenderer } from './webgl/WebGLIndexedBufferRenderer';
import { WebGLBufferRenderer } from './webgl/WebGLBufferRenderer';
import { WebGLLights } from './webgl/WebGLLights';
import { WebGLPrograms } from './webgl/WebGLPrograms';
import { WebGLObjects } from './webgl/WebGLObjects';
import { WebGLTextures } from './webgl/WebGLTextures';
import { WebGLProperties } from './webgl/WebGLProperties';
import { WebGLState } from './webgl/WebGLState';
import { WebGLCapabilities } from './webgl/WebGLCapabilities';
import { BufferGeometry } from '../core/BufferGeometry';
import { WebGLExtensions } from './webgl/WebGLExtensions';
import { Vector3 } from '../math/Vector3';
import { Sphere } from '../math/Sphere';
import { WebGLClipping } from './webgl/WebGLClipping';
import { Frustum } from '../math/Frustum';
import { Vector4 } from '../math/Vector4';
import { Color } from '../math/Color';

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

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

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

	parameters = parameters || {};

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

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

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

O
OpenShift guest 已提交
59
	var opaqueObjects = [];
M
Mr.doob 已提交
60
	var opaqueObjectsLastIndex = - 1;
61
	var transparentObjects = [];
M
Mr.doob 已提交
62
	var transparentObjectsLastIndex = - 1;
63

64 65
	var morphInfluences = new Float32Array( 8 );

M
Mr.doob 已提交
66 67 68
	var sprites = [];
	var lensFlares = [];

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

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

M
Mr.doob 已提交
90 91
	// physically based shading

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

96 97
	// physical lights

98
	this.physicallyCorrectLights = false;
99

B
Ben Houston 已提交
100 101
	// tone mapping

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

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

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

	// internal properties

	var _this = this,

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

117 118 119 120 121 122
		_currentProgram = null,
		_currentRenderTarget = null,
		_currentFramebuffer = null,
		_currentMaterialId = - 1,
		_currentGeometryProgram = '',
		_currentCamera = null,
M
Mr.doob 已提交
123

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

127
		_currentViewport = new Vector4(),
128

129
		//
130

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

133
		//
M
Mr.doob 已提交
134

135 136
		_clearColor = new Color( 0x000000 ),
		_clearAlpha = 0,
M
Mr.doob 已提交
137

138 139
		_width = _canvas.width,
		_height = _canvas.height,
M
Mr.doob 已提交
140

141
		_pixelRatio = 1,
M
Mr.doob 已提交
142

143 144
		_scissor = new Vector4( 0, 0, _width, _height ),
		_scissorTest = false,
145

146
		_viewport = new Vector4( 0, 0, _width, _height ),
147

148
		// frustum
M
Mr.doob 已提交
149

150
		_frustum = new Frustum(),
M
Mr.doob 已提交
151

152
		// clipping
T
tschw 已提交
153

154 155 156
		_clipping = new WebGLClipping(),
		_clippingEnabled = false,
		_localClippingEnabled = false,
T
tschw 已提交
157

158
		_sphere = new Sphere(),
T
tschw 已提交
159

160
		// camera matrices cache
M
Mr.doob 已提交
161

162
		_projScreenMatrix = new Matrix4(),
M
Mr.doob 已提交
163

A
aardgoose 已提交
164 165 166
		_vector3 = new Vector3(),
		_matrix4 = new Matrix4(), 
		_matrix42 = new Matrix4(),
M
Mr.doob 已提交
167

168
		// light arrays cache
M
Mr.doob 已提交
169

170
		_lights = {
M
Mr.doob 已提交
171

172
			hash: '',
173

M
Mr.doob 已提交
174
		ambient: [ 0, 0, 0 ],
M
Mr.doob 已提交
175
		directional: [],
176 177
		directionalShadowMap: [],
		directionalShadowMatrix: [],
M
Mr.doob 已提交
178
		spot: [],
179 180
		spotShadowMap: [],
		spotShadowMatrix: [],
181
		rectArea: [],
M
Mr.doob 已提交
182
		point: [],
183 184
		pointShadowMap: [],
		pointShadowMatrix: [],
185 186
		hemi: [],

187
			shadows: []
M
Mr.doob 已提交
188

189
		},
190

191
		// info
M
Mr.doob 已提交
192

193
		_infoRender = {
194

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,
205 206 207 208 209 210
		memory: {

			geometries: 0,
			textures: 0

		},
211
		programs: null
M
Mr.doob 已提交
212 213

	};
214

215

M
Mr.doob 已提交
216 217 218 219
	// initialize

	var _gl;

M
Mr.doob 已提交
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234
	try {

		var attributes = {
			alpha: _alpha,
			depth: _depth,
			stencil: _stencil,
			antialias: _antialias,
			premultipliedAlpha: _premultipliedAlpha,
			preserveDrawingBuffer: _preserveDrawingBuffer
		};

		_gl = _context || _canvas.getContext( 'webgl', attributes ) || _canvas.getContext( 'experimental-webgl', attributes );

		if ( _gl === null ) {

G
gero3 已提交
235
			if ( _canvas.getContext( 'webgl' ) !== null ) {
236 237 238 239 240 241 242 243

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

			} else {

				throw 'Error creating WebGL context.';

			}
M
Mr.doob 已提交
244 245 246

		}

247 248 249 250 251 252 253 254 255 256 257 258
		// Some experimental-webgl implementations do not have getShaderPrecisionFormat

		if ( _gl.getShaderPrecisionFormat === undefined ) {

			_gl.getShaderPrecisionFormat = function () {

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

			};

		}

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

M
Mr.doob 已提交
261 262
	} catch ( error ) {

263
		console.error( 'THREE.WebGLRenderer: ' + error );
M
Mr.doob 已提交
264 265 266

	}

R
Rich Harris 已提交
267
	var extensions = new WebGLExtensions( _gl );
268

269
	extensions.get( 'WEBGL_depth_texture' );
270 271
	extensions.get( 'OES_texture_float' );
	extensions.get( 'OES_texture_float_linear' );
272 273
	extensions.get( 'OES_texture_half_float' );
	extensions.get( 'OES_texture_half_float_linear' );
274
	extensions.get( 'OES_standard_derivatives' );
B
Ben Adams 已提交
275
	extensions.get( 'ANGLE_instanced_arrays' );
276

277 278
	if ( extensions.get( 'OES_element_index_uint' ) ) {

R
Rich Harris 已提交
279
		BufferGeometry.MaxIndex = 4294967296;
280 281 282

	}

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

R
Rich Harris 已提交
285 286 287 288 289 290
	var state = new WebGLState( _gl, extensions, paramThreeToGL );
	var properties = new WebGLProperties();
	var textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, this.info );
	var objects = new WebGLObjects( _gl, properties, this.info );
	var programCache = new WebGLPrograms( this, capabilities );
	var lightCache = new WebGLLights();
291

292 293
	this.info.programs = programCache.programs;

R
Rich Harris 已提交
294 295
	var bufferRenderer = new WebGLBufferRenderer( _gl, extensions, _infoRender );
	var indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );
296

M
Mr.doob 已提交
297 298
	//

R
Rich Harris 已提交
299 300 301 302 303
	var backgroundCamera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
	var backgroundCamera2 = new PerspectiveCamera();
	var backgroundPlaneMesh = new Mesh(
		new PlaneBufferGeometry( 2, 2 ),
		new MeshBasicMaterial( { depthTest: false, depthWrite: false, fog: false } )
M
Mr.doob 已提交
304
	);
R
Rich Harris 已提交
305 306 307 308
	var backgroundBoxShader = ShaderLib[ 'cube' ];
	var backgroundBoxMesh = new Mesh(
		new BoxBufferGeometry( 5, 5, 5 ),
		new ShaderMaterial( {
M
Mr.doob 已提交
309 310 311
			uniforms: backgroundBoxShader.uniforms,
			vertexShader: backgroundBoxShader.vertexShader,
			fragmentShader: backgroundBoxShader.fragmentShader,
R
Rich Harris 已提交
312
			side: BackSide,
M
Mr.doob 已提交
313 314
			depthTest: false,
			depthWrite: false,
315
			fog: false
M
Mr.doob 已提交
316 317 318 319 320
		} )
	);

	//

321 322
	function getTargetPixelRatio() {

323
		return _currentRenderTarget === null ? _pixelRatio : 1;
324 325 326

	}

327
	function setDefaultGLState() {
M
Mr.doob 已提交
328

M
Mr.doob 已提交
329
		state.init();
M
Mr.doob 已提交
330

331 332
		state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );
		state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );
M
Mr.doob 已提交
333

334
		state.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );
M
Mr.doob 已提交
335

336
	}
337

338
	function resetGLState() {
339 340 341 342

		_currentProgram = null;
		_currentCamera = null;

343
		_currentGeometryProgram = '';
344 345
		_currentMaterialId = - 1;

M
Mr.doob 已提交
346 347
		state.reset();

348
	}
M
Mr.doob 已提交
349 350 351 352

	setDefaultGLState();

	this.context = _gl;
M
Mr.doob 已提交
353
	this.capabilities = capabilities;
354
	this.extensions = extensions;
355
	this.properties = properties;
M
Mr.doob 已提交
356
	this.state = state;
M
Mr.doob 已提交
357

M
Mr.doob 已提交
358 359
	// shadow map

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

362
	this.shadowMap = shadowMap;
M
Mr.doob 已提交
363

M
Mr.doob 已提交
364

M
Mr.doob 已提交
365 366
	// Plugins

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

M
Mr.doob 已提交
370 371 372 373 374 375 376 377
	// API

	this.getContext = function () {

		return _gl;

	};

378 379 380 381 382 383
	this.getContextAttributes = function () {

		return _gl.getContextAttributes();

	};

384 385 386 387 388 389
	this.forceContextLoss = function () {

		extensions.get( 'WEBGL_lose_context' ).loseContext();

	};

390
	this.getMaxAnisotropy = function () {
391

392
		return capabilities.getMaxAnisotropy();
393

394
	};
M
Mr.doob 已提交
395 396 397

	this.getPrecision = function () {

G
gero3 已提交
398
		return capabilities.precision;
M
Mr.doob 已提交
399 400 401

	};

402 403
	this.getPixelRatio = function () {

404
		return _pixelRatio;
405 406 407 408 409

	};

	this.setPixelRatio = function ( value ) {

410 411 412 413 414
		if ( value === undefined ) return;

		_pixelRatio = value;

		this.setSize( _viewport.z, _viewport.w, false );
415 416 417

	};

418 419 420
	this.getSize = function () {

		return {
421 422
			width: _width,
			height: _height
423 424 425 426
		};

	};

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

429 430 431
		_width = width;
		_height = height;

432 433
		_canvas.width = width * _pixelRatio;
		_canvas.height = height * _pixelRatio;
434

435
		if ( updateStyle !== false ) {
436

G
gero3 已提交
437 438
			_canvas.style.width = width + 'px';
			_canvas.style.height = height + 'px';
439

G
gero3 已提交
440
		}
M
Mr.doob 已提交
441

442
		this.setViewport( 0, 0, width, height );
M
Mr.doob 已提交
443 444 445 446 447

	};

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

448
		state.viewport( _viewport.set( x, y, width, height ) );
M
Mr.doob 已提交
449 450 451

	};

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

454
		state.scissor( _scissor.set( x, y, width, height ) );
M
Mr.doob 已提交
455 456 457

	};

458 459
	this.setScissorTest = function ( boolean ) {

460
		state.setScissorTest( _scissorTest = boolean );
M
Mr.doob 已提交
461 462 463 464 465

	};

	// Clearing

M
Mr.doob 已提交
466
	this.getClearColor = function () {
M
Mr.doob 已提交
467

M
Mr.doob 已提交
468
		return _clearColor;
M
Mr.doob 已提交
469 470 471

	};

M
Mr.doob 已提交
472
	this.setClearColor = function ( color, alpha ) {
M
Mr.doob 已提交
473

M
Mr.doob 已提交
474
		_clearColor.set( color );
475

M
Mr.doob 已提交
476
		_clearAlpha = alpha !== undefined ? alpha : 1;
M
Mr.doob 已提交
477

478
		state.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );
M
Mr.doob 已提交
479 480 481

	};

M
Mr.doob 已提交
482
	this.getClearAlpha = function () {
M
Mr.doob 已提交
483

M
Mr.doob 已提交
484
		return _clearAlpha;
M
Mr.doob 已提交
485 486 487

	};

M
Mr.doob 已提交
488
	this.setClearAlpha = function ( alpha ) {
M
Mr.doob 已提交
489

M
Mr.doob 已提交
490
		_clearAlpha = alpha;
M
Mr.doob 已提交
491

492
		state.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );
M
Mr.doob 已提交
493 494 495 496 497 498 499 500 501 502 503 504

	};

	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 );
505 506 507 508 509

	};

	this.clearColor = function () {

M
Mr.doob 已提交
510
		this.clear( true, false, false );
511 512 513 514 515

	};

	this.clearDepth = function () {

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

	};

	this.clearStencil = function () {

M
Mr.doob 已提交
522
		this.clear( false, false, true );
M
Mr.doob 已提交
523 524 525 526 527 528 529 530 531 532

	};

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

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

	};

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

535
	this.resetGLState = resetGLState;
M
Mr.doob 已提交
536

D
dubejf 已提交
537 538
	this.dispose = function() {

539 540 541 542 543
		transparentObjects = [];
		transparentObjectsLastIndex = -1;
		opaqueObjects = [];
		opaqueObjectsLastIndex = -1;

D
dubejf 已提交
544 545 546 547
		_canvas.removeEventListener( 'webglcontextlost', onContextLost, false );

	};

M
Mr.doob 已提交
548
	// Events
M
Mr.doob 已提交
549

D
dubejf 已提交
550 551 552 553 554 555 556 557 558
	function onContextLost( event ) {

		event.preventDefault();

		resetGLState();
		setDefaultGLState();

		properties.clear();

M
Mr.doob 已提交
559
	}
D
dubejf 已提交
560

561
	function onMaterialDispose( event ) {
M
Mr.doob 已提交
562 563 564 565 566 567 568

		var material = event.target;

		material.removeEventListener( 'dispose', onMaterialDispose );

		deallocateMaterial( material );

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

	// Buffer deallocation

573
	function deallocateMaterial( material ) {
M
Mr.doob 已提交
574

575 576 577 578
		releaseMaterialProgramReference( material );

		properties.delete( material );

579
	}
580 581


582
	function releaseMaterialProgramReference( material ) {
583

584
		var programInfo = properties.get( material ).program;
M
Mr.doob 已提交
585 586 587

		material.program = undefined;

588
		if ( programInfo !== undefined ) {
M
Mr.doob 已提交
589

590
			programCache.releaseProgram( programInfo );
M
Mr.doob 已提交
591

M
Mr.doob 已提交
592 593
		}

594
	}
M
Mr.doob 已提交
595 596 597 598 599

	// Buffer rendering

	this.renderBufferImmediate = function ( object, program, material ) {

600
		state.initAttributes();
601

602
		var buffers = properties.get( object );
603

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

609
		var attributes = program.getAttributes();
610

M
Mr.doob 已提交
611 612
		if ( object.hasPositions ) {

613
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.position );
M
Mr.doob 已提交
614
			_gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );
615

616 617
			state.enableAttribute( attributes.position );
			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
618 619 620 621 622

		}

		if ( object.hasNormals ) {

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

625
			if ( ! material.isMeshPhongMaterial &&
T
Takahiro 已提交
626
				! material.isMeshToonMaterial &&
627 628
				! material.isMeshStandardMaterial &&
				material.shading === FlatShading ) {
M
Mr.doob 已提交
629

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

632
					var array = object.normalArray;
M
Mr.doob 已提交
633

634 635 636
					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 已提交
637

638 639 640
					array[ i + 0 ] = nx;
					array[ i + 1 ] = ny;
					array[ i + 2 ] = nz;
M
Mr.doob 已提交
641

642 643 644
					array[ i + 3 ] = nx;
					array[ i + 4 ] = ny;
					array[ i + 5 ] = nz;
M
Mr.doob 已提交
645

646 647 648
					array[ i + 6 ] = nx;
					array[ i + 7 ] = ny;
					array[ i + 8 ] = nz;
M
Mr.doob 已提交
649 650 651 652 653 654

				}

			}

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

656
			state.enableAttribute( attributes.normal );
657

658
			_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
659 660 661 662 663

		}

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

664
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );
M
Mr.doob 已提交
665
			_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );
666

667
			state.enableAttribute( attributes.uv );
668

669
			_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
670 671 672

		}

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

675
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );
M
Mr.doob 已提交
676
			_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );
677

678
			state.enableAttribute( attributes.color );
679

680
			_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
681 682 683

		}

684
		state.disableUnusedAttributes();
685

M
Mr.doob 已提交
686 687 688 689 690 691
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );

		object.count = 0;

	};

692
	this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {
693

M
Mr.doob 已提交
694 695
		setMaterial( material );

696
		var program = setProgram( camera, fog, material, object );
M
Mr.doob 已提交
697

M
Mr.doob 已提交
698 699
		var updateBuffers = false;
		var geometryProgram = geometry.id + '_' + program.id + '_' + material.wireframe;
M
Mr.doob 已提交
700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722

		if ( geometryProgram !== _currentGeometryProgram ) {

			_currentGeometryProgram = geometryProgram;
			updateBuffers = true;

		}

		// morph targets

		var morphTargetInfluences = object.morphTargetInfluences;

		if ( morphTargetInfluences !== undefined ) {

			var activeInfluences = [];

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

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

			}

723
			activeInfluences.sort( absNumericalSort );
M
Mr.doob 已提交
724 725 726 727 728 729 730

			if ( activeInfluences.length > 8 ) {

				activeInfluences.length = 8;

			}

731 732
			var morphAttributes = geometry.morphAttributes;

M
Mr.doob 已提交
733 734 735 736 737 738 739
			for ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {

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

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

740
					var index = influence[ 1 ];
M
Mr.doob 已提交
741

742 743
					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 已提交
744 745 746

				} else {

747 748
					if ( material.morphTargets === true ) geometry.removeAttribute( 'morphTarget' + i );
					if ( material.morphNormals === true ) geometry.removeAttribute( 'morphNormal' + i );
M
Mr.doob 已提交
749 750 751 752 753

				}

			}

754 755 756 757 758 759
			for ( var i = activeInfluences.length, il = morphInfluences.length; i < il; i ++ ) {

				morphInfluences[ i ] = 0.0;

			}

T
tschw 已提交
760
			program.getUniforms().setValue(
761
				_gl, 'morphTargetInfluences', morphInfluences );
M
Mr.doob 已提交
762 763 764 765 766

			updateBuffers = true;

		}

767 768
		//

769
		var index = geometry.index;
770
		var position = geometry.attributes.position;
771
		var rangeFactor = 1;
772

773 774
		if ( material.wireframe === true ) {

775
			index = objects.getWireframeAttribute( geometry );
776
			rangeFactor = 2;
777 778 779

		}

780 781
		var renderer;

782
		if ( index !== null ) {
783

784 785
			renderer = indexedBufferRenderer;
			renderer.setIndex( index );
786

787
		} else {
788

789
			renderer = bufferRenderer;
790

791
		}
M
Mr.doob 已提交
792

793
		if ( updateBuffers ) {
M
Mr.doob 已提交
794

795
			setupVertexAttributes( material, program, geometry );
M
Mr.doob 已提交
796

797
			if ( index !== null ) {
798

799
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, objects.getAttributeBuffer( index ) );
800 801 802

			}

803
		}
804

805 806
		//

807
		var dataCount = 0;
808

M
Mr.doob 已提交
809
		if ( index !== null ) {
810

M
Mr.doob 已提交
811
			dataCount = index.count;
812

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

M
Mr.doob 已提交
815
			dataCount = position.count;
816

M
Mr.doob 已提交
817
		}
818

M
Mr.doob 已提交
819 820
		var rangeStart = geometry.drawRange.start * rangeFactor;
		var rangeCount = geometry.drawRange.count * rangeFactor;
821

M
Mr.doob 已提交
822 823
		var groupStart = group !== null ? group.start * rangeFactor : 0;
		var groupCount = group !== null ? group.count * rangeFactor : Infinity;
824

M
Mr.doob 已提交
825 826
		var drawStart = Math.max( rangeStart, groupStart );
		var drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1;
M
Mr.doob 已提交
827 828 829

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

830 831
		if ( drawCount === 0 ) return;

M
Mr.doob 已提交
832
		//
833

834
		if ( object.isMesh ) {
835

836
			if ( material.wireframe === true ) {
837

838
				state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );
839
				renderer.setMode( _gl.LINES );
840

841
			} else {
M
Mr.doob 已提交
842 843

				switch ( object.drawMode ) {
844

R
Rich Harris 已提交
845
					case TrianglesDrawMode:
B
Ben Adams 已提交
846 847 848
						renderer.setMode( _gl.TRIANGLES );
						break;

R
Rich Harris 已提交
849
					case TriangleStripDrawMode:
B
Ben Adams 已提交
850 851 852
						renderer.setMode( _gl.TRIANGLE_STRIP );
						break;

R
Rich Harris 已提交
853
					case TriangleFanDrawMode:
B
Ben Adams 已提交
854 855 856 857
						renderer.setMode( _gl.TRIANGLE_FAN );
						break;

				}
858

859
			}
860

861

862
		} else if ( object.isLine ) {
863

864
			var lineWidth = material.linewidth;
865

866
			if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material
867

868
			state.setLineWidth( lineWidth * getTargetPixelRatio() );
869

870
			if ( object.isLineSegments ) {
871

872
				renderer.setMode( _gl.LINES );
873

874
			} else {
875

876
				renderer.setMode( _gl.LINE_STRIP );
877 878

			}
M
Mr.doob 已提交
879

880
		} else if ( object.isPoints ) {
881 882

			renderer.setMode( _gl.POINTS );
883 884

		}
885

T
Takahiro 已提交
886
		if ( geometry && geometry.isInstancedBufferGeometry ) {
M
Mr.doob 已提交
887 888 889

			if ( geometry.maxInstancedCount > 0 ) {

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

J
jfranc 已提交
892
			}
893 894 895

		} else {

M
Mr.doob 已提交
896
			renderer.render( drawStart, drawCount );
897

M
Mr.doob 已提交
898 899 900 901
		}

	};

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

M
Mr.doob 已提交
904
		var extension;
B
Ben Adams 已提交
905

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

M
Mr.doob 已提交
908
			extension = extensions.get( 'ANGLE_instanced_arrays' );
B
Ben Adams 已提交
909

M
Mr.doob 已提交
910
			if ( extension === null ) {
B
Ben Adams 已提交
911

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

M
Mr.doob 已提交
915 916 917
			}

		}
B
Ben Adams 已提交
918

919 920
		if ( startIndex === undefined ) startIndex = 0;

921 922
		state.initAttributes();

923
		var geometryAttributes = geometry.attributes;
924

925
		var programAttributes = program.getAttributes();
926

927
		var materialDefaultAttributeValues = material.defaultAttributeValues;
928

929
		for ( var name in programAttributes ) {
930

931
			var programAttribute = programAttributes[ name ];
M
Mr.doob 已提交
932

M
Mr.doob 已提交
933
			if ( programAttribute >= 0 ) {
M
Mr.doob 已提交
934

935
				var geometryAttribute = geometryAttributes[ name ];
936

M
Mr.doob 已提交
937
				if ( geometryAttribute !== undefined ) {
M
Mr.doob 已提交
938

939
					var normalized = geometryAttribute.normalized;
940
					var size = geometryAttribute.itemSize;
941

942
					var attributeProperties = objects.getAttributeProperties( geometryAttribute );
943

944 945 946
					var buffer = attributeProperties.__webglBuffer;
					var type = attributeProperties.type;
					var bytesPerElement = attributeProperties.bytesPerElement;
947

A
aardgoose 已提交
948
					if ( geometryAttribute.isInterleavedBufferAttribute ) {
949

M
Mr.doob 已提交
950 951 952 953
						var data = geometryAttribute.data;
						var stride = data.stride;
						var offset = geometryAttribute.offset;

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

M
Mr.doob 已提交
956
							state.enableAttributeAndDivisor( programAttribute, data.meshPerAttribute, extension );
B
Ben Adams 已提交
957

M
Mr.doob 已提交
958
							if ( geometry.maxInstancedCount === undefined ) {
959

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

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

M
Mr.doob 已提交
964
						} else {
B
Ben Adams 已提交
965

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

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

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

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

A
aardgoose 已提交
975
						if ( geometryAttribute.isInstancedBufferAttribute ) {
B
Ben Adams 已提交
976

M
Mr.doob 已提交
977
							state.enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute, extension );
B
Ben Adams 已提交
978

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

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

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

M
Mr.doob 已提交
985 986 987 988
						} else {

							state.enableAttribute( programAttribute );

M
Mr.doob 已提交
989
						}
B
Ben Adams 已提交
990

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

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

996 997
				} else if ( materialDefaultAttributeValues !== undefined ) {

T
tschw 已提交
998
					var value = materialDefaultAttributeValues[ name ];
999

1000
					if ( value !== undefined ) {
M
Mr.doob 已提交
1001

1002
						switch ( value.length ) {
M
Mr.doob 已提交
1003

1004 1005 1006
							case 2:
								_gl.vertexAttrib2fv( programAttribute, value );
								break;
M
Mr.doob 已提交
1007

1008 1009 1010
							case 3:
								_gl.vertexAttrib3fv( programAttribute, value );
								break;
M
Mr.doob 已提交
1011

1012 1013 1014
							case 4:
								_gl.vertexAttrib4fv( programAttribute, value );
								break;
1015

1016 1017
							default:
								_gl.vertexAttrib1fv( programAttribute, value );
1018 1019

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

					}

				}

			}

		}
1028

1029
		state.disableUnusedAttributes();
1030

M
Mr.doob 已提交
1031 1032
	}

M
Mr.doob 已提交
1033 1034
	// Sorting

1035
	function absNumericalSort( a, b ) {
1036

1037
		return Math.abs( b[ 0 ] ) - Math.abs( a[ 0 ] );
1038 1039 1040

	}

M
Mr.doob 已提交
1041
	function painterSortStable( a, b ) {
M
Mr.doob 已提交
1042

U
unconed 已提交
1043
		if ( a.object.renderOrder !== b.object.renderOrder ) {
1044

U
unconed 已提交
1045
			return a.object.renderOrder - b.object.renderOrder;
1046

1047 1048 1049 1050
		} else if ( a.material.program && b.material.program && a.material.program !== b.material.program ) {

			return a.material.program.id - b.material.program.id;

M
Mr.doob 已提交
1051
		} else if ( a.material.id !== b.material.id ) {
M
Mr.doob 已提交
1052

M
Mr.doob 已提交
1053
			return a.material.id - b.material.id;
1054 1055

		} else if ( a.z !== b.z ) {
M
Mr.doob 已提交
1056

M
Mr.doob 已提交
1057
			return a.z - b.z;
M
Mr.doob 已提交
1058 1059 1060

		} else {

1061
			return a.id - b.id;
M
Mr.doob 已提交
1062 1063 1064

		}

1065
	}
M
Mr.doob 已提交
1066

M
Mr.doob 已提交
1067
	function reversePainterSortStable( a, b ) {
1068

U
unconed 已提交
1069
		if ( a.object.renderOrder !== b.object.renderOrder ) {
1070

U
unconed 已提交
1071
			return a.object.renderOrder - b.object.renderOrder;
1072 1073

		} if ( a.z !== b.z ) {
1074

M
Mr.doob 已提交
1075
			return b.z - a.z;
1076 1077 1078 1079 1080 1081 1082

		} else {

			return a.id - b.id;

		}

1083
	}
1084

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

	this.render = function ( scene, camera, renderTarget, forceClear ) {

1089
		if ( camera !== undefined && camera.isCamera !== true ) {
M
Mr.doob 已提交
1090

1091
			console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );
M
Mr.doob 已提交
1092 1093 1094 1095 1096 1097
			return;

		}

		// reset caching for this frame

1098
		_currentGeometryProgram = '';
1099
		_currentMaterialId = - 1;
1100
		_currentCamera = null;
M
Mr.doob 已提交
1101 1102 1103

		// update scene graph

1104
		if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
M
Mr.doob 已提交
1105 1106 1107

		// update camera matrices and frustum

1108
		if ( camera.parent === null ) camera.updateMatrixWorld();
M
Mr.doob 已提交
1109 1110 1111 1112 1113 1114

		camera.matrixWorldInverse.getInverse( camera.matrixWorld );

		_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
		_frustum.setFromMatrix( _projScreenMatrix );

M
Mr.doob 已提交
1115
		lights.length = 0;
1116

M
Mr.doob 已提交
1117 1118
		opaqueObjectsLastIndex = - 1;
		transparentObjectsLastIndex = - 1;
1119

M
Mr.doob 已提交
1120 1121 1122
		sprites.length = 0;
		lensFlares.length = 0;

T
tschw 已提交
1123
		_localClippingEnabled = this.localClippingEnabled;
M
Mr.doob 已提交
1124
		_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );
T
tschw 已提交
1125

1126
		projectObject( scene, camera );
M
Mr.doob 已提交
1127

1128 1129 1130
		opaqueObjects.length = opaqueObjectsLastIndex + 1;
		transparentObjects.length = transparentObjectsLastIndex + 1;

M
Mr.doob 已提交
1131
		if ( _this.sortObjects === true ) {
1132 1133 1134

			opaqueObjects.sort( painterSortStable );
			transparentObjects.sort( reversePainterSortStable );
M
Mr.doob 已提交
1135

1136 1137
		}

M
Mr.doob 已提交
1138
		//
M
Mr.doob 已提交
1139

T
tschw 已提交
1140
		if ( _clippingEnabled ) _clipping.beginShadows();
T
tschw 已提交
1141

1142 1143
		setupShadows( lights );

M
Mr.doob 已提交
1144
		shadowMap.render( scene, camera );
M
Mr.doob 已提交
1145

1146 1147
		setupLights( lights, camera );

T
tschw 已提交
1148
		if ( _clippingEnabled ) _clipping.endShadows();
T
tschw 已提交
1149

M
Mr.doob 已提交
1150 1151
		//

1152 1153 1154 1155
		_infoRender.calls = 0;
		_infoRender.vertices = 0;
		_infoRender.faces = 0;
		_infoRender.points = 0;
M
Mr.doob 已提交
1156

1157 1158 1159 1160 1161 1162
		if ( renderTarget === undefined ) {

			renderTarget = null;

		}

M
Mr.doob 已提交
1163 1164
		this.setRenderTarget( renderTarget );

M
Mr.doob 已提交
1165 1166 1167 1168 1169 1170
		//

		var background = scene.background;

		if ( background === null ) {

1171
			state.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );
M
Mr.doob 已提交
1172

T
Takahiro 已提交
1173
		} else if ( background && background.isColor ) {
1174

1175
			state.buffers.color.setClear( background.r, background.g, background.b, 1, _premultipliedAlpha );
1176
			forceClear = true;
1177 1178 1179 1180 1181 1182 1183 1184 1185

		}

		if ( this.autoClear || forceClear ) {

			this.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil );

		}

T
Takahiro 已提交
1186
		if ( background && background.isCubeTexture ) {
M
Mr.doob 已提交
1187

1188
			backgroundCamera2.projectionMatrix.copy( camera.projectionMatrix );
M
Mr.doob 已提交
1189 1190 1191 1192 1193 1194 1195

			backgroundCamera2.matrixWorld.extractRotation( camera.matrixWorld );
			backgroundCamera2.matrixWorldInverse.getInverse( backgroundCamera2.matrixWorld );

			backgroundBoxMesh.material.uniforms[ "tCube" ].value = background;
			backgroundBoxMesh.modelViewMatrix.multiplyMatrices( backgroundCamera2.matrixWorldInverse, backgroundBoxMesh.matrixWorld );

1196 1197
			objects.update( backgroundBoxMesh );

M
Mr.doob 已提交
1198 1199
			_this.renderBufferDirect( backgroundCamera2, null, backgroundBoxMesh.geometry, backgroundBoxMesh.material, backgroundBoxMesh, null );

T
Takahiro 已提交
1200
		} else if ( background && background.isTexture ) {
M
Mr.doob 已提交
1201 1202 1203

			backgroundPlaneMesh.material.map = background;

1204 1205
			objects.update( backgroundPlaneMesh );

M
Mr.doob 已提交
1206 1207
			_this.renderBufferDirect( backgroundCamera, null, backgroundPlaneMesh.geometry, backgroundPlaneMesh.material, backgroundPlaneMesh, null );

M
Mr.doob 已提交
1208 1209
		}

1210
		//
M
Mr.doob 已提交
1211 1212 1213

		if ( scene.overrideMaterial ) {

1214
			var overrideMaterial = scene.overrideMaterial;
M
Mr.doob 已提交
1215

1216 1217
			renderObjects( opaqueObjects, scene, camera, overrideMaterial );
			renderObjects( transparentObjects, scene, camera, overrideMaterial );
1218

M
Mr.doob 已提交
1219 1220 1221 1222
		} else {

			// opaque pass (front-to-back order)

R
Rich Harris 已提交
1223
			state.setBlending( NoBlending );
1224
			renderObjects( opaqueObjects, scene, camera );
M
Mr.doob 已提交
1225 1226 1227

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

1228
			renderObjects( transparentObjects, scene, camera );
M
Mr.doob 已提交
1229 1230 1231 1232 1233

		}

		// custom render plugins (post pass)

M
Mr.doob 已提交
1234
		spritePlugin.render( scene, camera );
1235
		lensFlarePlugin.render( scene, camera, _currentViewport );
M
Mr.doob 已提交
1236 1237 1238

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

M
Mr.doob 已提交
1239 1240
		if ( renderTarget ) {

1241
			textures.updateRenderTargetMipmap( renderTarget );
M
Mr.doob 已提交
1242 1243 1244

		}

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

M
Mr.doob 已提交
1247 1248
		state.setDepthTest( true );
		state.setDepthWrite( true );
1249
		state.setColorWrite( true );
M
Mr.doob 已提交
1250 1251 1252 1253

		// _gl.finish();

	};
M
Mr.doob 已提交
1254

M
Mr.doob 已提交
1255 1256
	function pushRenderItem( object, geometry, material, z, group ) {

1257
		var array, index;
M
Mr.doob 已提交
1258

1259
		// allocate the next position in the appropriate array
M
Mr.doob 已提交
1260 1261 1262

		if ( material.transparent ) {

1263 1264
			array = transparentObjects;
			index = ++ transparentObjectsLastIndex;
M
Mr.doob 已提交
1265 1266 1267

		} else {

1268 1269 1270 1271 1272
			array = opaqueObjects;
			index = ++ opaqueObjectsLastIndex;

		}

1273 1274
		// recycle existing render item or grow the array

1275 1276 1277 1278 1279 1280 1281 1282 1283 1284
		var renderItem = array[ index ];

		if ( renderItem !== undefined ) {

			renderItem.id = object.id;
			renderItem.object = object;
			renderItem.geometry = geometry;
			renderItem.material = material;
			renderItem.z = _vector3.z;
			renderItem.group = group;
M
Mr.doob 已提交
1285 1286 1287

		} else {

1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298
			renderItem = {
				id: object.id,
				object: object,
				geometry: geometry,
				material: material,
				z: _vector3.z,
				group: group
			};

			// assert( index === array.length );
			array.push( renderItem );
M
Mr.doob 已提交
1299 1300 1301 1302 1303

		}

	}

M
Mr.doob 已提交
1304 1305
	// TODO Duplicated code (Frustum)

T
tschw 已提交
1306 1307 1308 1309 1310 1311 1312
	function isObjectViewable( object ) {

		var geometry = object.geometry;

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

M
Mr.doob 已提交
1313
		_sphere.copy( geometry.boundingSphere ).
1314
		applyMatrix4( object.matrixWorld );
M
Mr.doob 已提交
1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330

		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 已提交
1331 1332

		if ( ! _frustum.intersectsSphere( sphere ) ) return false;
T
tschw 已提交
1333 1334 1335 1336

		var numPlanes = _clipping.numPlanes;

		if ( numPlanes === 0 ) return true;
T
tschw 已提交
1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348

		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 已提交
1349
		} while ( ++ i !== numPlanes );
T
tschw 已提交
1350 1351 1352 1353 1354

		return true;

	}

1355
	function projectObject( object, camera ) {
M
Mr.doob 已提交
1356

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

1359
		var visible = ( object.layers.mask & camera.layers.mask ) !== 0;
M
Mr.doob 已提交
1360

1361 1362 1363
		if ( visible ) {

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

1365
				lights.push( object );
M
Mr.doob 已提交
1366

1367
			} else if ( object.isSprite ) {
M
Mr.doob 已提交
1368

M
Mr.doob 已提交
1369
				if ( object.frustumCulled === false || isSpriteViewable( object ) === true ) {
1370 1371 1372 1373

					sprites.push( object );

				}
M
Mr.doob 已提交
1374

1375
			} else if ( object.isLensFlare ) {
M
Mr.doob 已提交
1376

1377
				lensFlares.push( object );
M
Mr.doob 已提交
1378

1379
			} else if ( object.isImmediateRenderObject ) {
M
Mr.doob 已提交
1380

1381
				if ( _this.sortObjects === true ) {
M
Mr.doob 已提交
1382

1383 1384
					_vector3.setFromMatrixPosition( object.matrixWorld );
					_vector3.applyProjection( _projScreenMatrix );
M
Mr.doob 已提交
1385

1386
				}
1387

1388
				pushRenderItem( object, null, object.material, _vector3.z, null );
M
Mr.doob 已提交
1389

1390
			} else if ( object.isMesh || object.isLine || object.isPoints ) {
M
Mr.doob 已提交
1391

1392
				if ( object.isSkinnedMesh ) {
M
Mr.doob 已提交
1393

1394
					object.skeleton.update();
1395

1396
				}
1397

T
tschw 已提交
1398
				if ( object.frustumCulled === false || isObjectViewable( object ) === true ) {
1399

1400
					var material = object.material;
1401

1402
					if ( material.visible === true ) {
M
Mr.doob 已提交
1403

1404
						if ( _this.sortObjects === true ) {
M
Mr.doob 已提交
1405

1406 1407 1408 1409
							_vector3.setFromMatrixPosition( object.matrixWorld );
							_vector3.applyProjection( _projScreenMatrix );

						}
M
Mr.doob 已提交
1410

1411
						var geometry = objects.update( object );
M
Mr.doob 已提交
1412

1413
						if ( material.isMultiMaterial ) {
1414

1415 1416
							var groups = geometry.groups;
							var materials = material.materials;
1417

1418
							for ( var i = 0, l = groups.length; i < l; i ++ ) {
1419

1420 1421
								var group = groups[ i ];
								var groupMaterial = materials[ group.materialIndex ];
1422

1423
								if ( groupMaterial.visible === true ) {
1424

1425 1426 1427
									pushRenderItem( object, geometry, groupMaterial, _vector3.z, group );

								}
M
Mr.doob 已提交
1428

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

1431
						} else {
M
Mr.doob 已提交
1432

1433
							pushRenderItem( object, geometry, material, _vector3.z, null );
1434

1435
						}
O
OpenShift guest 已提交
1436

1437
					}
M
Mr.doob 已提交
1438

1439
				}
M
Mr.doob 已提交
1440

1441
			}
M
Mr.doob 已提交
1442

M
Mr.doob 已提交
1443
		}
M
Mr.doob 已提交
1444

M
Mr.doob 已提交
1445
		var children = object.children;
M
Mr.doob 已提交
1446

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

1449
			projectObject( children[ i ], camera );
M
Mr.doob 已提交
1450

1451
		}
1452

1453
	}
M
Mr.doob 已提交
1454

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

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

1459
			var renderItem = renderList[ i ];
M
Mr.doob 已提交
1460

1461
			var object = renderItem.object;
M
Mr.doob 已提交
1462 1463 1464
			var geometry = renderItem.geometry;
			var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;
			var group = renderItem.group;
M
Mr.doob 已提交
1465

1466 1467
			object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
			object.normalMatrix.getNormalMatrix( object.modelViewMatrix );
M
Mr.doob 已提交
1468

1469
			object.onBeforeRender( _this, scene, camera, geometry, material, group );
1470

1471
			if ( object.isImmediateRenderObject ) {
M
Mr.doob 已提交
1472

M
Mr.doob 已提交
1473
				setMaterial( material );
M
Mr.doob 已提交
1474

1475
				var program = setProgram( camera, scene.fog, material, object );
M
Mr.doob 已提交
1476

M
Mr.doob 已提交
1477
				_currentGeometryProgram = '';
M
Mr.doob 已提交
1478

M
Mr.doob 已提交
1479
				object.render( function ( object ) {
M
Mr.doob 已提交
1480

M
Mr.doob 已提交
1481
					_this.renderBufferImmediate( object, program, material );
M
Mr.doob 已提交
1482

M
Mr.doob 已提交
1483
				} );
1484

M
Mr.doob 已提交
1485
			} else {
M
Mr.doob 已提交
1486

1487
				_this.renderBufferDirect( camera, scene.fog, geometry, material, object, group );
M
Mr.doob 已提交
1488

M
Mr.doob 已提交
1489
			}
M
Mr.doob 已提交
1490

1491
			object.onAfterRender( _this, scene, camera, geometry, material, group );
D
Dusan Bosnjak 已提交
1492 1493


1494
		}
M
Mr.doob 已提交
1495

1496
	}
G
gero3 已提交
1497

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

1500
		var materialProperties = properties.get( material );
G
gero3 已提交
1501

T
tschw 已提交
1502
		var parameters = programCache.getParameters(
1503
			material, _lights, fog, _clipping.numPlanes, _clipping.numIntersection, object );
T
tschw 已提交
1504

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

1507
		var program = materialProperties.program;
T
tschw 已提交
1508
		var programChange = true;
1509

1510
		if ( program === undefined ) {
B
Ben Adams 已提交
1511

M
Mr.doob 已提交
1512 1513
			// new material
			material.addEventListener( 'dispose', onMaterialDispose );
B
Ben Adams 已提交
1514

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

M
Mr.doob 已提交
1517
			// changed glsl or parameters
1518
			releaseMaterialProgramReference( material );
B
Ben Adams 已提交
1519

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

T
tschw 已提交
1522
			// same glsl and uniform list
T
tschw 已提交
1523 1524
			return;

T
tschw 已提交
1525
		} else {
B
Ben Adams 已提交
1526

T
tschw 已提交
1527 1528
			// only rebuild uniform list
			programChange = false;
B
Ben Adams 已提交
1529 1530 1531

		}

1532
		if ( programChange ) {
B
Ben Adams 已提交
1533

1534
			if ( parameters.shaderID ) {
B
Ben Adams 已提交
1535

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

1538 1539
				materialProperties.__webglShader = {
					name: material.type,
M
Mr.doob 已提交
1540
					uniforms: Object.assign( {}, shader.uniforms ),
1541 1542 1543
					vertexShader: shader.vertexShader,
					fragmentShader: shader.fragmentShader
				};
B
Ben Adams 已提交
1544

1545
			} else {
B
Ben Adams 已提交
1546

1547 1548 1549 1550 1551 1552
				materialProperties.__webglShader = {
					name: material.type,
					uniforms: material.uniforms,
					vertexShader: material.vertexShader,
					fragmentShader: material.fragmentShader
				};
G
gero3 已提交
1553

1554
			}
G
gero3 已提交
1555

1556
			material.__webglShader = materialProperties.__webglShader;
G
gero3 已提交
1557

1558
			program = programCache.acquireProgram( material, parameters, code );
B
Ben Adams 已提交
1559

1560 1561
			materialProperties.program = program;
			material.program = program;
1562 1563 1564

		}

1565
		var attributes = program.getAttributes();
M
Mr.doob 已提交
1566 1567 1568 1569 1570

		if ( material.morphTargets ) {

			material.numSupportedMorphTargets = 0;

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

M
Mr.doob 已提交
1573
				if ( attributes[ 'morphTarget' + i ] >= 0 ) {
M
Mr.doob 已提交
1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586

					material.numSupportedMorphTargets ++;

				}

			}

		}

		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

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

M
Mr.doob 已提交
1589
				if ( attributes[ 'morphNormal' + i ] >= 0 ) {
M
Mr.doob 已提交
1590 1591 1592 1593 1594 1595 1596 1597 1598

					material.numSupportedMorphNormals ++;

				}

			}

		}

T
tschw 已提交
1599 1600
		var uniforms = materialProperties.__webglShader.uniforms;

1601
		if ( ! material.isShaderMaterial &&
1602 1603
			! material.isRawShaderMaterial ||
			material.clipping === true ) {
T
tschw 已提交
1604

T
tschw 已提交
1605
			materialProperties.numClippingPlanes = _clipping.numPlanes;
1606
			materialProperties.numIntersection = _clipping.numIntersection;
T
tschw 已提交
1607
			uniforms.clippingPlanes = _clipping.uniform;
T
tschw 已提交
1608 1609 1610

		}

1611
		materialProperties.fog = fog;
1612

1613
		// store the light setup it was created for
1614

1615
		materialProperties.lightsHash = _lights.hash;
1616

M
Mr.doob 已提交
1617
		if ( material.lights ) {
1618 1619 1620 1621 1622 1623

			// 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;
1624
			uniforms.rectAreaLights.value = _lights.rectArea;
M
Mr.doob 已提交
1625
			uniforms.pointLights.value = _lights.point;
1626 1627
			uniforms.hemisphereLights.value = _lights.hemi;

1628 1629 1630 1631 1632 1633
			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;
1634
			// TODO (abelnation): add area lights shadow info to uniforms
1635

1636 1637
		}

T
tschw 已提交
1638 1639
		var progUniforms = materialProperties.program.getUniforms(),
			uniformsList =
1640
				WebGLUniforms.seqWithValue( progUniforms.seq, uniforms );
A
arose 已提交
1641

T
tschw 已提交
1642
		materialProperties.uniformsList = uniformsList;
A
arose 已提交
1643

M
Mr.doob 已提交
1644
	}
M
Mr.doob 已提交
1645

1646 1647
	function setMaterial( material ) {

M
Mr.doob 已提交
1648 1649 1650
		material.side === DoubleSide
			? state.disable( _gl.CULL_FACE )
			: state.enable( _gl.CULL_FACE );
T
tschw 已提交
1651

R
Rich Harris 已提交
1652
		state.setFlipSided( material.side === BackSide );
M
Mr.doob 已提交
1653

M
Mr.doob 已提交
1654 1655 1656
		material.transparent === true
			? state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha )
			: state.setBlending( NoBlending );
1657

B
Ben Adams 已提交
1658
		state.setDepthFunc( material.depthFunc );
M
Mr.doob 已提交
1659 1660
		state.setDepthTest( material.depthTest );
		state.setDepthWrite( material.depthWrite );
1661
		state.setColorWrite( material.colorWrite );
M
Mr.doob 已提交
1662
		state.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
1663 1664 1665

	}

1666
	function setProgram( camera, fog, material, object ) {
M
Mr.doob 已提交
1667 1668 1669

		_usedTextureUnits = 0;

1670
		var materialProperties = properties.get( material );
1671

T
tschw 已提交
1672 1673 1674 1675 1676
		if ( _clippingEnabled ) {

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

				var useCache =
1677 1678
					camera === _currentCamera &&
					material.id === _currentMaterialId;
T
tschw 已提交
1679 1680 1681 1682

				// we might want to call this function with some ClippingGroup
				// object instead of the material, once it becomes feasible
				// (#8465, #8379)
T
tschw 已提交
1683
				_clipping.setState(
1684 1685
					material.clippingPlanes, material.clipIntersection, material.clipShadows,
					camera, materialProperties, useCache );
T
tschw 已提交
1686 1687 1688 1689 1690

			}

		}

1691
		if ( material.needsUpdate === false ) {
1692

1693
			if ( materialProperties.program === undefined ) {
1694

1695
				material.needsUpdate = true;
1696

1697
			} else if ( material.fog && materialProperties.fog !== fog ) {
1698

M
Mr.doob 已提交
1699
				material.needsUpdate = true;
1700

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

1703
				material.needsUpdate = true;
1704

1705
			} else if ( materialProperties.numClippingPlanes !== undefined &&
1706
				( materialProperties.numClippingPlanes !== _clipping.numPlanes ||
1707
				materialProperties.numIntersection  !== _clipping.numIntersection ) ) {
1708 1709 1710

				material.needsUpdate = true;

1711
			}
1712 1713 1714 1715

		}

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

1717
			initMaterial( material, fog, object );
M
Mr.doob 已提交
1718 1719 1720 1721
			material.needsUpdate = false;

		}

1722
		var refreshProgram = false;
M
Mr.doob 已提交
1723
		var refreshMaterial = false;
1724
		var refreshLights = false;
M
Mr.doob 已提交
1725

1726
		var program = materialProperties.program,
1727
			p_uniforms = program.getUniforms(),
1728
			m_uniforms = materialProperties.__webglShader.uniforms;
M
Mr.doob 已提交
1729

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

1732 1733
			_gl.useProgram( program.program );
			_currentProgram = program.id;
M
Mr.doob 已提交
1734

1735
			refreshProgram = true;
M
Mr.doob 已提交
1736
			refreshMaterial = true;
1737
			refreshLights = true;
M
Mr.doob 已提交
1738 1739 1740 1741 1742 1743

		}

		if ( material.id !== _currentMaterialId ) {

			_currentMaterialId = material.id;
1744

M
Mr.doob 已提交
1745 1746 1747 1748
			refreshMaterial = true;

		}

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

T
tschw 已提交
1751
			p_uniforms.set( _gl, camera, 'projectionMatrix' );
M
Mr.doob 已提交
1752

G
gero3 已提交
1753
			if ( capabilities.logarithmicDepthBuffer ) {
1754

T
tschw 已提交
1755
				p_uniforms.setValue( _gl, 'logDepthBufFC',
1756
					2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
1757 1758 1759 1760

			}


1761 1762 1763 1764 1765 1766 1767 1768 1769
			if ( camera !== _currentCamera ) {

				_currentCamera = camera;

				// 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 已提交
1770
				refreshLights = true;		// remains set until update done
1771 1772

			}
M
Mr.doob 已提交
1773

1774 1775 1776
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)

1777
			if ( material.isShaderMaterial ||
1778
				material.isMeshPhongMaterial ||
T
Takahiro 已提交
1779
				material.isMeshToonMaterial ||
1780 1781
				material.isMeshStandardMaterial ||
				material.envMap ) {
1782

T
tschw 已提交
1783 1784 1785
				var uCamPos = p_uniforms.map.cameraPosition;

				if ( uCamPos !== undefined ) {
1786

T
tschw 已提交
1787
					uCamPos.setValue( _gl,
1788
						_vector3.setFromMatrixPosition( camera.matrixWorld ) );
1789 1790 1791 1792 1793

				}

			}

1794
			if ( material.isMeshPhongMaterial ||
T
Takahiro 已提交
1795
				material.isMeshToonMaterial ||
1796 1797 1798 1799 1800
				material.isMeshLambertMaterial ||
				material.isMeshBasicMaterial ||
				material.isMeshStandardMaterial ||
				material.isShaderMaterial ||
				material.skinning ) {
1801

T
tschw 已提交
1802
				p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );
1803 1804 1805

			}

T
tschw 已提交
1806 1807
			p_uniforms.set( _gl, _this, 'toneMappingExposure' );
			p_uniforms.set( _gl, _this, 'toneMappingWhitePoint' );
M
Mr.doob 已提交
1808

M
Mr.doob 已提交
1809 1810 1811 1812 1813 1814 1815 1816
		}

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

		if ( material.skinning ) {

T
tschw 已提交
1817 1818
			p_uniforms.setOptional( _gl, object, 'bindMatrix' );
			p_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );
1819

T
tschw 已提交
1820
			var skeleton = object.skeleton;
1821

T
tschw 已提交
1822
			if ( skeleton ) {
1823

T
tschw 已提交
1824
				if ( capabilities.floatVertexTextures && skeleton.useVertexTexture ) {
M
Mr.doob 已提交
1825

T
tschw 已提交
1826 1827 1828
					p_uniforms.set( _gl, skeleton, 'boneTexture' );
					p_uniforms.set( _gl, skeleton, 'boneTextureWidth' );
					p_uniforms.set( _gl, skeleton, 'boneTextureHeight' );
M
Mr.doob 已提交
1829

T
tschw 已提交
1830
				} else {
M
Mr.doob 已提交
1831

T
tschw 已提交
1832
					p_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );
M
Mr.doob 已提交
1833 1834 1835 1836 1837 1838 1839 1840 1841

				}

			}

		}

		if ( refreshMaterial ) {

M
Mr.doob 已提交
1842
			if ( material.lights ) {
M
Mr.doob 已提交
1843

1844
				// the current material requires lighting info
M
Mr.doob 已提交
1845

T
tschw 已提交
1846 1847 1848 1849 1850 1851
				// 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 已提交
1852

T
tschw 已提交
1853
				markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
G
gero3 已提交
1854

T
tschw 已提交
1855
			}
G
gero3 已提交
1856

T
tschw 已提交
1857
			// refresh uniforms common to several materials
G
gero3 已提交
1858

T
tschw 已提交
1859
			if ( fog && material.fog ) {
G
gero3 已提交
1860

T
tschw 已提交
1861
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
1862 1863 1864

			}

1865
			if ( material.isMeshBasicMaterial ||
1866 1867
				material.isMeshLambertMaterial ||
				material.isMeshPhongMaterial ||
T
Takahiro 已提交
1868
				material.isMeshToonMaterial ||
1869 1870
				material.isMeshStandardMaterial ||
				material.isMeshDepthMaterial ) {
M
Mr.doob 已提交
1871 1872 1873 1874 1875 1876 1877

				refreshUniformsCommon( m_uniforms, material );

			}

			// refresh single material specific uniforms

1878
			if ( material.isLineBasicMaterial ) {
M
Mr.doob 已提交
1879 1880 1881

				refreshUniformsLine( m_uniforms, material );

1882
			} else if ( material.isLineDashedMaterial ) {
M
Mr.doob 已提交
1883 1884 1885 1886

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

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

M
Mr.doob 已提交
1889
				refreshUniformsPoints( m_uniforms, material );
M
Mr.doob 已提交
1890

1891
			} else if ( material.isMeshLambertMaterial ) {
1892 1893 1894

				refreshUniformsLambert( m_uniforms, material );

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

				refreshUniformsPhong( m_uniforms, material );

T
Takahiro 已提交
1899 1900 1901 1902
			} else if ( material.isMeshToonMaterial ) {

				refreshUniformsToon( m_uniforms, material );

1903
			} else if ( material.isMeshPhysicalMaterial ) {
W
WestLangley 已提交
1904 1905 1906

				refreshUniformsPhysical( m_uniforms, material );

1907
			} else if ( material.isMeshStandardMaterial ) {
W
WestLangley 已提交
1908

1909
				refreshUniformsStandard( m_uniforms, material );
W
WestLangley 已提交
1910

1911
			} else if ( material.isMeshDepthMaterial ) {
M
Mr.doob 已提交
1912

1913 1914 1915 1916 1917 1918 1919 1920
				if ( material.displacementMap ) {

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

				}

1921
			} else if ( material.isMeshNormalMaterial ) {
M
Mr.doob 已提交
1922 1923 1924 1925 1926

				m_uniforms.opacity.value = material.opacity;

			}

R
Rich Harris 已提交
1927
			WebGLUniforms.upload(
1928
				_gl, materialProperties.uniformsList, m_uniforms, _this );
A
arose 已提交
1929 1930 1931

		}

M
Mr.doob 已提交
1932

T
tschw 已提交
1933
		// common matrices
M
Mr.doob 已提交
1934

T
tschw 已提交
1935 1936 1937
		p_uniforms.set( _gl, object, 'modelViewMatrix' );
		p_uniforms.set( _gl, object, 'normalMatrix' );
		p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );
A
arose 已提交
1938

T
tschw 已提交
1939
		return program;
A
arose 已提交
1940 1941 1942

	}

M
Mr.doob 已提交
1943 1944
	// Uniforms (refresh uniforms objects)

M
Mr.doob 已提交
1945
	function refreshUniformsCommon( uniforms, material ) {
M
Mr.doob 已提交
1946 1947 1948

		uniforms.opacity.value = material.opacity;

1949
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
1950

1951
		if ( material.emissive ) {
M
Mr.doob 已提交
1952

1953
			uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );
M
Mr.doob 已提交
1954 1955 1956

		}

1957 1958 1959
		uniforms.map.value = material.map;
		uniforms.specularMap.value = material.specularMap;
		uniforms.alphaMap.value = material.alphaMap;
M
Mr.doob 已提交
1960

1961 1962 1963 1964 1965 1966 1967
		if ( material.lightMap ) {

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

		}

1968
		if ( material.aoMap ) {
1969

1970 1971
			uniforms.aoMap.value = material.aoMap;
			uniforms.aoMapIntensity.value = material.aoMapIntensity;
1972 1973 1974

		}

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

		var uvScaleMap;

		if ( material.map ) {

			uvScaleMap = material.map;

		} else if ( material.specularMap ) {

			uvScaleMap = material.specularMap;

1993 1994 1995 1996
		} else if ( material.displacementMap ) {

			uvScaleMap = material.displacementMap;

M
Mr.doob 已提交
1997 1998 1999 2000 2001 2002 2003 2004
		} else if ( material.normalMap ) {

			uvScaleMap = material.normalMap;

		} else if ( material.bumpMap ) {

			uvScaleMap = material.bumpMap;

2005 2006 2007 2008 2009 2010 2011 2012
		} else if ( material.roughnessMap ) {

			uvScaleMap = material.roughnessMap;

		} else if ( material.metalnessMap ) {

			uvScaleMap = material.metalnessMap;

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

			uvScaleMap = material.alphaMap;

2017 2018 2019 2020
		} else if ( material.emissiveMap ) {

			uvScaleMap = material.emissiveMap;

M
Mr.doob 已提交
2021 2022 2023 2024
		}

		if ( uvScaleMap !== undefined ) {

2025
			// backwards compatibility
2026
			if ( uvScaleMap.isWebGLRenderTarget ) {
M
Mr.doob 已提交
2027 2028 2029 2030 2031

				uvScaleMap = uvScaleMap.texture;

			}

M
Mr.doob 已提交
2032 2033 2034 2035 2036 2037 2038 2039
			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;
2040 2041 2042 2043 2044

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

2047
		uniforms.reflectivity.value = material.reflectivity;
M
Mr.doob 已提交
2048 2049
		uniforms.refractionRatio.value = material.refractionRatio;

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

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

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

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

M
Mr.doob 已提交
2059
	function refreshUniformsDash( uniforms, material ) {
M
Mr.doob 已提交
2060 2061 2062 2063 2064

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

M
Mr.doob 已提交
2065
	}
M
Mr.doob 已提交
2066

M
Mr.doob 已提交
2067
	function refreshUniformsPoints( uniforms, material ) {
M
Mr.doob 已提交
2068

2069
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
2070
		uniforms.opacity.value = material.opacity;
2071
		uniforms.size.value = material.size * _pixelRatio;
2072
		uniforms.scale.value = _height * 0.5;
M
Mr.doob 已提交
2073 2074 2075

		uniforms.map.value = material.map;

2076 2077 2078 2079 2080 2081 2082 2083 2084
		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 已提交
2085
	}
M
Mr.doob 已提交
2086

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

		uniforms.fogColor.value = fog.color;

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

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

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

			uniforms.fogDensity.value = fog.density;

		}

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

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

		if ( material.emissiveMap ) {

			uniforms.emissiveMap.value = material.emissiveMap;

		}

	}

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

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

2119
		if ( material.emissiveMap ) {
2120

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

2123
		}
M
Mr.doob 已提交
2124

2125 2126 2127 2128
		if ( material.bumpMap ) {

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

2130
		}
M
Mr.doob 已提交
2131

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

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

		}
M
Mr.doob 已提交
2138

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

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

2145
		}
2146

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

	function refreshUniformsToon( uniforms, material ) {

		refreshUniformsPhong( uniforms, material );

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

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

		}

2159 2160
	}

M
Mr.doob 已提交
2161
	function refreshUniformsStandard( uniforms, material ) {
W
WestLangley 已提交
2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214

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

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

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

	}

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

M
Mr.doob 已提交
2226
	function markUniformsLightsNeedsUpdate( uniforms, value ) {
2227

M
Mr.doob 已提交
2228
		uniforms.ambientLightColor.needsUpdate = value;
2229

B
Ben Houston 已提交
2230 2231 2232
		uniforms.directionalLights.needsUpdate = value;
		uniforms.pointLights.needsUpdate = value;
		uniforms.spotLights.needsUpdate = value;
2233
		uniforms.rectAreaLights.needsUpdate = value;
B
Ben Houston 已提交
2234
		uniforms.hemisphereLights.needsUpdate = value;
2235

M
Mr.doob 已提交
2236
	}
2237

T
tschw 已提交
2238
	// Lighting
M
Mr.doob 已提交
2239

M
Mr.doob 已提交
2240
	function setupShadows( lights ) {
2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259

		var lightShadowsLength = 0;

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

			var light = lights[ i ];

			if ( light.castShadow ) {

				_lights.shadows[ lightShadowsLength ++ ] = light;

			}

		}

		_lights.shadows.length = lightShadowsLength;

	}

M
Mr.doob 已提交
2260
	function setupLights( lights, camera ) {
M
Mr.doob 已提交
2261

B
brason 已提交
2262
		var l, ll, light,
2263 2264 2265 2266 2267
			r = 0, g = 0, b = 0,
			color,
			intensity,
			distance,
			shadowMap,
M
Mr.doob 已提交
2268

2269
			viewMatrix = camera.matrixWorldInverse,
M
Mr.doob 已提交
2270

M
Mr.doob 已提交
2271
		directionalLength = 0,
M
Mr.doob 已提交
2272 2273
		pointLength = 0,
		spotLength = 0,
2274
		rectAreaLength = 0,
2275
		hemiLength = 0;
M
Mr.doob 已提交
2276 2277 2278 2279 2280 2281 2282 2283 2284

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

			light = lights[ l ];

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

2285
			shadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null;
2286

2287
			if ( light.isAmbientLight ) {
M
Mr.doob 已提交
2288

2289 2290 2291
				r += color.r * intensity;
				g += color.g * intensity;
				b += color.b * intensity;
M
Mr.doob 已提交
2292

2293
			} else if ( light.isDirectionalLight ) {
M
Mr.doob 已提交
2294

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

2297
				uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
M
Mr.doob 已提交
2298
				uniforms.direction.setFromMatrixPosition( light.matrixWorld );
2299
				_vector3.setFromMatrixPosition( light.target.matrixWorld );
M
Mr.doob 已提交
2300 2301 2302
				uniforms.direction.sub( _vector3 );
				uniforms.direction.transformDirection( viewMatrix );

2303
				uniforms.shadow = light.castShadow;
M
Mr.doob 已提交
2304

2305
				if ( light.castShadow ) {
M
Mr.doob 已提交
2306

2307 2308 2309
					uniforms.shadowBias = light.shadow.bias;
					uniforms.shadowRadius = light.shadow.radius;
					uniforms.shadowMapSize = light.shadow.mapSize;
2310

2311 2312
				}

2313
				_lights.directionalShadowMap[ directionalLength ] = shadowMap;
2314
				_lights.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;
2315
				_lights.directional[ directionalLength ++ ] = uniforms;
M
Mr.doob 已提交
2316

2317
			} else if ( light.isSpotLight ) {
M
Mr.doob 已提交
2318

M
Mr.doob 已提交
2319
				var uniforms = lightCache.get( light );
M
Mr.doob 已提交
2320 2321 2322

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

M
Mr.doob 已提交
2324 2325 2326 2327 2328 2329 2330 2331
				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 );

2332 2333
				uniforms.coneCos = Math.cos( light.angle );
				uniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );
M
Mr.doob 已提交
2334
				uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;
M
Mr.doob 已提交
2335

2336
				uniforms.shadow = light.castShadow;
M
Mr.doob 已提交
2337

2338 2339
				if ( light.castShadow ) {

2340 2341 2342
					uniforms.shadowBias = light.shadow.bias;
					uniforms.shadowRadius = light.shadow.radius;
					uniforms.shadowMapSize = light.shadow.mapSize;
2343

2344 2345
				}

2346
				_lights.spotShadowMap[ spotLength ] = shadowMap;
2347
				_lights.spotShadowMatrix[ spotLength ] = light.shadow.matrix;
M
Mr.doob 已提交
2348
				_lights.spot[ spotLength ++ ] = uniforms;
2349

2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381
			} 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;

				_lights.rectArea[ rectAreaLength ++ ] = uniforms;

2382
			} else if ( light.isPointLight ) {
M
Mr.doob 已提交
2383

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

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

M
Mr.doob 已提交
2389 2390
				uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
				uniforms.distance = light.distance;
M
Mr.doob 已提交
2391 2392
				uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;

2393
				uniforms.shadow = light.castShadow;
2394

M
Mr.doob 已提交
2395
				if ( light.castShadow ) {
2396

2397 2398 2399 2400 2401
					uniforms.shadowBias = light.shadow.bias;
					uniforms.shadowRadius = light.shadow.radius;
					uniforms.shadowMapSize = light.shadow.mapSize;

				}
2402

2403
				_lights.pointShadowMap[ pointLength ] = shadowMap;
2404

2405 2406
				if ( _lights.pointShadowMatrix[ pointLength ] === undefined ) {

R
Rich Harris 已提交
2407
					_lights.pointShadowMatrix[ pointLength ] = new Matrix4();
2408

2409 2410
				}

2411 2412 2413 2414 2415
				// for point lights we set the shadow matrix to be a translation-only matrix
				// equal to inverse of the light's position
				_vector3.setFromMatrixPosition( light.matrixWorld ).negate();
				_lights.pointShadowMatrix[ pointLength ].identity().setPosition( _vector3 );

M
Mr.doob 已提交
2416
				_lights.point[ pointLength ++ ] = uniforms;
2417

2418
			} else if ( light.isHemisphereLight ) {
M
Mr.doob 已提交
2419

M
Mr.doob 已提交
2420
				var uniforms = lightCache.get( light );
M
Mr.doob 已提交
2421 2422 2423 2424

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

M
Mr.doob 已提交
2426 2427
				uniforms.skyColor.copy( light.color ).multiplyScalar( intensity );
				uniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );
M
Mr.doob 已提交
2428

M
Mr.doob 已提交
2429
				_lights.hemi[ hemiLength ++ ] = uniforms;
M
Mr.doob 已提交
2430 2431 2432 2433 2434

			}

		}

M
Mr.doob 已提交
2435 2436 2437
		_lights.ambient[ 0 ] = r;
		_lights.ambient[ 1 ] = g;
		_lights.ambient[ 2 ] = b;
M
Mr.doob 已提交
2438

M
Mr.doob 已提交
2439 2440
		_lights.directional.length = directionalLength;
		_lights.spot.length = spotLength;
2441
		_lights.rectArea.length = rectAreaLength;
2442
		_lights.point.length = pointLength;
M
Mr.doob 已提交
2443
		_lights.hemi.length = hemiLength;
2444

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

M
Mr.doob 已提交
2448
	}
M
Mr.doob 已提交
2449 2450 2451 2452 2453

	// GL state setting

	this.setFaceCulling = function ( cullFace, frontFaceDirection ) {

T
tschw 已提交
2454
		state.setCullFace( cullFace );
R
Rich Harris 已提交
2455
		state.setFlipSided( frontFaceDirection === FrontFaceDirectionCW );
M
Mr.doob 已提交
2456 2457 2458 2459 2460

	};

	// Textures

T
tschw 已提交
2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476
	function allocTextureUnit() {

		var textureUnit = _usedTextureUnits;

		if ( textureUnit >= capabilities.maxTextures ) {

			console.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures );

		}

		_usedTextureUnits += 1;

		return textureUnit;

	}

2477
	this.allocTextureUnit = allocTextureUnit;
T
tschw 已提交
2478

2479
	// this.setTexture2D = setTexture2D;
2480
	this.setTexture2D = ( function() {
T
tschw 已提交
2481

2482
		var warned = false;
T
tschw 已提交
2483

2484
		// backwards compatibility: peel texture.texture
W
WestLangley 已提交
2485
		return function setTexture2D( texture, slot ) {
T
tschw 已提交
2486

T
Takahiro 已提交
2487
			if ( texture && texture.isWebGLRenderTarget ) {
T
tschw 已提交
2488

2489
				if ( ! warned ) {
T
tschw 已提交
2490

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

2494
				}
T
tschw 已提交
2495

2496
				texture = texture.texture;
T
tschw 已提交
2497

2498
			}
T
tschw 已提交
2499

2500
			textures.setTexture2D( texture, slot );
T
tschw 已提交
2501

2502
		};
T
tschw 已提交
2503

2504
	}() );
T
tschw 已提交
2505

2506 2507 2508 2509
	this.setTexture = ( function() {

		var warned = false;

W
WestLangley 已提交
2510
		return function setTexture( texture, slot ) {
2511 2512 2513 2514 2515 2516 2517 2518

			if ( ! warned ) {

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

			}

2519
			textures.setTexture2D( texture, slot );
2520 2521 2522 2523 2524 2525 2526 2527 2528

		};

	}() );

	this.setTextureCube = ( function() {

		var warned = false;

W
WestLangley 已提交
2529
		return function setTextureCube( texture, slot ) {
2530 2531

			// backwards compatibility: peel texture.texture
T
Takahiro 已提交
2532
			if ( texture && texture.isWebGLRenderTargetCube ) {
2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546

				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 已提交
2547
			if ( ( texture && texture.isCubeTexture ) ||
2548
				( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {
2549 2550 2551 2552

				// CompressedTexture can have Array in image :/

				// this function alone should take care of cube textures
2553
				textures.setTextureCube( texture, slot );
2554 2555 2556 2557 2558

			} else {

				// assumed: texture property of THREE.WebGLRenderTargetCube

2559
				textures.setTextureCubeDynamic( texture, slot );
2560 2561 2562 2563 2564 2565

			}

		};

	}() );
T
tschw 已提交
2566

2567 2568 2569 2570
	this.getCurrentRenderTarget = function() {

		return _currentRenderTarget;

M
Michael Herzog 已提交
2571
	};
2572

2573
	this.setRenderTarget = function ( renderTarget ) {
M
Mr.doob 已提交
2574

2575 2576
		_currentRenderTarget = renderTarget;

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

2579
			textures.setupRenderTarget( renderTarget );
M
Mr.doob 已提交
2580 2581 2582

		}

T
Takahiro 已提交
2583
		var isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );
2584
		var framebuffer;
M
Mr.doob 已提交
2585 2586 2587

		if ( renderTarget ) {

2588
			var renderTargetProperties = properties.get( renderTarget );
F
Fordy 已提交
2589

M
Mr.doob 已提交
2590 2591
			if ( isCube ) {

2592
				framebuffer = renderTargetProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];
M
Mr.doob 已提交
2593 2594 2595

			} else {

2596
				framebuffer = renderTargetProperties.__webglFramebuffer;
M
Mr.doob 已提交
2597 2598 2599

			}

2600 2601
			_currentScissor.copy( renderTarget.scissor );
			_currentScissorTest = renderTarget.scissorTest;
2602

2603
			_currentViewport.copy( renderTarget.viewport );
M
Mr.doob 已提交
2604 2605 2606 2607 2608

		} else {

			framebuffer = null;

2609
			_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );
2610
			_currentScissorTest = _scissorTest;
2611

2612
			_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );
M
Mr.doob 已提交
2613 2614 2615

		}

M
Mr.doob 已提交
2616
		if ( _currentFramebuffer !== framebuffer ) {
M
Mr.doob 已提交
2617 2618 2619 2620 2621 2622

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

		}

2623 2624
		state.scissor( _currentScissor );
		state.setScissorTest( _currentScissorTest );
2625

2626
		state.viewport( _currentViewport );
2627

M
Mr.doob 已提交
2628 2629 2630
		if ( isCube ) {

			var textureProperties = properties.get( renderTarget.texture );
2631
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );
M
Mr.doob 已提交
2632 2633 2634

		}

M
Mr.doob 已提交
2635 2636
	};

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

T
Takahiro 已提交
2639
		if ( ( renderTarget && renderTarget.isWebGLRenderTarget ) === false ) {
2640

2641
			console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
G
gero3 已提交
2642
			return;
2643

G
gero3 已提交
2644
		}
2645

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

M
Mr.doob 已提交
2648
		if ( framebuffer ) {
2649

G
gero3 已提交
2650
			var restore = false;
2651

M
Mr.doob 已提交
2652
			if ( framebuffer !== _currentFramebuffer ) {
2653

M
Mr.doob 已提交
2654
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
2655

G
gero3 已提交
2656
				restore = true;
2657

G
gero3 已提交
2658
			}
2659

M
Mr.doob 已提交
2660
			try {
2661

M
Mr.doob 已提交
2662
				var texture = renderTarget.texture;
M
Mr.doob 已提交
2663 2664
				var textureFormat = texture.format;
				var textureType = texture.type;
2665

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

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

M
Mr.doob 已提交
2671
				}
2672

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

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

M
Mr.doob 已提交
2680
				}
2681

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

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

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

M
Mr.doob 已提交
2688
						_gl.readPixels( x, y, width, height, paramThreeToGL( textureFormat ), paramThreeToGL( textureType ), buffer );
2689 2690

					}
2691

M
Mr.doob 已提交
2692
				} else {
M
Mr.doob 已提交
2693

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

				}
M
Mr.doob 已提交
2697

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

M
Mr.doob 已提交
2700 2701 2702
				if ( restore ) {

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

M
Mr.doob 已提交
2704 2705 2706
				}

			}
M
Mr.doob 已提交
2707 2708 2709

		}

M
Mr.doob 已提交
2710 2711
	};

M
Mr.doob 已提交
2712 2713
	// Map three.js constants to WebGL constants

M
Mr.doob 已提交
2714
	function paramThreeToGL( p ) {
M
Mr.doob 已提交
2715

2716 2717
		var extension;

R
Rich Harris 已提交
2718 2719 2720
		if ( p === RepeatWrapping ) return _gl.REPEAT;
		if ( p === ClampToEdgeWrapping ) return _gl.CLAMP_TO_EDGE;
		if ( p === MirroredRepeatWrapping ) return _gl.MIRRORED_REPEAT;
M
Mr.doob 已提交
2721

R
Rich Harris 已提交
2722 2723 2724
		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 已提交
2725

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

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

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

2742
		if ( p === HalfFloatType ) {
2743

2744
			extension = extensions.get( 'OES_texture_half_float' );
2745

2746
			if ( extension !== null ) return extension.HALF_FLOAT_OES;
2747 2748 2749

		}

R
Rich Harris 已提交
2750 2751 2752 2753 2754 2755
		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;
2756
		if ( p === DepthStencilFormat ) return _gl.DEPTH_STENCIL;
M
Mr.doob 已提交
2757

R
Rich Harris 已提交
2758 2759 2760
		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 已提交
2761

R
Rich Harris 已提交
2762 2763 2764 2765 2766 2767 2768 2769
		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 已提交
2770

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

2775 2776
		if ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format ||
			p === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) {
M
Mr.doob 已提交
2777

2778
			extension = extensions.get( 'WEBGL_compressed_texture_s3tc' );
2779

2780 2781 2782 2783 2784 2785 2786 2787
			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 已提交
2788 2789 2790

		}

2791
		if ( p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format ||
2792
			p === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format ) {
2793

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

2796 2797 2798 2799 2800 2801 2802 2803
			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 已提交
2804 2805 2806

		}

2807
		if ( p === RGB_ETC1_Format ) {
2808

2809
			extension = extensions.get( 'WEBGL_compressed_texture_etc1' );
2810

2811
			if ( extension !== null ) return extension.COMPRESSED_RGB_ETC1_WEBGL;
2812 2813 2814

		}

2815 2816 2817
		if ( p === MinEquation || p === MaxEquation ) {

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

2819
			if ( extension !== null ) {
2820

2821 2822 2823 2824
				if ( p === MinEquation ) return extension.MIN_EXT;
				if ( p === MaxEquation ) return extension.MAX_EXT;

			}
2825 2826 2827

		}

2828
		if ( p === UnsignedInt248Type ) {
2829

2830
			extension = extensions.get( 'WEBGL_depth_texture' );
2831

2832
			if ( extension !== null ) return extension.UNSIGNED_INT_24_8_WEBGL;
2833 2834 2835

		}

M
Mr.doob 已提交
2836 2837
		return 0;

M
Mr.doob 已提交
2838
	}
M
Mr.doob 已提交
2839

M
Mr.doob 已提交
2840
}
R
Rich Harris 已提交
2841

2842
export { WebGLRenderer };