WebGLRenderer.js 68.8 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
import { Matrix4 } from '../math/Matrix4';
import { WebGLUniforms } from './webgl/WebGLUniforms';
4
import { UniformsUtils } from './shaders/UniformsUtils';
R
Rich Harris 已提交
5 6 7 8 9 10
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';
M
Mr.doob 已提交
11 12
import { BoxBufferGeometry } from '../geometries/BoxGeometry';
import { PlaneBufferGeometry } from '../geometries/PlaneGeometry';
R
Rich Harris 已提交
13 14 15
import { MeshBasicMaterial } from '../materials/MeshBasicMaterial';
import { PerspectiveCamera } from '../cameras/PerspectiveCamera';
import { OrthographicCamera } from '../cameras/OrthographicCamera';
16
import { WebGLAttributes } from './webgl/WebGLAttributes';
R
Rich Harris 已提交
17 18
import { WebGLIndexedBufferRenderer } from './webgl/WebGLIndexedBufferRenderer';
import { WebGLBufferRenderer } from './webgl/WebGLBufferRenderer';
19
import { WebGLGeometries } from './webgl/WebGLGeometries';
R
Rich Harris 已提交
20 21
import { WebGLLights } from './webgl/WebGLLights';
import { WebGLObjects } from './webgl/WebGLObjects';
22
import { WebGLPrograms } from './webgl/WebGLPrograms';
R
Rich Harris 已提交
23 24 25 26 27 28 29
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';
M
Mr.doob 已提交
30
// import { Sphere } from '../math/Sphere';
R
Rich Harris 已提交
31 32 33 34 35
import { WebGLClipping } from './webgl/WebGLClipping';
import { Frustum } from '../math/Frustum';
import { Vector4 } from '../math/Vector4';
import { Color } from '../math/Color';

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

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

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

	parameters = parameters || {};

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

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

M
Mr.doob 已提交
60
	var lights = [];
M
Mr.doob 已提交
61

O
OpenShift guest 已提交
62
	var opaqueObjects = [];
M
Mr.doob 已提交
63
	var opaqueObjectsLastIndex = - 1;
64
	var transparentObjects = [];
M
Mr.doob 已提交
65
	var transparentObjectsLastIndex = - 1;
66

67 68
	var morphInfluences = new Float32Array( 8 );

M
Mr.doob 已提交
69 70 71
	var sprites = [];
	var lensFlares = [];

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

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

M
Mr.doob 已提交
93 94
	// physically based shading

95
	this.gammaFactor = 2.0;	// for backwards compatibility
M
Mr.doob 已提交
96 97 98
	this.gammaInput = false;
	this.gammaOutput = false;

99 100
	// physical lights

101
	this.physicallyCorrectLights = false;
102

B
Ben Houston 已提交
103 104
	// tone mapping

R
Rich Harris 已提交
105
	this.toneMapping = LinearToneMapping;
B
Ben Houston 已提交
106 107 108
	this.toneMappingExposure = 1.0;
	this.toneMappingWhitePoint = 1.0;

M
Mr.doob 已提交
109 110 111 112 113 114 115 116 117
	// morphs

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

	// internal properties

	var _this = this,

118
		// internal state cache
M
Mr.doob 已提交
119

120 121 122 123 124 125
		_currentProgram = null,
		_currentRenderTarget = null,
		_currentFramebuffer = null,
		_currentMaterialId = - 1,
		_currentGeometryProgram = '',
		_currentCamera = null,
M
Mr.doob 已提交
126

127 128
		_currentScissor = new Vector4(),
		_currentScissorTest = null,
129

130
		_currentViewport = new Vector4(),
131

132
		//
133

134
		_usedTextureUnits = 0,
M
Mr.doob 已提交
135

136
		//
M
Mr.doob 已提交
137

138 139
		_clearColor = new Color( 0x000000 ),
		_clearAlpha = 0,
M
Mr.doob 已提交
140

141 142
		_width = _canvas.width,
		_height = _canvas.height,
M
Mr.doob 已提交
143

144
		_pixelRatio = 1,
M
Mr.doob 已提交
145

146 147
		_scissor = new Vector4( 0, 0, _width, _height ),
		_scissorTest = false,
148

149
		_viewport = new Vector4( 0, 0, _width, _height ),
150

151
		// frustum
M
Mr.doob 已提交
152

153
		_frustum = new Frustum(),
M
Mr.doob 已提交
154

155
		// clipping
T
tschw 已提交
156

157 158 159
		_clipping = new WebGLClipping(),
		_clippingEnabled = false,
		_localClippingEnabled = false,
T
tschw 已提交
160

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

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

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

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

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

173
			hash: '',
174

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

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

190
		},
191

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

M
Mr.doob 已提交
194 195 196 197 198
		_infoMemory = {
			geometries: 0,
			textures: 0
		},

199
		_infoRender = {
200

201
			frame: 0,
202 203 204 205
			calls: 0,
			vertices: 0,
			faces: 0,
			points: 0
206

207
		};
M
Mr.doob 已提交
208

M
Mr.doob 已提交
209
	this.info = {
210

M
Mr.doob 已提交
211
		render: _infoRender,
M
Mr.doob 已提交
212
		memory: _infoMemory,
213
		programs: null
M
Mr.doob 已提交
214 215

	};
216

217

M
Mr.doob 已提交
218 219 220 221
	// initialize

	var _gl;

M
Mr.doob 已提交
222 223
	try {

224
		var contextAttributes = {
M
Mr.doob 已提交
225 226 227 228 229 230 231 232
			alpha: _alpha,
			depth: _depth,
			stencil: _stencil,
			antialias: _antialias,
			premultipliedAlpha: _premultipliedAlpha,
			preserveDrawingBuffer: _preserveDrawingBuffer
		};

233
		_gl = _context || _canvas.getContext( 'webgl', contextAttributes ) || _canvas.getContext( 'experimental-webgl', contextAttributes );
M
Mr.doob 已提交
234 235 236

		if ( _gl === null ) {

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

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

			} else {

				throw 'Error creating WebGL context.';

			}
M
Mr.doob 已提交
246 247 248

		}

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

		if ( _gl.getShaderPrecisionFormat === undefined ) {

			_gl.getShaderPrecisionFormat = function () {

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

			};

		}

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

M
Mr.doob 已提交
263 264
	} catch ( error ) {

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

	}

R
Rich Harris 已提交
269
	var extensions = new WebGLExtensions( _gl );
270

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

279 280
	if ( extensions.get( 'OES_element_index_uint' ) ) {

R
Rich Harris 已提交
281
		BufferGeometry.MaxIndex = 4294967296;
282 283 284

	}

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

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

R
Rich Harris 已提交
289
	var properties = new WebGLProperties();
M
Mr.doob 已提交
290
	var textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, _infoMemory );
M
Mr.doob 已提交
291
	var attributes = new WebGLAttributes( _gl );
M
Mr.doob 已提交
292
	var geometries = new WebGLGeometries( _gl, attributes, _infoMemory );
293
	var objects = new WebGLObjects( _gl, geometries, _infoRender );
R
Rich Harris 已提交
294 295
	var programCache = new WebGLPrograms( this, capabilities );
	var lightCache = new WebGLLights();
296

297 298
	this.info.programs = programCache.programs;

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

M
Mr.doob 已提交
302 303
	//

M
Mr.doob 已提交
304 305
	var backgroundPlaneCamera, backgroundPlaneMesh;
	var backgroundBoxCamera, backgroundBoxMesh;
M
Mr.doob 已提交
306 307 308

	//

309 310
	function getTargetPixelRatio() {

311
		return _currentRenderTarget === null ? _pixelRatio : 1;
312 313 314

	}

315
	function setDefaultGLState() {
M
Mr.doob 已提交
316

M
Mr.doob 已提交
317
		state.init();
M
Mr.doob 已提交
318

319 320
		state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );
		state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );
M
Mr.doob 已提交
321

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

324
	}
325

326
	function resetGLState() {
327 328 329 330

		_currentProgram = null;
		_currentCamera = null;

331
		_currentGeometryProgram = '';
332 333
		_currentMaterialId = - 1;

M
Mr.doob 已提交
334 335
		state.reset();

336
	}
M
Mr.doob 已提交
337 338 339 340

	setDefaultGLState();

	this.context = _gl;
M
Mr.doob 已提交
341
	this.capabilities = capabilities;
342
	this.extensions = extensions;
343
	this.properties = properties;
M
Mr.doob 已提交
344
	this.state = state;
M
Mr.doob 已提交
345

M
Mr.doob 已提交
346 347
	// shadow map

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

350
	this.shadowMap = shadowMap;
M
Mr.doob 已提交
351

M
Mr.doob 已提交
352

M
Mr.doob 已提交
353 354
	// Plugins

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

M
Mr.doob 已提交
358 359 360 361 362 363 364 365
	// API

	this.getContext = function () {

		return _gl;

	};

366 367 368 369 370 371
	this.getContextAttributes = function () {

		return _gl.getContextAttributes();

	};

372 373 374 375 376 377
	this.forceContextLoss = function () {

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

	};

378
	this.getMaxAnisotropy = function () {
379

380
		return capabilities.getMaxAnisotropy();
381

382
	};
M
Mr.doob 已提交
383 384 385

	this.getPrecision = function () {

G
gero3 已提交
386
		return capabilities.precision;
M
Mr.doob 已提交
387 388 389

	};

390 391
	this.getPixelRatio = function () {

392
		return _pixelRatio;
393 394 395 396 397

	};

	this.setPixelRatio = function ( value ) {

398 399 400 401 402
		if ( value === undefined ) return;

		_pixelRatio = value;

		this.setSize( _viewport.z, _viewport.w, false );
403 404 405

	};

406 407 408
	this.getSize = function () {

		return {
409 410
			width: _width,
			height: _height
411 412 413 414
		};

	};

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

417 418 419
		_width = width;
		_height = height;

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

423
		if ( updateStyle !== false ) {
424

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

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

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

	};

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

436
		state.viewport( _viewport.set( x, y, width, height ) );
M
Mr.doob 已提交
437 438 439

	};

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

442
		state.scissor( _scissor.set( x, y, width, height ) );
M
Mr.doob 已提交
443 444 445

	};

446 447
	this.setScissorTest = function ( boolean ) {

448
		state.setScissorTest( _scissorTest = boolean );
M
Mr.doob 已提交
449 450 451 452 453

	};

	// Clearing

M
Mr.doob 已提交
454
	this.getClearColor = function () {
M
Mr.doob 已提交
455

M
Mr.doob 已提交
456
		return _clearColor;
M
Mr.doob 已提交
457 458 459

	};

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

M
Mr.doob 已提交
462
		_clearColor.set( color );
463

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

466
		state.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );
M
Mr.doob 已提交
467 468 469

	};

M
Mr.doob 已提交
470
	this.getClearAlpha = function () {
M
Mr.doob 已提交
471

M
Mr.doob 已提交
472
		return _clearAlpha;
M
Mr.doob 已提交
473 474 475

	};

M
Mr.doob 已提交
476
	this.setClearAlpha = function ( alpha ) {
M
Mr.doob 已提交
477

M
Mr.doob 已提交
478
		_clearAlpha = alpha;
M
Mr.doob 已提交
479

480
		state.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );
M
Mr.doob 已提交
481 482 483 484 485 486 487 488 489 490 491 492

	};

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

	};

	this.clearColor = function () {

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

	};

	this.clearDepth = function () {

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

	};

	this.clearStencil = function () {

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

	};

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

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

	};

M
Mr.doob 已提交
521 522
	// Reset

523
	this.resetGLState = resetGLState;
M
Mr.doob 已提交
524

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

527
		transparentObjects = [];
M
Mr.doob 已提交
528
		transparentObjectsLastIndex = - 1;
529
		opaqueObjects = [];
M
Mr.doob 已提交
530
		opaqueObjectsLastIndex = - 1;
531

D
dubejf 已提交
532 533 534 535
		_canvas.removeEventListener( 'webglcontextlost', onContextLost, false );

	};

M
Mr.doob 已提交
536
	// Events
M
Mr.doob 已提交
537

D
dubejf 已提交
538 539 540 541 542 543 544 545
	function onContextLost( event ) {

		event.preventDefault();

		resetGLState();
		setDefaultGLState();

		properties.clear();
546
		objects.clear();
D
dubejf 已提交
547

M
Mr.doob 已提交
548
	}
D
dubejf 已提交
549

550
	function onMaterialDispose( event ) {
M
Mr.doob 已提交
551 552 553 554 555 556 557

		var material = event.target;

		material.removeEventListener( 'dispose', onMaterialDispose );

		deallocateMaterial( material );

558
	}
M
Mr.doob 已提交
559 560 561

	// Buffer deallocation

562
	function deallocateMaterial( material ) {
M
Mr.doob 已提交
563

564 565
		releaseMaterialProgramReference( material );

566
		properties.remove( material );
567

568
	}
569 570


571
	function releaseMaterialProgramReference( material ) {
572

573
		var programInfo = properties.get( material ).program;
M
Mr.doob 已提交
574 575 576

		material.program = undefined;

577
		if ( programInfo !== undefined ) {
M
Mr.doob 已提交
578

579
			programCache.releaseProgram( programInfo );
M
Mr.doob 已提交
580

M
Mr.doob 已提交
581 582
		}

583
	}
M
Mr.doob 已提交
584 585 586

	// Buffer rendering

M
Mr.doob 已提交
587 588 589 590 591 592 593 594 595 596
	function renderObjectImmediate( object, program, material ) {

		object.render( function ( object ) {

			_this.renderBufferImmediate( object, program, material );

		} );

	}

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

599
		state.initAttributes();
600

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

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

608
		var programAttributes = program.getAttributes();
609

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

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

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

		}

		if ( object.hasNormals ) {

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

624
			if ( ! material.isMeshPhongMaterial &&
625
				! material.isMeshStandardMaterial &&
626
				! material.isMeshNormalMaterial &&
627
				material.shading === FlatShading ) {
M
Mr.doob 已提交
628

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

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

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

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

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

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

				}

			}

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

655
			state.enableAttribute( programAttributes.normal );
656

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

		}

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

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

666
			state.enableAttribute( programAttributes.uv );
667

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

		}

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

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

677
			state.enableAttribute( programAttributes.color );
678

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

		}

683
		state.disableUnusedAttributes();
684

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

		object.count = 0;

	};

M
Mr.doob 已提交
691 692
	var program, geometryProgram, updateBuffers;

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

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

M
Mr.doob 已提交
697 698
		program = setProgram( camera, fog, material, object );
		geometryProgram = geometry.id + '_' + program.id + '_' + material.wireframe;
M
Mr.doob 已提交
699

M
Mr.doob 已提交
700
		updateBuffers = false;
M
Mr.doob 已提交
701 702 703 704 705 706 707 708 709 710 711 712 713 714

		if ( geometryProgram !== _currentGeometryProgram ) {

			_currentGeometryProgram = geometryProgram;
			updateBuffers = true;

		}

		// morph targets

		var morphTargetInfluences = object.morphTargetInfluences;

		if ( morphTargetInfluences !== undefined ) {

M
Mr.doob 已提交
715 716
			// TODO Remove allocations

M
Mr.doob 已提交
717 718 719 720 721 722 723 724 725
			var activeInfluences = [];

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

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

			}

726
			activeInfluences.sort( absNumericalSort );
M
Mr.doob 已提交
727 728 729 730 731 732 733

			if ( activeInfluences.length > 8 ) {

				activeInfluences.length = 8;

			}

734 735
			var morphAttributes = geometry.morphAttributes;

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

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

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

743
					var index = influence[ 1 ];
M
Mr.doob 已提交
744

745 746
					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 已提交
747 748 749

				} else {

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

				}

			}

757 758 759 760 761 762
			for ( var i = activeInfluences.length, il = morphInfluences.length; i < il; i ++ ) {

				morphInfluences[ i ] = 0.0;

			}

M
Mr.doob 已提交
763
			program.getUniforms().setValue( _gl, 'morphTargetInfluences', morphInfluences );
M
Mr.doob 已提交
764 765 766 767 768

			updateBuffers = true;

		}

769 770
		//

771
		var index = geometry.index;
772
		var position = geometry.attributes.position;
773
		var rangeFactor = 1;
774

775 776
		if ( material.wireframe === true ) {

777
			index = geometries.getWireframeAttribute( geometry );
778
			rangeFactor = 2;
779 780 781

		}

M
Mr.doob 已提交
782
		var renderer = bufferRenderer;
783

784
		if ( index !== null ) {
785

786 787
			renderer = indexedBufferRenderer;
			renderer.setIndex( index );
788

789
		}
M
Mr.doob 已提交
790

791
		if ( updateBuffers ) {
M
Mr.doob 已提交
792

793
			setupVertexAttributes( material, program, geometry );
M
Mr.doob 已提交
794

795
			if ( index !== null ) {
796

M
Mr.doob 已提交
797
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, attributes.get( index ).buffer );
798 799 800

			}

801
		}
802

803 804
		//

805
		var dataCount = 0;
806

M
Mr.doob 已提交
807
		if ( index !== null ) {
808

M
Mr.doob 已提交
809
			dataCount = index.count;
810

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

M
Mr.doob 已提交
813
			dataCount = position.count;
814

M
Mr.doob 已提交
815
		}
816

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

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

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

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

828 829
		if ( drawCount === 0 ) return;

M
Mr.doob 已提交
830
		//
831

832
		if ( object.isMesh ) {
833

834
			if ( material.wireframe === true ) {
835

836
				state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );
837
				renderer.setMode( _gl.LINES );
838

839
			} else {
M
Mr.doob 已提交
840 841

				switch ( object.drawMode ) {
842

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

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

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

				}
856

857
			}
858

859

860
		} else if ( object.isLine ) {
861

862
			var lineWidth = material.linewidth;
863

864
			if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material
865

866
			state.setLineWidth( lineWidth * getTargetPixelRatio() );
867

868
			if ( object.isLineSegments ) {
869

870
				renderer.setMode( _gl.LINES );
871

872 873 874 875
			} else if ( object.isLineLoop ) {

				renderer.setMode( _gl.LINE_LOOP );

876
			} else {
877

878
				renderer.setMode( _gl.LINE_STRIP );
879 880

			}
M
Mr.doob 已提交
881

882
		} else if ( object.isPoints ) {
883 884

			renderer.setMode( _gl.POINTS );
885 886

		}
887

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

			if ( geometry.maxInstancedCount > 0 ) {

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

J
jfranc 已提交
894
			}
895 896 897

		} else {

M
Mr.doob 已提交
898
			renderer.render( drawStart, drawCount );
899

M
Mr.doob 已提交
900 901 902 903
		}

	};

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

M
Mr.doob 已提交
906
		var extension;
B
Ben Adams 已提交
907

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

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

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

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

M
Mr.doob 已提交
917 918 919
			}

		}
B
Ben Adams 已提交
920

921 922
		if ( startIndex === undefined ) startIndex = 0;

923 924
		state.initAttributes();

925
		var geometryAttributes = geometry.attributes;
926

927
		var programAttributes = program.getAttributes();
928

929
		var materialDefaultAttributeValues = material.defaultAttributeValues;
930

931
		for ( var name in programAttributes ) {
932

933
			var programAttribute = programAttributes[ name ];
M
Mr.doob 已提交
934

M
Mr.doob 已提交
935
			if ( programAttribute >= 0 ) {
M
Mr.doob 已提交
936

937
				var geometryAttribute = geometryAttributes[ name ];
938

M
Mr.doob 已提交
939
				if ( geometryAttribute !== undefined ) {
M
Mr.doob 已提交
940

941
					var normalized = geometryAttribute.normalized;
942
					var size = geometryAttribute.itemSize;
943

944
					var attributeProperties = attributes.get( geometryAttribute );
945

M
Mr.doob 已提交
946
					var buffer = attributeProperties.buffer;
947 948
					var type = attributeProperties.type;
					var bytesPerElement = attributeProperties.bytesPerElement;
949

A
aardgoose 已提交
950
					if ( geometryAttribute.isInterleavedBufferAttribute ) {
951

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

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

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

M
Mr.doob 已提交
960
							if ( geometry.maxInstancedCount === undefined ) {
961

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

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

M
Mr.doob 已提交
966
						} else {
B
Ben Adams 已提交
967

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

M
Mr.doob 已提交
970
						}
B
Ben Adams 已提交
971

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

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

A
aardgoose 已提交
977
						if ( geometryAttribute.isInstancedBufferAttribute ) {
B
Ben Adams 已提交
978

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

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

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

M
Mr.doob 已提交
985
							}
B
Ben Adams 已提交
986

M
Mr.doob 已提交
987 988 989 990
						} else {

							state.enableAttribute( programAttribute );

M
Mr.doob 已提交
991
						}
B
Ben Adams 已提交
992

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

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

998 999
				} else if ( materialDefaultAttributeValues !== undefined ) {

T
tschw 已提交
1000
					var value = materialDefaultAttributeValues[ name ];
1001

1002
					if ( value !== undefined ) {
M
Mr.doob 已提交
1003

1004
						switch ( value.length ) {
M
Mr.doob 已提交
1005

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

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

1014 1015 1016
							case 4:
								_gl.vertexAttrib4fv( programAttribute, value );
								break;
1017

1018 1019
							default:
								_gl.vertexAttrib1fv( programAttribute, value );
1020 1021

						}
M
Mr.doob 已提交
1022 1023 1024 1025 1026 1027 1028 1029

					}

				}

			}

		}
1030

1031
		state.disableUnusedAttributes();
1032

M
Mr.doob 已提交
1033 1034
	}

M
Mr.doob 已提交
1035 1036
	// Sorting

1037
	function absNumericalSort( a, b ) {
1038

1039
		return Math.abs( b[ 0 ] ) - Math.abs( a[ 0 ] );
1040 1041 1042

	}

M
Mr.doob 已提交
1043
	function painterSortStable( a, b ) {
M
Mr.doob 已提交
1044

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

U
unconed 已提交
1047
			return a.object.renderOrder - b.object.renderOrder;
1048

1049 1050 1051 1052
		} 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 已提交
1053
		} else if ( a.material.id !== b.material.id ) {
M
Mr.doob 已提交
1054

M
Mr.doob 已提交
1055
			return a.material.id - b.material.id;
1056 1057

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

M
Mr.doob 已提交
1059
			return a.z - b.z;
M
Mr.doob 已提交
1060 1061 1062

		} else {

1063
			return a.id - b.id;
M
Mr.doob 已提交
1064 1065 1066

		}

1067
	}
M
Mr.doob 已提交
1068

M
Mr.doob 已提交
1069
	function reversePainterSortStable( a, b ) {
1070

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

U
unconed 已提交
1073
			return a.object.renderOrder - b.object.renderOrder;
1074 1075

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

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

		} else {

			return a.id - b.id;

		}

1085
	}
1086

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

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

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

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

		}

		// reset caching for this frame

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

		// update scene graph

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

		// update camera matrices and frustum

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

		camera.matrixWorldInverse.getInverse( camera.matrixWorld );

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

M
Mr.doob 已提交
1117
		lights.length = 0;
1118

M
Mr.doob 已提交
1119 1120
		opaqueObjectsLastIndex = - 1;
		transparentObjectsLastIndex = - 1;
1121

M
Mr.doob 已提交
1122 1123 1124
		sprites.length = 0;
		lensFlares.length = 0;

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

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

1130 1131 1132
		opaqueObjects.length = opaqueObjectsLastIndex + 1;
		transparentObjects.length = transparentObjectsLastIndex + 1;

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

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

1138 1139
		}

M
Mr.doob 已提交
1140
		//
M
Mr.doob 已提交
1141

T
tschw 已提交
1142
		if ( _clippingEnabled ) _clipping.beginShadows();
T
tschw 已提交
1143

1144 1145
		setupShadows( lights );

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

1148 1149
		setupLights( lights, camera );

T
tschw 已提交
1150
		if ( _clippingEnabled ) _clipping.endShadows();
T
tschw 已提交
1151

M
Mr.doob 已提交
1152 1153
		//

M
Mr.doob 已提交
1154
		_infoRender.frame ++;
1155 1156 1157 1158
		_infoRender.calls = 0;
		_infoRender.vertices = 0;
		_infoRender.faces = 0;
		_infoRender.points = 0;
M
Mr.doob 已提交
1159

1160 1161 1162 1163 1164 1165
		if ( renderTarget === undefined ) {

			renderTarget = null;

		}

M
Mr.doob 已提交
1166 1167
		this.setRenderTarget( renderTarget );

M
Mr.doob 已提交
1168 1169 1170 1171 1172 1173
		//

		var background = scene.background;

		if ( background === null ) {

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

T
Takahiro 已提交
1176
		} else if ( background && background.isColor ) {
1177

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

		}

		if ( this.autoClear || forceClear ) {

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

		}

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

M
Mr.doob 已提交
1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213
			if ( backgroundBoxCamera === undefined ) {

				backgroundBoxCamera = new PerspectiveCamera();

				backgroundBoxMesh = new Mesh(
					new BoxBufferGeometry( 5, 5, 5 ),
					new ShaderMaterial( {
						uniforms: ShaderLib.cube.uniforms,
						vertexShader: ShaderLib.cube.vertexShader,
						fragmentShader: ShaderLib.cube.fragmentShader,
						side: BackSide,
						depthTest: false,
						depthWrite: false,
						fog: false
					} )
				);

			}

			backgroundBoxCamera.projectionMatrix.copy( camera.projectionMatrix );

			backgroundBoxCamera.matrixWorld.extractRotation( camera.matrixWorld );
			backgroundBoxCamera.matrixWorldInverse.getInverse( backgroundBoxCamera.matrixWorld );
M
Mr.doob 已提交
1214 1215 1216


			backgroundBoxMesh.material.uniforms[ "tCube" ].value = background;
M
Mr.doob 已提交
1217
			backgroundBoxMesh.modelViewMatrix.multiplyMatrices( backgroundBoxCamera.matrixWorldInverse, backgroundBoxMesh.matrixWorld );
M
Mr.doob 已提交
1218

1219 1220
			objects.update( backgroundBoxMesh );

M
Mr.doob 已提交
1221
			_this.renderBufferDirect( backgroundBoxCamera, null, backgroundBoxMesh.geometry, backgroundBoxMesh.material, backgroundBoxMesh, null );
M
Mr.doob 已提交
1222

T
Takahiro 已提交
1223
		} else if ( background && background.isTexture ) {
M
Mr.doob 已提交
1224

M
Mr.doob 已提交
1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235
			if ( backgroundPlaneCamera === undefined ) {

				backgroundPlaneCamera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );

				backgroundPlaneMesh = new Mesh(
					new PlaneBufferGeometry( 2, 2 ),
					new MeshBasicMaterial( { depthTest: false, depthWrite: false, fog: false } )
				);

			}

M
Mr.doob 已提交
1236 1237
			backgroundPlaneMesh.material.map = background;

1238 1239
			objects.update( backgroundPlaneMesh );

M
Mr.doob 已提交
1240
			_this.renderBufferDirect( backgroundPlaneCamera, null, backgroundPlaneMesh.geometry, backgroundPlaneMesh.material, backgroundPlaneMesh, null );
M
Mr.doob 已提交
1241

M
Mr.doob 已提交
1242 1243
		}

1244
		//
M
Mr.doob 已提交
1245 1246 1247

		if ( scene.overrideMaterial ) {

1248
			var overrideMaterial = scene.overrideMaterial;
M
Mr.doob 已提交
1249

1250 1251
			renderObjects( opaqueObjects, scene, camera, overrideMaterial );
			renderObjects( transparentObjects, scene, camera, overrideMaterial );
1252

M
Mr.doob 已提交
1253 1254 1255 1256
		} else {

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

R
Rich Harris 已提交
1257
			state.setBlending( NoBlending );
1258
			renderObjects( opaqueObjects, scene, camera );
M
Mr.doob 已提交
1259 1260 1261

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

1262
			renderObjects( transparentObjects, scene, camera );
M
Mr.doob 已提交
1263 1264 1265 1266 1267

		}

		// custom render plugins (post pass)

M
Mr.doob 已提交
1268
		spritePlugin.render( scene, camera );
1269
		lensFlarePlugin.render( scene, camera, _currentViewport );
M
Mr.doob 已提交
1270 1271 1272

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

M
Mr.doob 已提交
1273 1274
		if ( renderTarget ) {

1275
			textures.updateRenderTargetMipmap( renderTarget );
M
Mr.doob 已提交
1276 1277 1278

		}

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

M
Mr.doob 已提交
1281 1282
		state.setDepthTest( true );
		state.setDepthWrite( true );
1283
		state.setColorWrite( true );
M
Mr.doob 已提交
1284 1285 1286 1287

		// _gl.finish();

	};
M
Mr.doob 已提交
1288

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

1291
		var array, index;
M
Mr.doob 已提交
1292

1293
		// allocate the next position in the appropriate array
M
Mr.doob 已提交
1294 1295 1296

		if ( material.transparent ) {

1297 1298
			array = transparentObjects;
			index = ++ transparentObjectsLastIndex;
M
Mr.doob 已提交
1299 1300 1301

		} else {

1302 1303 1304 1305 1306
			array = opaqueObjects;
			index = ++ opaqueObjectsLastIndex;

		}

1307 1308
		// recycle existing render item or grow the array

1309 1310
		var renderItem = array[ index ];

M
Mr.doob 已提交
1311
		if ( renderItem ) {
1312 1313 1314 1315 1316 1317 1318

			renderItem.id = object.id;
			renderItem.object = object;
			renderItem.geometry = geometry;
			renderItem.material = material;
			renderItem.z = _vector3.z;
			renderItem.group = group;
M
Mr.doob 已提交
1319 1320 1321

		} else {

1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332
			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 已提交
1333 1334 1335 1336 1337

		}

	}

1338
	/*
M
Mr.doob 已提交
1339 1340
	// TODO Duplicated code (Frustum)

1341 1342
	var _sphere = new Sphere();

T
tschw 已提交
1343 1344 1345 1346 1347 1348 1349
	function isObjectViewable( object ) {

		var geometry = object.geometry;

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

M
Mr.doob 已提交
1350
		_sphere.copy( geometry.boundingSphere ).
1351
		applyMatrix4( object.matrixWorld );
M
Mr.doob 已提交
1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367

		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 已提交
1368 1369

		if ( ! _frustum.intersectsSphere( sphere ) ) return false;
T
tschw 已提交
1370 1371 1372 1373

		var numPlanes = _clipping.numPlanes;

		if ( numPlanes === 0 ) return true;
T
tschw 已提交
1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385

		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 已提交
1386
		} while ( ++ i !== numPlanes );
T
tschw 已提交
1387 1388 1389 1390

		return true;

	}
1391
	*/
T
tschw 已提交
1392

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

M
Mr.doob 已提交
1395
		if ( ! object.visible ) return;
M
Mr.doob 已提交
1396

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

1399 1400 1401
		if ( visible ) {

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

1403
				lights.push( object );
M
Mr.doob 已提交
1404

1405
			} else if ( object.isSprite ) {
M
Mr.doob 已提交
1406

1407
				if ( ! object.frustumCulled || _frustum.intersectsSprite( object ) ) {
1408 1409 1410 1411

					sprites.push( object );

				}
M
Mr.doob 已提交
1412

1413
			} else if ( object.isLensFlare ) {
M
Mr.doob 已提交
1414

1415
				lensFlares.push( object );
M
Mr.doob 已提交
1416

1417
			} else if ( object.isImmediateRenderObject ) {
M
Mr.doob 已提交
1418

M
Mr.doob 已提交
1419
				if ( sortObjects ) {
M
Mr.doob 已提交
1420

M
Mr.doob 已提交
1421 1422
					_vector3.setFromMatrixPosition( object.matrixWorld )
						.applyMatrix4( _projScreenMatrix );
M
Mr.doob 已提交
1423

1424
				}
1425

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

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

1430
				if ( object.isSkinnedMesh ) {
M
Mr.doob 已提交
1431

1432
					object.skeleton.update();
1433

1434
				}
1435

1436
				if ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) {
1437

M
Mr.doob 已提交
1438
					if ( sortObjects ) {
1439

M
Mr.doob 已提交
1440 1441
						_vector3.setFromMatrixPosition( object.matrixWorld )
							.applyMatrix4( _projScreenMatrix );
1442

M
Mr.doob 已提交
1443
					}
1444

M
Mr.doob 已提交
1445 1446
					var geometry = objects.update( object );
					var material = object.material;
1447

M
Mr.doob 已提交
1448
					if ( Array.isArray( material ) ) {
1449

M
Mr.doob 已提交
1450
						var groups = geometry.groups;
1451

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

M
Mr.doob 已提交
1454 1455
							var group = groups[ i ];
							var groupMaterial = material[ group.materialIndex ];
M
Mr.doob 已提交
1456

M
Mr.doob 已提交
1457
							if ( groupMaterial && groupMaterial.visible ) {
1458

M
Mr.doob 已提交
1459
								pushRenderItem( object, geometry, groupMaterial, _vector3.z, group );
1460

M
Mr.doob 已提交
1461
							}
M
Mr.doob 已提交
1462

M
Mr.doob 已提交
1463
						}
M
Mr.doob 已提交
1464

M
Mr.doob 已提交
1465
					} else if ( material.visible ) {
1466

M
Mr.doob 已提交
1467
						pushRenderItem( object, geometry, material, _vector3.z, null );
O
OpenShift guest 已提交
1468

1469
					}
M
Mr.doob 已提交
1470

1471
				}
M
Mr.doob 已提交
1472

1473
			}
M
Mr.doob 已提交
1474

M
Mr.doob 已提交
1475
		}
M
Mr.doob 已提交
1476

M
Mr.doob 已提交
1477
		var children = object.children;
M
Mr.doob 已提交
1478

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

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

1483
		}
1484

1485
	}
M
Mr.doob 已提交
1486

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

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

1491
			var renderItem = renderList[ i ];
M
Mr.doob 已提交
1492

1493
			var object = renderItem.object;
M
Mr.doob 已提交
1494 1495 1496
			var geometry = renderItem.geometry;
			var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;
			var group = renderItem.group;
M
Mr.doob 已提交
1497

1498 1499
			object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
			object.normalMatrix.getNormalMatrix( object.modelViewMatrix );
M
Mr.doob 已提交
1500

1501
			object.onBeforeRender( _this, scene, camera, geometry, material, group );
1502

1503
			if ( object.isImmediateRenderObject ) {
M
Mr.doob 已提交
1504

M
Mr.doob 已提交
1505
				setMaterial( material );
M
Mr.doob 已提交
1506

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

M
Mr.doob 已提交
1509
				_currentGeometryProgram = '';
M
Mr.doob 已提交
1510

M
Mr.doob 已提交
1511
				renderObjectImmediate( object, program, material );
1512

M
Mr.doob 已提交
1513
			} else {
M
Mr.doob 已提交
1514

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

M
Mr.doob 已提交
1517
			}
M
Mr.doob 已提交
1518

1519
			object.onAfterRender( _this, scene, camera, geometry, material, group );
D
Dusan Bosnjak 已提交
1520 1521


1522
		}
M
Mr.doob 已提交
1523

1524
	}
G
gero3 已提交
1525

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

1528
		var materialProperties = properties.get( material );
G
gero3 已提交
1529

T
tschw 已提交
1530
		var parameters = programCache.getParameters(
1531
			material, _lights, fog, _clipping.numPlanes, _clipping.numIntersection, object );
T
tschw 已提交
1532

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

1535
		var program = materialProperties.program;
T
tschw 已提交
1536
		var programChange = true;
1537

1538
		if ( program === undefined ) {
B
Ben Adams 已提交
1539

M
Mr.doob 已提交
1540 1541
			// new material
			material.addEventListener( 'dispose', onMaterialDispose );
B
Ben Adams 已提交
1542

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

M
Mr.doob 已提交
1545
			// changed glsl or parameters
1546
			releaseMaterialProgramReference( material );
B
Ben Adams 已提交
1547

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

T
tschw 已提交
1550
			// same glsl and uniform list
T
tschw 已提交
1551 1552
			return;

T
tschw 已提交
1553
		} else {
B
Ben Adams 已提交
1554

T
tschw 已提交
1555 1556
			// only rebuild uniform list
			programChange = false;
B
Ben Adams 已提交
1557 1558 1559

		}

1560
		if ( programChange ) {
B
Ben Adams 已提交
1561

1562
			if ( parameters.shaderID ) {
B
Ben Adams 已提交
1563

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

1566 1567
				materialProperties.__webglShader = {
					name: material.type,
1568
					uniforms: UniformsUtils.clone( shader.uniforms ),
1569 1570 1571
					vertexShader: shader.vertexShader,
					fragmentShader: shader.fragmentShader
				};
B
Ben Adams 已提交
1572

1573
			} else {
B
Ben Adams 已提交
1574

1575 1576 1577 1578 1579 1580
				materialProperties.__webglShader = {
					name: material.type,
					uniforms: material.uniforms,
					vertexShader: material.vertexShader,
					fragmentShader: material.fragmentShader
				};
G
gero3 已提交
1581

1582
			}
G
gero3 已提交
1583

1584
			material.__webglShader = materialProperties.__webglShader;
G
gero3 已提交
1585

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

1588 1589
			materialProperties.program = program;
			material.program = program;
1590 1591 1592

		}

1593
		var programAttributes = program.getAttributes();
M
Mr.doob 已提交
1594 1595 1596 1597 1598

		if ( material.morphTargets ) {

			material.numSupportedMorphTargets = 0;

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

1601
				if ( programAttributes[ 'morphTarget' + i ] >= 0 ) {
M
Mr.doob 已提交
1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614

					material.numSupportedMorphTargets ++;

				}

			}

		}

		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

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

1617
				if ( programAttributes[ 'morphNormal' + i ] >= 0 ) {
M
Mr.doob 已提交
1618 1619 1620 1621 1622 1623 1624 1625 1626

					material.numSupportedMorphNormals ++;

				}

			}

		}

T
tschw 已提交
1627 1628
		var uniforms = materialProperties.__webglShader.uniforms;

1629
		if ( ! material.isShaderMaterial &&
1630 1631
			! material.isRawShaderMaterial ||
			material.clipping === true ) {
T
tschw 已提交
1632

T
tschw 已提交
1633
			materialProperties.numClippingPlanes = _clipping.numPlanes;
1634
			materialProperties.numIntersection = _clipping.numIntersection;
T
tschw 已提交
1635
			uniforms.clippingPlanes = _clipping.uniform;
T
tschw 已提交
1636 1637 1638

		}

1639
		materialProperties.fog = fog;
1640

1641
		// store the light setup it was created for
1642

1643
		materialProperties.lightsHash = _lights.hash;
1644

M
Mr.doob 已提交
1645
		if ( material.lights ) {
1646 1647 1648 1649 1650 1651

			// 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;
1652
			uniforms.rectAreaLights.value = _lights.rectArea;
M
Mr.doob 已提交
1653
			uniforms.pointLights.value = _lights.point;
1654 1655
			uniforms.hemisphereLights.value = _lights.hemi;

1656 1657 1658 1659 1660 1661
			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;
1662
			// TODO (abelnation): add area lights shadow info to uniforms
1663

1664 1665
		}

T
tschw 已提交
1666 1667
		var progUniforms = materialProperties.program.getUniforms(),
			uniformsList =
1668
				WebGLUniforms.seqWithValue( progUniforms.seq, uniforms );
A
arose 已提交
1669

T
tschw 已提交
1670
		materialProperties.uniformsList = uniformsList;
A
arose 已提交
1671

M
Mr.doob 已提交
1672
	}
M
Mr.doob 已提交
1673

1674 1675
	function setMaterial( material ) {

M
Mr.doob 已提交
1676 1677 1678
		material.side === DoubleSide
			? state.disable( _gl.CULL_FACE )
			: state.enable( _gl.CULL_FACE );
T
tschw 已提交
1679

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

M
Mr.doob 已提交
1682 1683 1684
		material.transparent === true
			? state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha )
			: state.setBlending( NoBlending );
1685

B
Ben Adams 已提交
1686
		state.setDepthFunc( material.depthFunc );
M
Mr.doob 已提交
1687 1688
		state.setDepthTest( material.depthTest );
		state.setDepthWrite( material.depthWrite );
1689
		state.setColorWrite( material.colorWrite );
M
Mr.doob 已提交
1690
		state.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
1691 1692 1693

	}

1694
	function setProgram( camera, fog, material, object ) {
M
Mr.doob 已提交
1695 1696 1697

		_usedTextureUnits = 0;

1698
		var materialProperties = properties.get( material );
1699

T
tschw 已提交
1700 1701 1702 1703 1704
		if ( _clippingEnabled ) {

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

				var useCache =
1705 1706
					camera === _currentCamera &&
					material.id === _currentMaterialId;
T
tschw 已提交
1707 1708 1709 1710

				// we might want to call this function with some ClippingGroup
				// object instead of the material, once it becomes feasible
				// (#8465, #8379)
T
tschw 已提交
1711
				_clipping.setState(
1712 1713
					material.clippingPlanes, material.clipIntersection, material.clipShadows,
					camera, materialProperties, useCache );
T
tschw 已提交
1714 1715 1716 1717 1718

			}

		}

1719
		if ( material.needsUpdate === false ) {
1720

1721
			if ( materialProperties.program === undefined ) {
1722

1723
				material.needsUpdate = true;
1724

1725
			} else if ( material.fog && materialProperties.fog !== fog ) {
1726

M
Mr.doob 已提交
1727
				material.needsUpdate = true;
1728

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

1731
				material.needsUpdate = true;
1732

1733
			} else if ( materialProperties.numClippingPlanes !== undefined &&
1734
				( materialProperties.numClippingPlanes !== _clipping.numPlanes ||
M
Mr.doob 已提交
1735
				materialProperties.numIntersection !== _clipping.numIntersection ) ) {
1736 1737 1738

				material.needsUpdate = true;

1739
			}
1740 1741 1742 1743

		}

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

1745
			initMaterial( material, fog, object );
M
Mr.doob 已提交
1746 1747 1748 1749
			material.needsUpdate = false;

		}

1750
		var refreshProgram = false;
M
Mr.doob 已提交
1751
		var refreshMaterial = false;
1752
		var refreshLights = false;
M
Mr.doob 已提交
1753

1754
		var program = materialProperties.program,
1755
			p_uniforms = program.getUniforms(),
1756
			m_uniforms = materialProperties.__webglShader.uniforms;
M
Mr.doob 已提交
1757

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

1760 1761
			_gl.useProgram( program.program );
			_currentProgram = program.id;
M
Mr.doob 已提交
1762

1763
			refreshProgram = true;
M
Mr.doob 已提交
1764
			refreshMaterial = true;
1765
			refreshLights = true;
M
Mr.doob 已提交
1766 1767 1768 1769 1770 1771

		}

		if ( material.id !== _currentMaterialId ) {

			_currentMaterialId = material.id;
1772

M
Mr.doob 已提交
1773 1774 1775 1776
			refreshMaterial = true;

		}

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

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

G
gero3 已提交
1781
			if ( capabilities.logarithmicDepthBuffer ) {
1782

T
tschw 已提交
1783
				p_uniforms.setValue( _gl, 'logDepthBufFC',
1784
					2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
1785 1786 1787 1788

			}


1789 1790 1791 1792 1793 1794 1795 1796 1797
			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 已提交
1798
				refreshLights = true;		// remains set until update done
1799 1800

			}
M
Mr.doob 已提交
1801

1802 1803 1804
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)

1805
			if ( material.isShaderMaterial ||
1806 1807 1808
				material.isMeshPhongMaterial ||
				material.isMeshStandardMaterial ||
				material.envMap ) {
1809

T
tschw 已提交
1810 1811 1812
				var uCamPos = p_uniforms.map.cameraPosition;

				if ( uCamPos !== undefined ) {
1813

T
tschw 已提交
1814
					uCamPos.setValue( _gl,
1815
						_vector3.setFromMatrixPosition( camera.matrixWorld ) );
1816 1817 1818 1819 1820

				}

			}

1821
			if ( material.isMeshPhongMaterial ||
1822 1823 1824 1825
				material.isMeshLambertMaterial ||
				material.isMeshBasicMaterial ||
				material.isMeshStandardMaterial ||
				material.isShaderMaterial ||
1826
				object.isSkinnedMesh ) {
1827

T
tschw 已提交
1828
				p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );
1829 1830 1831

			}

T
tschw 已提交
1832 1833
			p_uniforms.set( _gl, _this, 'toneMappingExposure' );
			p_uniforms.set( _gl, _this, 'toneMappingWhitePoint' );
M
Mr.doob 已提交
1834

M
Mr.doob 已提交
1835 1836 1837 1838 1839 1840
		}

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

1841
		if ( object.isSkinnedMesh ) {
M
Mr.doob 已提交
1842

T
tschw 已提交
1843 1844
			p_uniforms.setOptional( _gl, object, 'bindMatrix' );
			p_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );
1845

T
tschw 已提交
1846
			var skeleton = object.skeleton;
1847

T
tschw 已提交
1848
			if ( skeleton ) {
1849

1850
				if ( capabilities.floatVertexTextures ) {
M
Mr.doob 已提交
1851

T
tschw 已提交
1852
					p_uniforms.set( _gl, skeleton, 'boneTexture' );
1853
					p_uniforms.set( _gl, skeleton, 'boneTextureSize' );
M
Mr.doob 已提交
1854

T
tschw 已提交
1855
				} else {
M
Mr.doob 已提交
1856

T
tschw 已提交
1857
					p_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );
M
Mr.doob 已提交
1858 1859 1860 1861 1862 1863 1864 1865 1866

				}

			}

		}

		if ( refreshMaterial ) {

M
Mr.doob 已提交
1867
			if ( material.lights ) {
M
Mr.doob 已提交
1868

1869
				// the current material requires lighting info
M
Mr.doob 已提交
1870

T
tschw 已提交
1871 1872 1873 1874 1875 1876
				// 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 已提交
1877

T
tschw 已提交
1878
				markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
G
gero3 已提交
1879

T
tschw 已提交
1880
			}
G
gero3 已提交
1881

T
tschw 已提交
1882
			// refresh uniforms common to several materials
G
gero3 已提交
1883

T
tschw 已提交
1884
			if ( fog && material.fog ) {
G
gero3 已提交
1885

T
tschw 已提交
1886
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
1887 1888 1889

			}

1890
			if ( material.isMeshBasicMaterial ||
1891 1892 1893
				material.isMeshLambertMaterial ||
				material.isMeshPhongMaterial ||
				material.isMeshStandardMaterial ||
1894
				material.isMeshNormalMaterial ||
1895
				material.isMeshDepthMaterial ) {
M
Mr.doob 已提交
1896 1897 1898 1899 1900 1901 1902

				refreshUniformsCommon( m_uniforms, material );

			}

			// refresh single material specific uniforms

1903
			if ( material.isLineBasicMaterial ) {
M
Mr.doob 已提交
1904 1905 1906

				refreshUniformsLine( m_uniforms, material );

1907
			} else if ( material.isLineDashedMaterial ) {
M
Mr.doob 已提交
1908 1909 1910 1911

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

1912
			} else if ( material.isPointsMaterial ) {
M
Mr.doob 已提交
1913

M
Mr.doob 已提交
1914
				refreshUniformsPoints( m_uniforms, material );
M
Mr.doob 已提交
1915

1916
			} else if ( material.isMeshLambertMaterial ) {
1917 1918 1919

				refreshUniformsLambert( m_uniforms, material );

T
Takahiro 已提交
1920 1921 1922 1923
			} else if ( material.isMeshToonMaterial ) {

				refreshUniformsToon( m_uniforms, material );

1924 1925 1926 1927
			} else if ( material.isMeshPhongMaterial ) {

				refreshUniformsPhong( m_uniforms, material );

1928
			} else if ( material.isMeshPhysicalMaterial ) {
W
WestLangley 已提交
1929 1930 1931

				refreshUniformsPhysical( m_uniforms, material );

1932
			} else if ( material.isMeshStandardMaterial ) {
W
WestLangley 已提交
1933

1934
				refreshUniformsStandard( m_uniforms, material );
W
WestLangley 已提交
1935

1936
			} else if ( material.isMeshDepthMaterial ) {
M
Mr.doob 已提交
1937

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

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

				}

1946
			} else if ( material.isMeshNormalMaterial ) {
M
Mr.doob 已提交
1947

1948
				refreshUniformsNormal( m_uniforms, material );
M
Mr.doob 已提交
1949 1950 1951

			}

M
Mr.doob 已提交
1952 1953 1954 1955 1956 1957
			// RectAreaLight Texture
			// TODO (mrdoob): Find a nicer implementation

			if ( m_uniforms.ltcMat !== undefined ) m_uniforms.ltcMat.value = THREE.UniformsLib.LTC_MAT_TEXTURE;
			if ( m_uniforms.ltcMag !== undefined ) m_uniforms.ltcMag.value = THREE.UniformsLib.LTC_MAG_TEXTURE;

R
Rich Harris 已提交
1958
			WebGLUniforms.upload(
1959
				_gl, materialProperties.uniformsList, m_uniforms, _this );
A
arose 已提交
1960 1961 1962

		}

M
Mr.doob 已提交
1963

T
tschw 已提交
1964
		// common matrices
M
Mr.doob 已提交
1965

T
tschw 已提交
1966 1967 1968
		p_uniforms.set( _gl, object, 'modelViewMatrix' );
		p_uniforms.set( _gl, object, 'normalMatrix' );
		p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );
A
arose 已提交
1969

T
tschw 已提交
1970
		return program;
A
arose 已提交
1971 1972 1973

	}

M
Mr.doob 已提交
1974 1975
	// Uniforms (refresh uniforms objects)

M
Mr.doob 已提交
1976
	function refreshUniformsCommon( uniforms, material ) {
M
Mr.doob 已提交
1977 1978 1979

		uniforms.opacity.value = material.opacity;

1980
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
1981

1982
		if ( material.emissive ) {
M
Mr.doob 已提交
1983

1984
			uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );
M
Mr.doob 已提交
1985 1986 1987

		}

1988 1989 1990
		uniforms.map.value = material.map;
		uniforms.specularMap.value = material.specularMap;
		uniforms.alphaMap.value = material.alphaMap;
M
Mr.doob 已提交
1991

1992 1993 1994 1995 1996 1997 1998
		if ( material.lightMap ) {

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

		}

1999
		if ( material.aoMap ) {
2000

2001 2002
			uniforms.aoMap.value = material.aoMap;
			uniforms.aoMapIntensity.value = material.aoMapIntensity;
2003 2004 2005

		}

M
Mr.doob 已提交
2006
		// uv repeat and offset setting priorities
M
Mr.doob 已提交
2007 2008 2009 2010 2011
		// 1. color map
		// 2. specular map
		// 3. normal map
		// 4. bump map
		// 5. alpha map
2012
		// 6. emissive map
M
Mr.doob 已提交
2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023

		var uvScaleMap;

		if ( material.map ) {

			uvScaleMap = material.map;

		} else if ( material.specularMap ) {

			uvScaleMap = material.specularMap;

2024 2025 2026 2027
		} else if ( material.displacementMap ) {

			uvScaleMap = material.displacementMap;

M
Mr.doob 已提交
2028 2029 2030 2031 2032 2033 2034 2035
		} else if ( material.normalMap ) {

			uvScaleMap = material.normalMap;

		} else if ( material.bumpMap ) {

			uvScaleMap = material.bumpMap;

2036 2037 2038 2039 2040 2041 2042 2043
		} else if ( material.roughnessMap ) {

			uvScaleMap = material.roughnessMap;

		} else if ( material.metalnessMap ) {

			uvScaleMap = material.metalnessMap;

2044 2045 2046 2047
		} else if ( material.alphaMap ) {

			uvScaleMap = material.alphaMap;

2048 2049 2050 2051
		} else if ( material.emissiveMap ) {

			uvScaleMap = material.emissiveMap;

M
Mr.doob 已提交
2052 2053 2054 2055
		}

		if ( uvScaleMap !== undefined ) {

2056
			// backwards compatibility
2057
			if ( uvScaleMap.isWebGLRenderTarget ) {
M
Mr.doob 已提交
2058 2059 2060 2061 2062

				uvScaleMap = uvScaleMap.texture;

			}

M
Mr.doob 已提交
2063 2064 2065 2066 2067 2068 2069 2070
			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;
2071 2072 2073 2074 2075

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

2078
		uniforms.reflectivity.value = material.reflectivity;
M
Mr.doob 已提交
2079 2080
		uniforms.refractionRatio.value = material.refractionRatio;

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

M
Mr.doob 已提交
2083
	function refreshUniformsLine( uniforms, material ) {
M
Mr.doob 已提交
2084 2085 2086 2087

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

M
Mr.doob 已提交
2088
	}
M
Mr.doob 已提交
2089

M
Mr.doob 已提交
2090
	function refreshUniformsDash( uniforms, material ) {
M
Mr.doob 已提交
2091 2092 2093 2094 2095

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

M
Mr.doob 已提交
2096
	}
M
Mr.doob 已提交
2097

M
Mr.doob 已提交
2098
	function refreshUniformsPoints( uniforms, material ) {
M
Mr.doob 已提交
2099

2100
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
2101
		uniforms.opacity.value = material.opacity;
2102
		uniforms.size.value = material.size * _pixelRatio;
2103
		uniforms.scale.value = _height * 0.5;
M
Mr.doob 已提交
2104 2105 2106

		uniforms.map.value = material.map;

2107 2108 2109 2110 2111 2112 2113 2114 2115
		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 已提交
2116
	}
M
Mr.doob 已提交
2117

M
Mr.doob 已提交
2118
	function refreshUniformsFog( uniforms, fog ) {
M
Mr.doob 已提交
2119 2120 2121

		uniforms.fogColor.value = fog.color;

2122
		if ( fog.isFog ) {
M
Mr.doob 已提交
2123 2124 2125 2126

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

2127
		} else if ( fog.isFogExp2 ) {
M
Mr.doob 已提交
2128 2129 2130 2131 2132

			uniforms.fogDensity.value = fog.density;

		}

M
Mr.doob 已提交
2133
	}
M
Mr.doob 已提交
2134

M
Mr.doob 已提交
2135
	function refreshUniformsLambert( uniforms, material ) {
2136 2137 2138 2139 2140 2141 2142 2143 2144

		if ( material.emissiveMap ) {

			uniforms.emissiveMap.value = material.emissiveMap;

		}

	}

M
Mr.doob 已提交
2145
	function refreshUniformsPhong( uniforms, material ) {
M
Mr.doob 已提交
2146

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

2150
		if ( material.emissiveMap ) {
2151

2152
			uniforms.emissiveMap.value = material.emissiveMap;
2153

2154
		}
M
Mr.doob 已提交
2155

2156 2157 2158 2159
		if ( material.bumpMap ) {

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

2161
		}
M
Mr.doob 已提交
2162

2163 2164 2165 2166 2167 2168
		if ( material.normalMap ) {

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

		}
M
Mr.doob 已提交
2169

2170 2171 2172 2173 2174
		if ( material.displacementMap ) {

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

2176
		}
2177

T
Takahiro 已提交
2178 2179 2180 2181 2182 2183
	}

	function refreshUniformsToon( uniforms, material ) {

		refreshUniformsPhong( uniforms, material );

T
Takahiro 已提交
2184
		if ( material.gradientMap ) {
T
Takahiro 已提交
2185

T
Takahiro 已提交
2186
			uniforms.gradientMap.value = material.gradientMap;
T
Takahiro 已提交
2187 2188 2189

		}

2190 2191
	}

M
Mr.doob 已提交
2192
	function refreshUniformsStandard( uniforms, material ) {
W
WestLangley 已提交
2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245

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

2248 2249 2250
		uniforms.clearCoat.value = material.clearCoat;
		uniforms.clearCoatRoughness.value = material.clearCoatRoughness;

W
WestLangley 已提交
2251 2252 2253 2254
		refreshUniformsStandard( uniforms, material );

	}

2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280
	function refreshUniformsNormal( uniforms, material ) {

		if ( material.bumpMap ) {

			uniforms.bumpMap.value = material.bumpMap;
			uniforms.bumpScale.value = material.bumpScale;

		}

		if ( material.normalMap ) {

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

		}

		if ( material.displacementMap ) {

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

		}

	}

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

M
Mr.doob 已提交
2283
	function markUniformsLightsNeedsUpdate( uniforms, value ) {
2284

M
Mr.doob 已提交
2285
		uniforms.ambientLightColor.needsUpdate = value;
2286

B
Ben Houston 已提交
2287 2288 2289
		uniforms.directionalLights.needsUpdate = value;
		uniforms.pointLights.needsUpdate = value;
		uniforms.spotLights.needsUpdate = value;
2290
		uniforms.rectAreaLights.needsUpdate = value;
B
Ben Houston 已提交
2291
		uniforms.hemisphereLights.needsUpdate = value;
2292

M
Mr.doob 已提交
2293
	}
2294

T
tschw 已提交
2295
	// Lighting
M
Mr.doob 已提交
2296

M
Mr.doob 已提交
2297
	function setupShadows( lights ) {
2298 2299 2300 2301 2302 2303 2304 2305 2306

		var lightShadowsLength = 0;

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

			var light = lights[ i ];

			if ( light.castShadow ) {

M
Mr.doob 已提交
2307 2308
				_lights.shadows[ lightShadowsLength ] = light;
				lightShadowsLength ++;
2309 2310 2311 2312 2313 2314 2315 2316 2317

			}

		}

		_lights.shadows.length = lightShadowsLength;

	}

M
Mr.doob 已提交
2318
	function setupLights( lights, camera ) {
M
Mr.doob 已提交
2319

M
Mr.doob 已提交
2320
		var l, ll, light, shadow,
2321 2322 2323 2324 2325
			r = 0, g = 0, b = 0,
			color,
			intensity,
			distance,
			shadowMap,
M
Mr.doob 已提交
2326

2327
			viewMatrix = camera.matrixWorldInverse,
M
Mr.doob 已提交
2328

M
Mr.doob 已提交
2329 2330 2331 2332 2333
			directionalLength = 0,
			pointLength = 0,
			spotLength = 0,
			rectAreaLength = 0,
			hemiLength = 0;
M
Mr.doob 已提交
2334 2335 2336 2337 2338 2339 2340 2341 2342

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

			light = lights[ l ];

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

2343
			shadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null;
2344

2345
			if ( light.isAmbientLight ) {
M
Mr.doob 已提交
2346

2347 2348 2349
				r += color.r * intensity;
				g += color.g * intensity;
				b += color.b * intensity;
M
Mr.doob 已提交
2350

2351
			} else if ( light.isDirectionalLight ) {
M
Mr.doob 已提交
2352

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

2355
				uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
M
Mr.doob 已提交
2356
				uniforms.direction.setFromMatrixPosition( light.matrixWorld );
2357
				_vector3.setFromMatrixPosition( light.target.matrixWorld );
M
Mr.doob 已提交
2358 2359 2360
				uniforms.direction.sub( _vector3 );
				uniforms.direction.transformDirection( viewMatrix );

2361
				uniforms.shadow = light.castShadow;
M
Mr.doob 已提交
2362

2363
				if ( light.castShadow ) {
M
Mr.doob 已提交
2364

M
Mr.doob 已提交
2365 2366 2367 2368 2369
					shadow = light.shadow;

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

2371 2372
				}

2373
				_lights.directionalShadowMap[ directionalLength ] = shadowMap;
2374
				_lights.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;
M
Mr.doob 已提交
2375 2376 2377
				_lights.directional[ directionalLength ] = uniforms;

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

2379
			} else if ( light.isSpotLight ) {
M
Mr.doob 已提交
2380

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

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

M
Mr.doob 已提交
2386 2387 2388 2389 2390 2391 2392 2393
				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 );

2394 2395
				uniforms.coneCos = Math.cos( light.angle );
				uniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );
M
Mr.doob 已提交
2396
				uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;
M
Mr.doob 已提交
2397

2398
				uniforms.shadow = light.castShadow;
M
Mr.doob 已提交
2399

2400 2401
				if ( light.castShadow ) {

M
Mr.doob 已提交
2402 2403 2404 2405 2406
					shadow = light.shadow;

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

2408 2409
				}

2410
				_lights.spotShadowMap[ spotLength ] = shadowMap;
2411
				_lights.spotShadowMatrix[ spotLength ] = light.shadow.matrix;
M
Mr.doob 已提交
2412 2413 2414
				_lights.spot[ spotLength ] = uniforms;

				spotLength ++;
2415

2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445
			} else if ( light.isRectAreaLight ) {

				var uniforms = lightCache.get( light );

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

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

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

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

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

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

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

M
Mr.doob 已提交
2446 2447 2448
				_lights.rectArea[ rectAreaLength ] = uniforms;

				rectAreaLength ++;
2449

2450
			} else if ( light.isPointLight ) {
M
Mr.doob 已提交
2451

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

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

M
Mr.doob 已提交
2457 2458
				uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
				uniforms.distance = light.distance;
M
Mr.doob 已提交
2459 2460
				uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;

2461
				uniforms.shadow = light.castShadow;
2462

M
Mr.doob 已提交
2463
				if ( light.castShadow ) {
2464

M
Mr.doob 已提交
2465 2466 2467 2468 2469
					shadow = light.shadow;

					uniforms.shadowBias = shadow.bias;
					uniforms.shadowRadius = shadow.radius;
					uniforms.shadowMapSize = shadow.mapSize;
2470 2471

				}
2472

2473
				_lights.pointShadowMap[ pointLength ] = shadowMap;
2474

2475 2476
				if ( _lights.pointShadowMatrix[ pointLength ] === undefined ) {

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

2479 2480
				}

2481 2482 2483 2484 2485
				// 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 已提交
2486 2487 2488
				_lights.point[ pointLength ] = uniforms;

				pointLength ++;
2489

2490
			} else if ( light.isHemisphereLight ) {
M
Mr.doob 已提交
2491

M
Mr.doob 已提交
2492
				var uniforms = lightCache.get( light );
M
Mr.doob 已提交
2493 2494 2495 2496

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

M
Mr.doob 已提交
2498 2499
				uniforms.skyColor.copy( light.color ).multiplyScalar( intensity );
				uniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );
M
Mr.doob 已提交
2500

M
Mr.doob 已提交
2501 2502 2503
				_lights.hemi[ hemiLength ] = uniforms;

				hemiLength ++;
M
Mr.doob 已提交
2504 2505 2506 2507 2508

			}

		}

M
Mr.doob 已提交
2509 2510 2511
		_lights.ambient[ 0 ] = r;
		_lights.ambient[ 1 ] = g;
		_lights.ambient[ 2 ] = b;
M
Mr.doob 已提交
2512

M
Mr.doob 已提交
2513 2514
		_lights.directional.length = directionalLength;
		_lights.spot.length = spotLength;
2515
		_lights.rectArea.length = rectAreaLength;
2516
		_lights.point.length = pointLength;
M
Mr.doob 已提交
2517
		_lights.hemi.length = hemiLength;
2518

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

M
Mr.doob 已提交
2522
	}
M
Mr.doob 已提交
2523 2524 2525 2526 2527

	// GL state setting

	this.setFaceCulling = function ( cullFace, frontFaceDirection ) {

T
tschw 已提交
2528
		state.setCullFace( cullFace );
R
Rich Harris 已提交
2529
		state.setFlipSided( frontFaceDirection === FrontFaceDirectionCW );
M
Mr.doob 已提交
2530 2531 2532 2533 2534

	};

	// Textures

T
tschw 已提交
2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550
	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;

	}

2551
	this.allocTextureUnit = allocTextureUnit;
T
tschw 已提交
2552

2553
	// this.setTexture2D = setTexture2D;
M
Mr.doob 已提交
2554
	this.setTexture2D = ( function () {
T
tschw 已提交
2555

2556
		var warned = false;
T
tschw 已提交
2557

2558
		// backwards compatibility: peel texture.texture
W
WestLangley 已提交
2559
		return function setTexture2D( texture, slot ) {
T
tschw 已提交
2560

T
Takahiro 已提交
2561
			if ( texture && texture.isWebGLRenderTarget ) {
T
tschw 已提交
2562

2563
				if ( ! warned ) {
T
tschw 已提交
2564

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

2568
				}
T
tschw 已提交
2569

2570
				texture = texture.texture;
T
tschw 已提交
2571

2572
			}
T
tschw 已提交
2573

2574
			textures.setTexture2D( texture, slot );
T
tschw 已提交
2575

2576
		};
T
tschw 已提交
2577

2578
	}() );
T
tschw 已提交
2579

M
Mr.doob 已提交
2580
	this.setTexture = ( function () {
2581 2582 2583

		var warned = false;

W
WestLangley 已提交
2584
		return function setTexture( texture, slot ) {
2585 2586 2587 2588 2589 2590 2591 2592

			if ( ! warned ) {

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

			}

2593
			textures.setTexture2D( texture, slot );
2594 2595 2596 2597 2598

		};

	}() );

M
Mr.doob 已提交
2599
	this.setTextureCube = ( function () {
2600 2601 2602

		var warned = false;

W
WestLangley 已提交
2603
		return function setTextureCube( texture, slot ) {
2604 2605

			// backwards compatibility: peel texture.texture
T
Takahiro 已提交
2606
			if ( texture && texture.isWebGLRenderTargetCube ) {
2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620

				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 已提交
2621
			if ( ( texture && texture.isCubeTexture ) ||
2622
				( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {
2623 2624 2625 2626

				// CompressedTexture can have Array in image :/

				// this function alone should take care of cube textures
2627
				textures.setTextureCube( texture, slot );
2628 2629 2630 2631 2632

			} else {

				// assumed: texture property of THREE.WebGLRenderTargetCube

2633
				textures.setTextureCubeDynamic( texture, slot );
2634 2635 2636 2637 2638 2639

			}

		};

	}() );
T
tschw 已提交
2640

M
Mr.doob 已提交
2641
	this.getCurrentRenderTarget = function () {
2642 2643 2644

		return _currentRenderTarget;

M
Michael Herzog 已提交
2645
	};
2646

2647
	this.setRenderTarget = function ( renderTarget ) {
M
Mr.doob 已提交
2648

2649 2650
		_currentRenderTarget = renderTarget;

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

2653
			textures.setupRenderTarget( renderTarget );
M
Mr.doob 已提交
2654 2655 2656

		}

T
Takahiro 已提交
2657
		var isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );
2658
		var framebuffer;
M
Mr.doob 已提交
2659 2660 2661

		if ( renderTarget ) {

2662
			var renderTargetProperties = properties.get( renderTarget );
F
Fordy 已提交
2663

M
Mr.doob 已提交
2664 2665
			if ( isCube ) {

2666
				framebuffer = renderTargetProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];
M
Mr.doob 已提交
2667 2668 2669

			} else {

2670
				framebuffer = renderTargetProperties.__webglFramebuffer;
M
Mr.doob 已提交
2671 2672 2673

			}

2674 2675
			_currentScissor.copy( renderTarget.scissor );
			_currentScissorTest = renderTarget.scissorTest;
2676

2677
			_currentViewport.copy( renderTarget.viewport );
M
Mr.doob 已提交
2678 2679 2680 2681 2682

		} else {

			framebuffer = null;

2683
			_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );
2684
			_currentScissorTest = _scissorTest;
2685

2686
			_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );
M
Mr.doob 已提交
2687 2688 2689

		}

M
Mr.doob 已提交
2690
		if ( _currentFramebuffer !== framebuffer ) {
M
Mr.doob 已提交
2691 2692 2693 2694 2695 2696

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

		}

2697 2698
		state.scissor( _currentScissor );
		state.setScissorTest( _currentScissorTest );
2699

2700
		state.viewport( _currentViewport );
2701

M
Mr.doob 已提交
2702 2703 2704
		if ( isCube ) {

			var textureProperties = properties.get( renderTarget.texture );
2705
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );
M
Mr.doob 已提交
2706 2707 2708

		}

M
Mr.doob 已提交
2709 2710
	};

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

T
Takahiro 已提交
2713
		if ( ( renderTarget && renderTarget.isWebGLRenderTarget ) === false ) {
2714

2715
			console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
G
gero3 已提交
2716
			return;
2717

G
gero3 已提交
2718
		}
2719

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

M
Mr.doob 已提交
2722
		if ( framebuffer ) {
2723

G
gero3 已提交
2724
			var restore = false;
2725

M
Mr.doob 已提交
2726
			if ( framebuffer !== _currentFramebuffer ) {
2727

M
Mr.doob 已提交
2728
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
2729

G
gero3 已提交
2730
				restore = true;
2731

G
gero3 已提交
2732
			}
2733

M
Mr.doob 已提交
2734
			try {
2735

M
Mr.doob 已提交
2736
				var texture = renderTarget.texture;
M
Mr.doob 已提交
2737 2738
				var textureFormat = texture.format;
				var textureType = texture.type;
2739

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

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

M
Mr.doob 已提交
2745
				}
2746

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

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

M
Mr.doob 已提交
2754
				}
2755

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

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

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

M
Mr.doob 已提交
2762
						_gl.readPixels( x, y, width, height, paramThreeToGL( textureFormat ), paramThreeToGL( textureType ), buffer );
2763 2764

					}
2765

M
Mr.doob 已提交
2766
				} else {
M
Mr.doob 已提交
2767

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

				}
M
Mr.doob 已提交
2771

M
Mr.doob 已提交
2772
			} finally {
M
Mr.doob 已提交
2773

M
Mr.doob 已提交
2774 2775 2776
				if ( restore ) {

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

M
Mr.doob 已提交
2778 2779 2780
				}

			}
M
Mr.doob 已提交
2781 2782 2783

		}

M
Mr.doob 已提交
2784 2785
	};

M
Mr.doob 已提交
2786 2787
	// Map three.js constants to WebGL constants

M
Mr.doob 已提交
2788
	function paramThreeToGL( p ) {
M
Mr.doob 已提交
2789

2790 2791
		var extension;

R
Rich Harris 已提交
2792 2793 2794
		if ( p === RepeatWrapping ) return _gl.REPEAT;
		if ( p === ClampToEdgeWrapping ) return _gl.CLAMP_TO_EDGE;
		if ( p === MirroredRepeatWrapping ) return _gl.MIRRORED_REPEAT;
M
Mr.doob 已提交
2795

R
Rich Harris 已提交
2796 2797 2798
		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 已提交
2799

R
Rich Harris 已提交
2800 2801 2802
		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 已提交
2803

R
Rich Harris 已提交
2804 2805 2806 2807
		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 已提交
2808

R
Rich Harris 已提交
2809 2810 2811 2812 2813 2814
		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 已提交
2815

2816
		if ( p === HalfFloatType ) {
2817

2818
			extension = extensions.get( 'OES_texture_half_float' );
2819

2820
			if ( extension !== null ) return extension.HALF_FLOAT_OES;
2821 2822 2823

		}

R
Rich Harris 已提交
2824 2825 2826 2827 2828 2829
		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;
2830
		if ( p === DepthStencilFormat ) return _gl.DEPTH_STENCIL;
M
Mr.doob 已提交
2831

R
Rich Harris 已提交
2832 2833 2834
		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 已提交
2835

R
Rich Harris 已提交
2836 2837 2838 2839 2840 2841 2842 2843
		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 已提交
2844

R
Rich Harris 已提交
2845 2846 2847
		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 已提交
2848

2849 2850
		if ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format ||
			p === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) {
M
Mr.doob 已提交
2851

2852
			extension = extensions.get( 'WEBGL_compressed_texture_s3tc' );
2853

2854 2855 2856 2857 2858 2859 2860 2861
			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 已提交
2862 2863 2864

		}

2865
		if ( p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format ||
2866
			p === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format ) {
2867

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

2870 2871 2872 2873 2874 2875 2876 2877
			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 已提交
2878 2879 2880

		}

2881
		if ( p === RGB_ETC1_Format ) {
2882

2883
			extension = extensions.get( 'WEBGL_compressed_texture_etc1' );
2884

2885
			if ( extension !== null ) return extension.COMPRESSED_RGB_ETC1_WEBGL;
2886 2887 2888

		}

2889 2890 2891
		if ( p === MinEquation || p === MaxEquation ) {

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

2893
			if ( extension !== null ) {
2894

2895 2896 2897 2898
				if ( p === MinEquation ) return extension.MIN_EXT;
				if ( p === MaxEquation ) return extension.MAX_EXT;

			}
2899 2900 2901

		}

2902
		if ( p === UnsignedInt248Type ) {
2903

2904
			extension = extensions.get( 'WEBGL_depth_texture' );
2905

2906
			if ( extension !== null ) return extension.UNSIGNED_INT_24_8_WEBGL;
2907 2908 2909

		}

M
Mr.doob 已提交
2910 2911
		return 0;

M
Mr.doob 已提交
2912
	}
M
Mr.doob 已提交
2913

M
Mr.doob 已提交
2914
}
R
Rich Harris 已提交
2915

T
Tristan VALCKE 已提交
2916

2917
export { WebGLRenderer };