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

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

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

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

	parameters = parameters || {};

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

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

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

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

64 65
	var morphInfluences = new Float32Array( 8 );

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

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

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

	// clearing

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

	// scene graph

	this.sortObjects = true;

T
tschw 已提交
85 86 87 88 89
	// user-defined clipping

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

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

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

96 97
	// physical lights

98
	this.physicallyCorrectLights = false;
99

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

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

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

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

	// internal properties

	var _this = this,

	// internal state cache

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

R
Rich Harris 已提交
124
	_currentScissor = new Vector4(),
125 126
	_currentScissorTest = null,

R
Rich Harris 已提交
127
	_currentViewport = new Vector4(),
128

129 130
	//

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

M
Mr.doob 已提交
133 134
	//

R
Rich Harris 已提交
135
	_clearColor = new Color( 0x000000 ),
M
Mr.doob 已提交
136 137 138 139 140 141 142
	_clearAlpha = 0,

	_width = _canvas.width,
	_height = _canvas.height,

	_pixelRatio = 1,

R
Rich Harris 已提交
143
	_scissor = new Vector4( 0, 0, _width, _height ),
144 145
	_scissorTest = false,

R
Rich Harris 已提交
146
	_viewport = new Vector4( 0, 0, _width, _height ),
147

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

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

T
tschw 已提交
152 153
	// clipping

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

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

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

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

R
Rich Harris 已提交
164
	_vector3 = new Vector3(),
M
Mr.doob 已提交
165 166 167 168 169

	// light arrays cache

	_lights = {

170 171
		hash: '',

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

184
		shadows: []
M
Mr.doob 已提交
185

186 187
	},

M
Mr.doob 已提交
188 189
	// info

190
	_infoRender = {
191 192 193 194 195 196

		calls: 0,
		vertices: 0,
		faces: 0,
		points: 0

M
Mr.doob 已提交
197 198
	};

M
Mr.doob 已提交
199
	this.info = {
200

M
Mr.doob 已提交
201
		render: _infoRender,
202 203 204 205 206 207
		memory: {

			geometries: 0,
			textures: 0

		},
208
		programs: null
M
Mr.doob 已提交
209 210

	};
211

212

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

	var _gl;

M
Mr.doob 已提交
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
	try {

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

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

		if ( _gl === null ) {

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

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

			} else {

				throw 'Error creating WebGL context.';

			}
M
Mr.doob 已提交
241 242 243

		}

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

		if ( _gl.getShaderPrecisionFormat === undefined ) {

			_gl.getShaderPrecisionFormat = function () {

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

			};

		}

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

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

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

	}

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

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

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

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

	}

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

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

289 290
	this.info.programs = programCache.programs;

R
Rich Harris 已提交
291 292
	var bufferRenderer = new WebGLBufferRenderer( _gl, extensions, _infoRender );
	var indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );
293

M
Mr.doob 已提交
294 295
	//

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

	//

318 319
	function getTargetPixelRatio() {

320
		return _currentRenderTarget === null ? _pixelRatio : 1;
321 322 323

	}

324
	function setDefaultGLState() {
M
Mr.doob 已提交
325

M
Mr.doob 已提交
326
		state.init();
M
Mr.doob 已提交
327

328 329
		state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) );
		state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) );
M
Mr.doob 已提交
330

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

333
	}
334

335
	function resetGLState() {
336 337 338 339

		_currentProgram = null;
		_currentCamera = null;

340
		_currentGeometryProgram = '';
341 342
		_currentMaterialId = - 1;

M
Mr.doob 已提交
343 344
		state.reset();

345
	}
M
Mr.doob 已提交
346 347 348 349

	setDefaultGLState();

	this.context = _gl;
M
Mr.doob 已提交
350
	this.capabilities = capabilities;
351
	this.extensions = extensions;
352
	this.properties = properties;
M
Mr.doob 已提交
353
	this.state = state;
M
Mr.doob 已提交
354

M
Mr.doob 已提交
355 356
	// shadow map

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

359
	this.shadowMap = shadowMap;
M
Mr.doob 已提交
360

M
Mr.doob 已提交
361

M
Mr.doob 已提交
362 363
	// Plugins

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

M
Mr.doob 已提交
367 368 369 370 371 372 373 374
	// API

	this.getContext = function () {

		return _gl;

	};

375 376 377 378 379 380
	this.getContextAttributes = function () {

		return _gl.getContextAttributes();

	};

381 382 383 384 385 386
	this.forceContextLoss = function () {

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

	};

387
	this.getMaxAnisotropy = function () {
388

389
		return capabilities.getMaxAnisotropy();
390

391
	};
M
Mr.doob 已提交
392 393 394

	this.getPrecision = function () {

G
gero3 已提交
395
		return capabilities.precision;
M
Mr.doob 已提交
396 397 398

	};

399 400
	this.getPixelRatio = function () {

401
		return _pixelRatio;
402 403 404 405 406

	};

	this.setPixelRatio = function ( value ) {

407 408 409 410 411
		if ( value === undefined ) return;

		_pixelRatio = value;

		this.setSize( _viewport.z, _viewport.w, false );
412 413 414

	};

415 416 417
	this.getSize = function () {

		return {
418 419
			width: _width,
			height: _height
420 421 422 423
		};

	};

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

426 427 428
		_width = width;
		_height = height;

429 430
		_canvas.width = width * _pixelRatio;
		_canvas.height = height * _pixelRatio;
431

432
		if ( updateStyle !== false ) {
433

G
gero3 已提交
434 435
			_canvas.style.width = width + 'px';
			_canvas.style.height = height + 'px';
436

G
gero3 已提交
437
		}
M
Mr.doob 已提交
438

439
		this.setViewport( 0, 0, width, height );
M
Mr.doob 已提交
440 441 442 443 444

	};

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

445
		state.viewport( _viewport.set( x, y, width, height ) );
M
Mr.doob 已提交
446 447 448

	};

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

451
		state.scissor( _scissor.set( x, y, width, height ) );
M
Mr.doob 已提交
452 453 454

	};

455 456
	this.setScissorTest = function ( boolean ) {

457
		state.setScissorTest( _scissorTest = boolean );
M
Mr.doob 已提交
458 459 460 461 462

	};

	// Clearing

M
Mr.doob 已提交
463
	this.getClearColor = function () {
M
Mr.doob 已提交
464

M
Mr.doob 已提交
465
		return _clearColor;
M
Mr.doob 已提交
466 467 468

	};

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

M
Mr.doob 已提交
471
		_clearColor.set( color );
472

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

475
		state.buffers.color.setClear( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha, _premultipliedAlpha );
M
Mr.doob 已提交
476 477 478

	};

M
Mr.doob 已提交
479
	this.getClearAlpha = function () {
M
Mr.doob 已提交
480

M
Mr.doob 已提交
481
		return _clearAlpha;
M
Mr.doob 已提交
482 483 484

	};

M
Mr.doob 已提交
485
	this.setClearAlpha = function ( alpha ) {
M
Mr.doob 已提交
486

M
Mr.doob 已提交
487
		_clearAlpha = alpha;
M
Mr.doob 已提交
488

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

	};

	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 );
502 503 504 505 506

	};

	this.clearColor = function () {

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

	};

	this.clearDepth = function () {

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

	};

	this.clearStencil = function () {

M
Mr.doob 已提交
519
		this.clear( false, false, true );
M
Mr.doob 已提交
520 521 522 523 524 525 526 527 528 529

	};

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

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

	};

M
Mr.doob 已提交
530 531
	// Reset

532
	this.resetGLState = resetGLState;
M
Mr.doob 已提交
533

D
dubejf 已提交
534 535
	this.dispose = function() {

536 537 538 539 540
		transparentObjects = [];
		transparentObjectsLastIndex = -1;
		opaqueObjects = [];
		opaqueObjectsLastIndex = -1;

D
dubejf 已提交
541 542 543 544
		_canvas.removeEventListener( 'webglcontextlost', onContextLost, false );

	};

M
Mr.doob 已提交
545
	// Events
M
Mr.doob 已提交
546

D
dubejf 已提交
547 548 549 550 551 552 553 554 555
	function onContextLost( event ) {

		event.preventDefault();

		resetGLState();
		setDefaultGLState();

		properties.clear();

M
Mr.doob 已提交
556
	}
D
dubejf 已提交
557

558
	function onMaterialDispose( event ) {
M
Mr.doob 已提交
559 560 561 562 563 564 565

		var material = event.target;

		material.removeEventListener( 'dispose', onMaterialDispose );

		deallocateMaterial( material );

566
	}
M
Mr.doob 已提交
567 568 569

	// Buffer deallocation

570
	function deallocateMaterial( material ) {
M
Mr.doob 已提交
571

572 573 574 575
		releaseMaterialProgramReference( material );

		properties.delete( material );

576
	}
577 578


579
	function releaseMaterialProgramReference( material ) {
580

581
		var programInfo = properties.get( material ).program;
M
Mr.doob 已提交
582 583 584

		material.program = undefined;

585
		if ( programInfo !== undefined ) {
M
Mr.doob 已提交
586

587
			programCache.releaseProgram( programInfo );
M
Mr.doob 已提交
588

M
Mr.doob 已提交
589 590
		}

591
	}
M
Mr.doob 已提交
592 593 594 595 596

	// Buffer rendering

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

597
		state.initAttributes();
598

599
		var buffers = properties.get( object );
600

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

606
		var attributes = program.getAttributes();
607

M
Mr.doob 已提交
608 609
		if ( object.hasPositions ) {

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

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

		}

		if ( object.hasNormals ) {

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

622 623 624
			if ( ! material.isMeshPhongMaterial &&
			     ! material.isMeshStandardMaterial &&
			       material.shading === FlatShading ) {
M
Mr.doob 已提交
625

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

628
					var array = object.normalArray;
M
Mr.doob 已提交
629

630 631 632
					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 已提交
633

634 635 636
					array[ i + 0 ] = nx;
					array[ i + 1 ] = ny;
					array[ i + 2 ] = nz;
M
Mr.doob 已提交
637

638 639 640
					array[ i + 3 ] = nx;
					array[ i + 4 ] = ny;
					array[ i + 5 ] = nz;
M
Mr.doob 已提交
641

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

				}

			}

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

652
			state.enableAttribute( attributes.normal );
653

654
			_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
655 656 657 658 659

		}

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

660
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.uv );
M
Mr.doob 已提交
661
			_gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );
662

663
			state.enableAttribute( attributes.uv );
664

665
			_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
666 667 668

		}

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

671
			_gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.color );
M
Mr.doob 已提交
672
			_gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );
673

674
			state.enableAttribute( attributes.color );
675

676
			_gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
M
Mr.doob 已提交
677 678 679

		}

680
		state.disableUnusedAttributes();
681

M
Mr.doob 已提交
682 683 684 685 686 687
		_gl.drawArrays( _gl.TRIANGLES, 0, object.count );

		object.count = 0;

	};

688
	this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {
689

M
Mr.doob 已提交
690 691
		setMaterial( material );

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

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

		if ( geometryProgram !== _currentGeometryProgram ) {

			_currentGeometryProgram = geometryProgram;
			updateBuffers = true;

		}

		// morph targets

		var morphTargetInfluences = object.morphTargetInfluences;

		if ( morphTargetInfluences !== undefined ) {

			var activeInfluences = [];

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

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

			}

719
			activeInfluences.sort( absNumericalSort );
M
Mr.doob 已提交
720 721 722 723 724 725 726

			if ( activeInfluences.length > 8 ) {

				activeInfluences.length = 8;

			}

727 728
			var morphAttributes = geometry.morphAttributes;

M
Mr.doob 已提交
729 730 731 732 733 734 735
			for ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {

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

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

736
					var index = influence[ 1 ];
M
Mr.doob 已提交
737

738 739
					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 已提交
740 741 742

				} else {

743 744
					if ( material.morphTargets === true ) geometry.removeAttribute( 'morphTarget' + i );
					if ( material.morphNormals === true ) geometry.removeAttribute( 'morphNormal' + i );
M
Mr.doob 已提交
745 746 747 748 749

				}

			}

750 751 752 753 754 755
			for ( var i = activeInfluences.length, il = morphInfluences.length; i < il; i ++ ) {

				morphInfluences[ i ] = 0.0;

			}

T
tschw 已提交
756 757
			program.getUniforms().setValue(
					_gl, 'morphTargetInfluences', morphInfluences );
M
Mr.doob 已提交
758 759 760 761 762

			updateBuffers = true;

		}

763 764
		//

765
		var index = geometry.index;
766
		var position = geometry.attributes.position;
767
		var rangeFactor = 1;
768

769 770
		if ( material.wireframe === true ) {

771
			index = objects.getWireframeAttribute( geometry );
772
			rangeFactor = 2;
773 774 775

		}

776 777
		var renderer;

778
		if ( index !== null ) {
779

780 781
			renderer = indexedBufferRenderer;
			renderer.setIndex( index );
782

783
		} else {
784

785
			renderer = bufferRenderer;
786

787
		}
M
Mr.doob 已提交
788

789
		if ( updateBuffers ) {
M
Mr.doob 已提交
790

791
			setupVertexAttributes( material, program, geometry );
M
Mr.doob 已提交
792

793
			if ( index !== null ) {
794

795
				_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, objects.getAttributeBuffer( index ) );
796 797 798

			}

799
		}
800

801 802
		//

803
		var dataCount = 0;
804

M
Mr.doob 已提交
805
		if ( index !== null ) {
806

M
Mr.doob 已提交
807
			dataCount = index.count;
808

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

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

M
Mr.doob 已提交
813
		}
814

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

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

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

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

826 827
		if ( drawCount === 0 ) return;

M
Mr.doob 已提交
828
		//
829

830
		if ( object.isMesh ) {
831

832
			if ( material.wireframe === true ) {
833

834
				state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );
835
				renderer.setMode( _gl.LINES );
836

837
			} else {
M
Mr.doob 已提交
838 839

				switch ( object.drawMode ) {
840

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

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

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

				}
854

855
			}
856

857

858
		} else if ( object.isLine ) {
859

860
			var lineWidth = material.linewidth;
861

862
			if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material
863

864
			state.setLineWidth( lineWidth * getTargetPixelRatio() );
865

866
			if ( object.isLineSegments ) {
867

868
				renderer.setMode( _gl.LINES );
869

870
			} else {
871

872
				renderer.setMode( _gl.LINE_STRIP );
873 874

			}
M
Mr.doob 已提交
875

876
		} else if ( object.isPoints ) {
877 878

			renderer.setMode( _gl.POINTS );
879 880

		}
881

T
Takahiro 已提交
882
		if ( geometry && geometry.isInstancedBufferGeometry ) {
M
Mr.doob 已提交
883 884 885

			if ( geometry.maxInstancedCount > 0 ) {

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

J
jfranc 已提交
888
			}
889 890 891

		} else {

M
Mr.doob 已提交
892
			renderer.render( drawStart, drawCount );
893

M
Mr.doob 已提交
894 895 896 897
		}

	};

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

M
Mr.doob 已提交
900
		var extension;
B
Ben Adams 已提交
901

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

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

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

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

M
Mr.doob 已提交
911 912 913
			}

		}
B
Ben Adams 已提交
914

915 916
		if ( startIndex === undefined ) startIndex = 0;

917 918
		state.initAttributes();

919
		var geometryAttributes = geometry.attributes;
920

921
		var programAttributes = program.getAttributes();
922

923
		var materialDefaultAttributeValues = material.defaultAttributeValues;
924

925
		for ( var name in programAttributes ) {
926

927
			var programAttribute = programAttributes[ name ];
M
Mr.doob 已提交
928

M
Mr.doob 已提交
929
			if ( programAttribute >= 0 ) {
M
Mr.doob 已提交
930

931
				var geometryAttribute = geometryAttributes[ name ];
932

M
Mr.doob 已提交
933
				if ( geometryAttribute !== undefined ) {
M
Mr.doob 已提交
934

935
					var normalized = geometryAttribute.normalized;
936
					var size = geometryAttribute.itemSize;
937

938
					var attributeProperties = objects.getAttributeProperties( geometryAttribute );
939

940 941 942
					var buffer = attributeProperties.__webglBuffer;
					var type = attributeProperties.type;
					var bytesPerElement = attributeProperties.bytesPerElement;
943

A
aardgoose 已提交
944
					if ( geometryAttribute.isInterleavedBufferAttribute ) {
945

M
Mr.doob 已提交
946 947 948 949
						var data = geometryAttribute.data;
						var stride = data.stride;
						var offset = geometryAttribute.offset;

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

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

M
Mr.doob 已提交
954
							if ( geometry.maxInstancedCount === undefined ) {
955

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

M
Mr.doob 已提交
958
							}
B
Ben Adams 已提交
959

M
Mr.doob 已提交
960
						} else {
B
Ben Adams 已提交
961

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

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

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

M
Mr.doob 已提交
969
					} else {
B
Ben Adams 已提交
970

A
aardgoose 已提交
971
						if ( geometryAttribute.isInstancedBufferAttribute ) {
B
Ben Adams 已提交
972

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

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

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

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

M
Mr.doob 已提交
981 982 983 984
						} else {

							state.enableAttribute( programAttribute );

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

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

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

992 993
				} else if ( materialDefaultAttributeValues !== undefined ) {

T
tschw 已提交
994
					var value = materialDefaultAttributeValues[ name ];
995

996
					if ( value !== undefined ) {
M
Mr.doob 已提交
997

998
						switch ( value.length ) {
M
Mr.doob 已提交
999

1000 1001 1002
							case 2:
								_gl.vertexAttrib2fv( programAttribute, value );
								break;
M
Mr.doob 已提交
1003

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

1008 1009 1010
							case 4:
								_gl.vertexAttrib4fv( programAttribute, value );
								break;
1011

1012 1013
							default:
								_gl.vertexAttrib1fv( programAttribute, value );
1014 1015

						}
M
Mr.doob 已提交
1016 1017 1018 1019 1020 1021 1022 1023

					}

				}

			}

		}
1024

1025
		state.disableUnusedAttributes();
1026

M
Mr.doob 已提交
1027 1028
	}

M
Mr.doob 已提交
1029 1030
	// Sorting

1031
	function absNumericalSort( a, b ) {
1032

1033
		return Math.abs( b[ 0 ] ) - Math.abs( a[ 0 ] );
1034 1035 1036

	}

M
Mr.doob 已提交
1037
	function painterSortStable( a, b ) {
M
Mr.doob 已提交
1038

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

U
unconed 已提交
1041
			return a.object.renderOrder - b.object.renderOrder;
1042

1043 1044 1045 1046
		} 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 已提交
1047
		} else if ( a.material.id !== b.material.id ) {
M
Mr.doob 已提交
1048

M
Mr.doob 已提交
1049
			return a.material.id - b.material.id;
1050 1051

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

M
Mr.doob 已提交
1053
			return a.z - b.z;
M
Mr.doob 已提交
1054 1055 1056

		} else {

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

		}

1061
	}
M
Mr.doob 已提交
1062

M
Mr.doob 已提交
1063
	function reversePainterSortStable( a, b ) {
1064

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

U
unconed 已提交
1067
			return a.object.renderOrder - b.object.renderOrder;
1068 1069

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

M
Mr.doob 已提交
1071
			return b.z - a.z;
1072 1073 1074 1075 1076 1077 1078

		} else {

			return a.id - b.id;

		}

1079
	}
1080

M
Mr.doob 已提交
1081 1082 1083 1084
	// Rendering

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

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

1087
			console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );
M
Mr.doob 已提交
1088 1089 1090 1091 1092 1093
			return;

		}

		// reset caching for this frame

1094
		_currentGeometryProgram = '';
1095
		_currentMaterialId = - 1;
1096
		_currentCamera = null;
M
Mr.doob 已提交
1097 1098 1099

		// update scene graph

1100
		if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
M
Mr.doob 已提交
1101 1102 1103

		// update camera matrices and frustum

1104
		if ( camera.parent === null ) camera.updateMatrixWorld();
M
Mr.doob 已提交
1105 1106 1107 1108 1109 1110

		camera.matrixWorldInverse.getInverse( camera.matrixWorld );

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

M
Mr.doob 已提交
1111
		lights.length = 0;
1112

M
Mr.doob 已提交
1113 1114
		opaqueObjectsLastIndex = - 1;
		transparentObjectsLastIndex = - 1;
1115

M
Mr.doob 已提交
1116 1117 1118
		sprites.length = 0;
		lensFlares.length = 0;

T
tschw 已提交
1119
		_localClippingEnabled = this.localClippingEnabled;
M
Mr.doob 已提交
1120
		_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );
T
tschw 已提交
1121

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

1124 1125 1126
		opaqueObjects.length = opaqueObjectsLastIndex + 1;
		transparentObjects.length = transparentObjectsLastIndex + 1;

M
Mr.doob 已提交
1127
		if ( _this.sortObjects === true ) {
1128 1129 1130

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

1132 1133
		}

M
Mr.doob 已提交
1134
		//
M
Mr.doob 已提交
1135

T
tschw 已提交
1136
		if ( _clippingEnabled ) _clipping.beginShadows();
T
tschw 已提交
1137

1138 1139
		setupShadows( lights );

M
Mr.doob 已提交
1140
		shadowMap.render( scene, camera );
M
Mr.doob 已提交
1141

1142 1143
		setupLights( lights, camera );

T
tschw 已提交
1144
		if ( _clippingEnabled ) _clipping.endShadows();
T
tschw 已提交
1145

M
Mr.doob 已提交
1146 1147
		//

1148 1149 1150 1151
		_infoRender.calls = 0;
		_infoRender.vertices = 0;
		_infoRender.faces = 0;
		_infoRender.points = 0;
M
Mr.doob 已提交
1152

1153 1154 1155 1156 1157 1158
		if ( renderTarget === undefined ) {

			renderTarget = null;

		}

M
Mr.doob 已提交
1159 1160
		this.setRenderTarget( renderTarget );

M
Mr.doob 已提交
1161 1162 1163 1164 1165 1166
		//

		var background = scene.background;

		if ( background === null ) {

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

T
Takahiro 已提交
1169
		} else if ( background && background.isColor ) {
1170

1171
			state.buffers.color.setClear( background.r, background.g, background.b, 1, _premultipliedAlpha );
1172
			forceClear = true;
1173 1174 1175 1176 1177 1178 1179 1180 1181

		}

		if ( this.autoClear || forceClear ) {

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

		}

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

1184
			backgroundCamera2.projectionMatrix.copy( camera.projectionMatrix );
M
Mr.doob 已提交
1185 1186 1187 1188 1189 1190 1191

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

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

1192 1193
			objects.update( backgroundBoxMesh );

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

T
Takahiro 已提交
1196
		} else if ( background && background.isTexture ) {
M
Mr.doob 已提交
1197 1198 1199

			backgroundPlaneMesh.material.map = background;

1200 1201
			objects.update( backgroundPlaneMesh );

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

M
Mr.doob 已提交
1204 1205
		}

1206
		//
M
Mr.doob 已提交
1207 1208 1209

		if ( scene.overrideMaterial ) {

1210
			var overrideMaterial = scene.overrideMaterial;
M
Mr.doob 已提交
1211

1212 1213
			renderObjects( opaqueObjects, scene, camera, overrideMaterial );
			renderObjects( transparentObjects, scene, camera, overrideMaterial );
1214

M
Mr.doob 已提交
1215 1216 1217 1218
		} else {

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

R
Rich Harris 已提交
1219
			state.setBlending( NoBlending );
1220
			renderObjects( opaqueObjects, scene, camera );
M
Mr.doob 已提交
1221 1222 1223

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

1224
			renderObjects( transparentObjects, scene, camera );
M
Mr.doob 已提交
1225 1226 1227 1228 1229

		}

		// custom render plugins (post pass)

M
Mr.doob 已提交
1230
		spritePlugin.render( scene, camera );
1231
		lensFlarePlugin.render( scene, camera, _currentViewport );
M
Mr.doob 已提交
1232 1233 1234

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

M
Mr.doob 已提交
1235 1236
		if ( renderTarget ) {

1237
			textures.updateRenderTargetMipmap( renderTarget );
M
Mr.doob 已提交
1238 1239 1240

		}

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

M
Mr.doob 已提交
1243 1244
		state.setDepthTest( true );
		state.setDepthWrite( true );
1245
		state.setColorWrite( true );
M
Mr.doob 已提交
1246 1247 1248 1249

		// _gl.finish();

	};
M
Mr.doob 已提交
1250

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

1253
		var array, index;
M
Mr.doob 已提交
1254

1255
		// allocate the next position in the appropriate array
M
Mr.doob 已提交
1256 1257 1258

		if ( material.transparent ) {

1259 1260
			array = transparentObjects;
			index = ++ transparentObjectsLastIndex;
M
Mr.doob 已提交
1261 1262 1263

		} else {

1264 1265 1266 1267 1268
			array = opaqueObjects;
			index = ++ opaqueObjectsLastIndex;

		}

1269 1270
		// recycle existing render item or grow the array

1271 1272 1273 1274 1275 1276 1277 1278 1279 1280
		var renderItem = array[ index ];

		if ( renderItem !== undefined ) {

			renderItem.id = object.id;
			renderItem.object = object;
			renderItem.geometry = geometry;
			renderItem.material = material;
			renderItem.z = _vector3.z;
			renderItem.group = group;
M
Mr.doob 已提交
1281 1282 1283

		} else {

1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294
			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 已提交
1295 1296 1297 1298 1299

		}

	}

M
Mr.doob 已提交
1300 1301
	// TODO Duplicated code (Frustum)

T
tschw 已提交
1302 1303 1304 1305 1306 1307 1308
	function isObjectViewable( object ) {

		var geometry = object.geometry;

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

M
Mr.doob 已提交
1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326
		_sphere.copy( geometry.boundingSphere ).
			applyMatrix4( object.matrixWorld );

		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 已提交
1327 1328

		if ( ! _frustum.intersectsSphere( sphere ) ) return false;
T
tschw 已提交
1329 1330 1331 1332

		var numPlanes = _clipping.numPlanes;

		if ( numPlanes === 0 ) return true;
T
tschw 已提交
1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344

		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 已提交
1345
		} while ( ++ i !== numPlanes );
T
tschw 已提交
1346 1347 1348 1349 1350

		return true;

	}

1351
	function projectObject( object, camera ) {
M
Mr.doob 已提交
1352

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

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

1357 1358 1359
		if ( visible ) {

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

1361
				lights.push( object );
M
Mr.doob 已提交
1362

1363
			} else if ( object.isSprite ) {
M
Mr.doob 已提交
1364

M
Mr.doob 已提交
1365
				if ( object.frustumCulled === false || isSpriteViewable( object ) === true ) {
1366 1367 1368 1369

					sprites.push( object );

				}
M
Mr.doob 已提交
1370

1371
			} else if ( object.isLensFlare ) {
M
Mr.doob 已提交
1372

1373
				lensFlares.push( object );
M
Mr.doob 已提交
1374

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

1377
				if ( _this.sortObjects === true ) {
M
Mr.doob 已提交
1378

1379 1380
					_vector3.setFromMatrixPosition( object.matrixWorld );
					_vector3.applyProjection( _projScreenMatrix );
M
Mr.doob 已提交
1381

1382
				}
1383

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

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

1388
				if ( object.isSkinnedMesh ) {
M
Mr.doob 已提交
1389

1390
					object.skeleton.update();
1391

1392
				}
1393

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

1396
					var material = object.material;
1397

1398
					if ( material.visible === true ) {
M
Mr.doob 已提交
1399

1400
						if ( _this.sortObjects === true ) {
M
Mr.doob 已提交
1401

1402 1403 1404 1405
							_vector3.setFromMatrixPosition( object.matrixWorld );
							_vector3.applyProjection( _projScreenMatrix );

						}
M
Mr.doob 已提交
1406

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

1409
						if ( material.isMultiMaterial ) {
1410

1411 1412
							var groups = geometry.groups;
							var materials = material.materials;
1413

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

1416 1417
								var group = groups[ i ];
								var groupMaterial = materials[ group.materialIndex ];
1418

1419
								if ( groupMaterial.visible === true ) {
1420

1421 1422 1423
									pushRenderItem( object, geometry, groupMaterial, _vector3.z, group );

								}
M
Mr.doob 已提交
1424

M
Mr.doob 已提交
1425
							}
M
Mr.doob 已提交
1426

1427
						} else {
M
Mr.doob 已提交
1428

1429
							pushRenderItem( object, geometry, material, _vector3.z, null );
1430

1431
						}
O
OpenShift guest 已提交
1432

1433
					}
M
Mr.doob 已提交
1434

1435
				}
M
Mr.doob 已提交
1436

1437
			}
M
Mr.doob 已提交
1438

M
Mr.doob 已提交
1439
		}
M
Mr.doob 已提交
1440

M
Mr.doob 已提交
1441
		var children = object.children;
M
Mr.doob 已提交
1442

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

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

1447
		}
1448

1449
	}
M
Mr.doob 已提交
1450

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

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

1455
			var renderItem = renderList[ i ];
M
Mr.doob 已提交
1456

1457
			var object = renderItem.object;
M
Mr.doob 已提交
1458 1459 1460
			var geometry = renderItem.geometry;
			var material = overrideMaterial === undefined ? renderItem.material : overrideMaterial;
			var group = renderItem.group;
M
Mr.doob 已提交
1461

1462 1463
			object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
			object.normalMatrix.getNormalMatrix( object.modelViewMatrix );
M
Mr.doob 已提交
1464

1465
			object.onBeforeRender( _this, scene, camera, geometry, material, group );
1466

1467
			if ( object.isImmediateRenderObject ) {
M
Mr.doob 已提交
1468

M
Mr.doob 已提交
1469
				setMaterial( material );
M
Mr.doob 已提交
1470

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

M
Mr.doob 已提交
1473
				_currentGeometryProgram = '';
M
Mr.doob 已提交
1474

M
Mr.doob 已提交
1475
				object.render( function ( object ) {
M
Mr.doob 已提交
1476

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

M
Mr.doob 已提交
1479
				} );
1480

M
Mr.doob 已提交
1481
			} else {
M
Mr.doob 已提交
1482

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

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

1487
			object.onAfterRender( _this, scene, camera, geometry, material, group );
D
Dusan Bosnjak 已提交
1488 1489


1490
		}
M
Mr.doob 已提交
1491

1492
	}
G
gero3 已提交
1493

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

1496
		var materialProperties = properties.get( material );
G
gero3 已提交
1497

T
tschw 已提交
1498
		var parameters = programCache.getParameters(
1499
				material, _lights, fog, _clipping.numPlanes, _clipping.numIntersection, object );
T
tschw 已提交
1500

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

1503
		var program = materialProperties.program;
T
tschw 已提交
1504
		var programChange = true;
1505

1506
		if ( program === undefined ) {
B
Ben Adams 已提交
1507

M
Mr.doob 已提交
1508 1509
			// new material
			material.addEventListener( 'dispose', onMaterialDispose );
B
Ben Adams 已提交
1510

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

M
Mr.doob 已提交
1513
			// changed glsl or parameters
1514
			releaseMaterialProgramReference( material );
B
Ben Adams 已提交
1515

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

T
tschw 已提交
1518
			// same glsl and uniform list
T
tschw 已提交
1519 1520
			return;

T
tschw 已提交
1521
		} else {
B
Ben Adams 已提交
1522

T
tschw 已提交
1523 1524
			// only rebuild uniform list
			programChange = false;
B
Ben Adams 已提交
1525 1526 1527

		}

1528
		if ( programChange ) {
B
Ben Adams 已提交
1529

1530
			if ( parameters.shaderID ) {
B
Ben Adams 已提交
1531

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

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

1541
			} else {
B
Ben Adams 已提交
1542

1543 1544 1545 1546 1547 1548
				materialProperties.__webglShader = {
					name: material.type,
					uniforms: material.uniforms,
					vertexShader: material.vertexShader,
					fragmentShader: material.fragmentShader
				};
G
gero3 已提交
1549

1550
			}
G
gero3 已提交
1551

1552
			material.__webglShader = materialProperties.__webglShader;
G
gero3 已提交
1553

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

1556 1557
			materialProperties.program = program;
			material.program = program;
1558 1559 1560

		}

1561
		var attributes = program.getAttributes();
M
Mr.doob 已提交
1562 1563 1564 1565 1566

		if ( material.morphTargets ) {

			material.numSupportedMorphTargets = 0;

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

M
Mr.doob 已提交
1569
				if ( attributes[ 'morphTarget' + i ] >= 0 ) {
M
Mr.doob 已提交
1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582

					material.numSupportedMorphTargets ++;

				}

			}

		}

		if ( material.morphNormals ) {

			material.numSupportedMorphNormals = 0;

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

M
Mr.doob 已提交
1585
				if ( attributes[ 'morphNormal' + i ] >= 0 ) {
M
Mr.doob 已提交
1586 1587 1588 1589 1590 1591 1592 1593 1594

					material.numSupportedMorphNormals ++;

				}

			}

		}

T
tschw 已提交
1595 1596
		var uniforms = materialProperties.__webglShader.uniforms;

1597
		if ( ! material.isShaderMaterial &&
1598
		     ! material.isRawShaderMaterial ||
1599
		       material.clipping === true ) {
T
tschw 已提交
1600

T
tschw 已提交
1601
			materialProperties.numClippingPlanes = _clipping.numPlanes;
1602
			materialProperties.numIntersection = _clipping.numIntersection;
T
tschw 已提交
1603
			uniforms.clippingPlanes = _clipping.uniform;
T
tschw 已提交
1604 1605 1606

		}

1607
		materialProperties.fog = fog;
1608

1609
		// store the light setup it was created for
1610

1611
		materialProperties.lightsHash = _lights.hash;
1612

M
Mr.doob 已提交
1613
		if ( material.lights ) {
1614 1615 1616 1617 1618 1619

			// 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;
M
Mr.doob 已提交
1620
			uniforms.pointLights.value = _lights.point;
1621 1622
			uniforms.hemisphereLights.value = _lights.hemi;

1623 1624 1625 1626 1627 1628
			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;
1629

1630 1631
		}

T
tschw 已提交
1632 1633
		var progUniforms = materialProperties.program.getUniforms(),
			uniformsList =
R
Rich Harris 已提交
1634
					WebGLUniforms.seqWithValue( progUniforms.seq, uniforms );
A
arose 已提交
1635

T
tschw 已提交
1636
		materialProperties.uniformsList = uniformsList;
A
arose 已提交
1637

M
Mr.doob 已提交
1638
	}
M
Mr.doob 已提交
1639

1640 1641
	function setMaterial( material ) {

M
Mr.doob 已提交
1642 1643 1644
		material.side === DoubleSide
			? state.disable( _gl.CULL_FACE )
			: state.enable( _gl.CULL_FACE );
T
tschw 已提交
1645

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

M
Mr.doob 已提交
1648 1649 1650
		material.transparent === true
			? state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha )
			: state.setBlending( NoBlending );
1651

B
Ben Adams 已提交
1652
		state.setDepthFunc( material.depthFunc );
M
Mr.doob 已提交
1653 1654
		state.setDepthTest( material.depthTest );
		state.setDepthWrite( material.depthWrite );
1655
		state.setColorWrite( material.colorWrite );
M
Mr.doob 已提交
1656
		state.setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
1657 1658 1659

	}

1660
	function setProgram( camera, fog, material, object ) {
M
Mr.doob 已提交
1661 1662 1663

		_usedTextureUnits = 0;

1664
		var materialProperties = properties.get( material );
1665

T
tschw 已提交
1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676
		if ( _clippingEnabled ) {

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

				var useCache =
						camera === _currentCamera &&
						material.id === _currentMaterialId;

				// we might want to call this function with some ClippingGroup
				// object instead of the material, once it becomes feasible
				// (#8465, #8379)
T
tschw 已提交
1677
				_clipping.setState(
1678
						material.clippingPlanes, material.clipIntersection, material.clipShadows,
T
tschw 已提交
1679 1680 1681 1682 1683 1684
						camera, materialProperties, useCache );

			}

		}

1685
		if ( material.needsUpdate === false ) {
1686

1687
			if ( materialProperties.program === undefined ) {
1688

1689
				material.needsUpdate = true;
1690

1691
			} else if ( material.fog && materialProperties.fog !== fog ) {
1692

M
Mr.doob 已提交
1693
				material.needsUpdate = true;
1694

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

1697
				material.needsUpdate = true;
1698

1699
			} else if ( materialProperties.numClippingPlanes !== undefined &&
1700
				( materialProperties.numClippingPlanes !== _clipping.numPlanes ||
1701
 				  materialProperties.numIntersection  !== _clipping.numIntersection ) ) {
1702 1703 1704

				material.needsUpdate = true;

1705
			}
1706 1707 1708 1709

		}

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

1711
			initMaterial( material, fog, object );
M
Mr.doob 已提交
1712 1713 1714 1715
			material.needsUpdate = false;

		}

1716
		var refreshProgram = false;
M
Mr.doob 已提交
1717
		var refreshMaterial = false;
1718
		var refreshLights = false;
M
Mr.doob 已提交
1719

1720
		var program = materialProperties.program,
1721
			p_uniforms = program.getUniforms(),
1722
			m_uniforms = materialProperties.__webglShader.uniforms;
M
Mr.doob 已提交
1723

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

1726 1727
			_gl.useProgram( program.program );
			_currentProgram = program.id;
M
Mr.doob 已提交
1728

1729
			refreshProgram = true;
M
Mr.doob 已提交
1730
			refreshMaterial = true;
1731
			refreshLights = true;
M
Mr.doob 已提交
1732 1733 1734 1735 1736 1737

		}

		if ( material.id !== _currentMaterialId ) {

			_currentMaterialId = material.id;
1738

M
Mr.doob 已提交
1739 1740 1741 1742
			refreshMaterial = true;

		}

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

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

G
gero3 已提交
1747
			if ( capabilities.logarithmicDepthBuffer ) {
1748

T
tschw 已提交
1749 1750
				p_uniforms.setValue( _gl, 'logDepthBufFC',
						2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
1751 1752 1753 1754

			}


1755 1756 1757 1758 1759 1760 1761 1762 1763
			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 已提交
1764
				refreshLights = true;		// remains set until update done
1765 1766

			}
M
Mr.doob 已提交
1767

1768 1769 1770
			// load material specific uniforms
			// (shader material also gets them for the sake of genericity)

1771 1772 1773 1774
			if ( material.isShaderMaterial ||
			     material.isMeshPhongMaterial ||
			     material.isMeshStandardMaterial ||
			     material.envMap ) {
1775

T
tschw 已提交
1776 1777 1778
				var uCamPos = p_uniforms.map.cameraPosition;

				if ( uCamPos !== undefined ) {
1779

T
tschw 已提交
1780 1781
					uCamPos.setValue( _gl,
							_vector3.setFromMatrixPosition( camera.matrixWorld ) );
1782 1783 1784 1785 1786

				}

			}

1787 1788 1789 1790 1791 1792
			if ( material.isMeshPhongMaterial ||
			     material.isMeshLambertMaterial ||
			     material.isMeshBasicMaterial ||
			     material.isMeshStandardMaterial ||
			     material.isShaderMaterial ||
			     material.skinning ) {
1793

T
tschw 已提交
1794
				p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );
1795 1796 1797

			}

T
tschw 已提交
1798 1799
			p_uniforms.set( _gl, _this, 'toneMappingExposure' );
			p_uniforms.set( _gl, _this, 'toneMappingWhitePoint' );
M
Mr.doob 已提交
1800

M
Mr.doob 已提交
1801 1802 1803 1804 1805 1806 1807 1808
		}

		// skinning uniforms must be set even if material didn't change
		// auto-setting of texture unit for bone texture must go before other textures
		// not sure why, but otherwise weird things happen

		if ( material.skinning ) {

T
tschw 已提交
1809 1810
			p_uniforms.setOptional( _gl, object, 'bindMatrix' );
			p_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );
1811

T
tschw 已提交
1812
			var skeleton = object.skeleton;
1813

T
tschw 已提交
1814
			if ( skeleton ) {
1815

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

T
tschw 已提交
1818 1819 1820
					p_uniforms.set( _gl, skeleton, 'boneTexture' );
					p_uniforms.set( _gl, skeleton, 'boneTextureWidth' );
					p_uniforms.set( _gl, skeleton, 'boneTextureHeight' );
M
Mr.doob 已提交
1821

T
tschw 已提交
1822
				} else {
M
Mr.doob 已提交
1823

T
tschw 已提交
1824
					p_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );
M
Mr.doob 已提交
1825 1826 1827 1828 1829 1830 1831 1832 1833

				}

			}

		}

		if ( refreshMaterial ) {

M
Mr.doob 已提交
1834
			if ( material.lights ) {
M
Mr.doob 已提交
1835

1836
				// the current material requires lighting info
M
Mr.doob 已提交
1837

T
tschw 已提交
1838 1839 1840 1841 1842 1843
				// 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 已提交
1844

T
tschw 已提交
1845
				markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
G
gero3 已提交
1846

T
tschw 已提交
1847
			}
G
gero3 已提交
1848

T
tschw 已提交
1849
			// refresh uniforms common to several materials
G
gero3 已提交
1850

T
tschw 已提交
1851
			if ( fog && material.fog ) {
G
gero3 已提交
1852

T
tschw 已提交
1853
				refreshUniformsFog( m_uniforms, fog );
M
Mr.doob 已提交
1854 1855 1856

			}

1857 1858 1859 1860 1861
			if ( material.isMeshBasicMaterial ||
			     material.isMeshLambertMaterial ||
			     material.isMeshPhongMaterial ||
			     material.isMeshStandardMaterial ||
			     material.isMeshDepthMaterial ) {
M
Mr.doob 已提交
1862 1863 1864 1865 1866 1867 1868

				refreshUniformsCommon( m_uniforms, material );

			}

			// refresh single material specific uniforms

1869
			if ( material.isLineBasicMaterial ) {
M
Mr.doob 已提交
1870 1871 1872

				refreshUniformsLine( m_uniforms, material );

1873
			} else if ( material.isLineDashedMaterial ) {
M
Mr.doob 已提交
1874 1875 1876 1877

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

1878
			} else if ( material.isPointsMaterial ) {
M
Mr.doob 已提交
1879

M
Mr.doob 已提交
1880
				refreshUniformsPoints( m_uniforms, material );
M
Mr.doob 已提交
1881

1882
			} else if ( material.isMeshLambertMaterial ) {
1883 1884 1885

				refreshUniformsLambert( m_uniforms, material );

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

				refreshUniformsPhong( m_uniforms, material );

1890
			} else if ( material.isMeshPhysicalMaterial ) {
W
WestLangley 已提交
1891 1892 1893

				refreshUniformsPhysical( m_uniforms, material );

1894
			} else if ( material.isMeshStandardMaterial ) {
W
WestLangley 已提交
1895

1896
				refreshUniformsStandard( m_uniforms, material );
W
WestLangley 已提交
1897

1898
			} else if ( material.isMeshDepthMaterial ) {
M
Mr.doob 已提交
1899

1900 1901 1902 1903 1904 1905 1906 1907
				if ( material.displacementMap ) {

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

				}

1908
			} else if ( material.isMeshNormalMaterial ) {
M
Mr.doob 已提交
1909 1910 1911 1912 1913

				m_uniforms.opacity.value = material.opacity;

			}

R
Rich Harris 已提交
1914
			WebGLUniforms.upload(
T
tschw 已提交
1915
					_gl, materialProperties.uniformsList, m_uniforms, _this );
A
arose 已提交
1916 1917 1918

		}

M
Mr.doob 已提交
1919

T
tschw 已提交
1920
		// common matrices
M
Mr.doob 已提交
1921

T
tschw 已提交
1922 1923 1924
		p_uniforms.set( _gl, object, 'modelViewMatrix' );
		p_uniforms.set( _gl, object, 'normalMatrix' );
		p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );
A
arose 已提交
1925

T
tschw 已提交
1926
		return program;
A
arose 已提交
1927 1928 1929

	}

M
Mr.doob 已提交
1930 1931
	// Uniforms (refresh uniforms objects)

M
Mr.doob 已提交
1932
	function refreshUniformsCommon( uniforms, material ) {
M
Mr.doob 已提交
1933 1934 1935

		uniforms.opacity.value = material.opacity;

1936
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
1937

1938
		if ( material.emissive ) {
M
Mr.doob 已提交
1939

1940
			uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );
M
Mr.doob 已提交
1941 1942 1943

		}

1944 1945 1946
		uniforms.map.value = material.map;
		uniforms.specularMap.value = material.specularMap;
		uniforms.alphaMap.value = material.alphaMap;
M
Mr.doob 已提交
1947

1948 1949 1950 1951 1952 1953 1954
		if ( material.lightMap ) {

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

		}

1955
		if ( material.aoMap ) {
1956

1957 1958
			uniforms.aoMap.value = material.aoMap;
			uniforms.aoMapIntensity.value = material.aoMapIntensity;
1959 1960 1961

		}

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

		var uvScaleMap;

		if ( material.map ) {

			uvScaleMap = material.map;

		} else if ( material.specularMap ) {

			uvScaleMap = material.specularMap;

1980 1981 1982 1983
		} else if ( material.displacementMap ) {

			uvScaleMap = material.displacementMap;

M
Mr.doob 已提交
1984 1985 1986 1987 1988 1989 1990 1991
		} else if ( material.normalMap ) {

			uvScaleMap = material.normalMap;

		} else if ( material.bumpMap ) {

			uvScaleMap = material.bumpMap;

1992 1993 1994 1995 1996 1997 1998 1999
		} else if ( material.roughnessMap ) {

			uvScaleMap = material.roughnessMap;

		} else if ( material.metalnessMap ) {

			uvScaleMap = material.metalnessMap;

2000 2001 2002 2003
		} else if ( material.alphaMap ) {

			uvScaleMap = material.alphaMap;

2004 2005 2006 2007
		} else if ( material.emissiveMap ) {

			uvScaleMap = material.emissiveMap;

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

		if ( uvScaleMap !== undefined ) {

2012
			// backwards compatibility
2013
			if ( uvScaleMap.isWebGLRenderTarget ) {
M
Mr.doob 已提交
2014 2015 2016 2017 2018

				uvScaleMap = uvScaleMap.texture;

			}

M
Mr.doob 已提交
2019 2020 2021 2022 2023 2024 2025 2026
			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;
2027 2028 2029 2030 2031

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

2034
		uniforms.reflectivity.value = material.reflectivity;
M
Mr.doob 已提交
2035 2036
		uniforms.refractionRatio.value = material.refractionRatio;

M
Mr.doob 已提交
2037
	}
M
Mr.doob 已提交
2038

M
Mr.doob 已提交
2039
	function refreshUniformsLine( uniforms, material ) {
M
Mr.doob 已提交
2040 2041 2042 2043

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

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

M
Mr.doob 已提交
2046
	function refreshUniformsDash( uniforms, material ) {
M
Mr.doob 已提交
2047 2048 2049 2050 2051

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

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

M
Mr.doob 已提交
2054
	function refreshUniformsPoints( uniforms, material ) {
M
Mr.doob 已提交
2055

2056
		uniforms.diffuse.value = material.color;
M
Mr.doob 已提交
2057
		uniforms.opacity.value = material.opacity;
2058
		uniforms.size.value = material.size * _pixelRatio;
2059
		uniforms.scale.value = _height * 0.5;
M
Mr.doob 已提交
2060 2061 2062

		uniforms.map.value = material.map;

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

M
Mr.doob 已提交
2074
	function refreshUniformsFog( uniforms, fog ) {
M
Mr.doob 已提交
2075 2076 2077

		uniforms.fogColor.value = fog.color;

2078
		if ( fog.isFog ) {
M
Mr.doob 已提交
2079 2080 2081 2082

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

2083
		} else if ( fog.isFogExp2 ) {
M
Mr.doob 已提交
2084 2085 2086 2087 2088

			uniforms.fogDensity.value = fog.density;

		}

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

M
Mr.doob 已提交
2091
	function refreshUniformsLambert( uniforms, material ) {
2092 2093 2094 2095 2096 2097 2098 2099 2100

		if ( material.emissiveMap ) {

			uniforms.emissiveMap.value = material.emissiveMap;

		}

	}

M
Mr.doob 已提交
2101
	function refreshUniformsPhong( uniforms, material ) {
M
Mr.doob 已提交
2102

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

2106
		if ( material.emissiveMap ) {
2107

2108
			uniforms.emissiveMap.value = material.emissiveMap;
2109

2110
		}
M
Mr.doob 已提交
2111

2112 2113 2114 2115
		if ( material.bumpMap ) {

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

2117
		}
M
Mr.doob 已提交
2118

2119 2120 2121 2122 2123 2124
		if ( material.normalMap ) {

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

		}
M
Mr.doob 已提交
2125

2126 2127 2128 2129 2130
		if ( material.displacementMap ) {

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

2132
		}
2133 2134 2135

	}

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

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

2192 2193 2194
		uniforms.clearCoat.value = material.clearCoat;
		uniforms.clearCoatRoughness.value = material.clearCoatRoughness;

W
WestLangley 已提交
2195 2196 2197 2198
		refreshUniformsStandard( uniforms, material );

	}

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

M
Mr.doob 已提交
2201
	function markUniformsLightsNeedsUpdate( uniforms, value ) {
2202

M
Mr.doob 已提交
2203
		uniforms.ambientLightColor.needsUpdate = value;
2204

B
Ben Houston 已提交
2205 2206 2207 2208
		uniforms.directionalLights.needsUpdate = value;
		uniforms.pointLights.needsUpdate = value;
		uniforms.spotLights.needsUpdate = value;
		uniforms.hemisphereLights.needsUpdate = value;
2209

M
Mr.doob 已提交
2210
	}
2211

T
tschw 已提交
2212
	// Lighting
M
Mr.doob 已提交
2213

M
Mr.doob 已提交
2214
	function setupShadows( lights ) {
2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233

		var lightShadowsLength = 0;

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

			var light = lights[ i ];

			if ( light.castShadow ) {

				_lights.shadows[ lightShadowsLength ++ ] = light;

			}

		}

		_lights.shadows.length = lightShadowsLength;

	}

M
Mr.doob 已提交
2234
	function setupLights( lights, camera ) {
M
Mr.doob 已提交
2235

B
brason 已提交
2236
		var l, ll, light,
M
Mr.doob 已提交
2237
		r = 0, g = 0, b = 0,
B
Ben Houston 已提交
2238
		color,
B
brason 已提交
2239
		intensity,
M
Mr.doob 已提交
2240
		distance,
2241
		shadowMap,
M
Mr.doob 已提交
2242

2243
		viewMatrix = camera.matrixWorldInverse,
M
Mr.doob 已提交
2244

M
Mr.doob 已提交
2245
		directionalLength = 0,
M
Mr.doob 已提交
2246 2247
		pointLength = 0,
		spotLength = 0,
2248
		hemiLength = 0;
M
Mr.doob 已提交
2249 2250 2251 2252 2253 2254 2255 2256 2257

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

			light = lights[ l ];

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

2258
			shadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null;
2259

2260
			if ( light.isAmbientLight ) {
M
Mr.doob 已提交
2261

2262 2263 2264
				r += color.r * intensity;
				g += color.g * intensity;
				b += color.b * intensity;
M
Mr.doob 已提交
2265

2266
			} else if ( light.isDirectionalLight ) {
M
Mr.doob 已提交
2267

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

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

2276
				uniforms.shadow = light.castShadow;
M
Mr.doob 已提交
2277

2278
				if ( light.castShadow ) {
M
Mr.doob 已提交
2279

2280 2281 2282
					uniforms.shadowBias = light.shadow.bias;
					uniforms.shadowRadius = light.shadow.radius;
					uniforms.shadowMapSize = light.shadow.mapSize;
2283

2284 2285
				}

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

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

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

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

M
Mr.doob 已提交
2297 2298 2299 2300 2301 2302 2303 2304
				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 );

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

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

2311 2312
				if ( light.castShadow ) {

2313 2314 2315
					uniforms.shadowBias = light.shadow.bias;
					uniforms.shadowRadius = light.shadow.radius;
					uniforms.shadowMapSize = light.shadow.mapSize;
2316

2317 2318
				}

2319
				_lights.spotShadowMap[ spotLength ] = shadowMap;
2320
				_lights.spotShadowMatrix[ spotLength ] = light.shadow.matrix;
M
Mr.doob 已提交
2321
				_lights.spot[ spotLength ++ ] = uniforms;
2322

2323
			} else if ( light.isPointLight ) {
M
Mr.doob 已提交
2324

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

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

M
Mr.doob 已提交
2330 2331
				uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
				uniforms.distance = light.distance;
M
Mr.doob 已提交
2332 2333
				uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;

2334
				uniforms.shadow = light.castShadow;
2335

M
Mr.doob 已提交
2336
				if ( light.castShadow ) {
2337

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

				}
2343

2344
				_lights.pointShadowMap[ pointLength ] = shadowMap;
2345

2346 2347
				if ( _lights.pointShadowMatrix[ pointLength ] === undefined ) {

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

2350 2351
				}

2352 2353 2354 2355 2356
				// 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 已提交
2357
				_lights.point[ pointLength ++ ] = uniforms;
2358

2359
			} else if ( light.isHemisphereLight ) {
M
Mr.doob 已提交
2360

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

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

M
Mr.doob 已提交
2367 2368
				uniforms.skyColor.copy( light.color ).multiplyScalar( intensity );
				uniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );
M
Mr.doob 已提交
2369

M
Mr.doob 已提交
2370
				_lights.hemi[ hemiLength ++ ] = uniforms;
M
Mr.doob 已提交
2371 2372 2373 2374 2375

			}

		}

M
Mr.doob 已提交
2376 2377 2378
		_lights.ambient[ 0 ] = r;
		_lights.ambient[ 1 ] = g;
		_lights.ambient[ 2 ] = b;
M
Mr.doob 已提交
2379

M
Mr.doob 已提交
2380 2381
		_lights.directional.length = directionalLength;
		_lights.spot.length = spotLength;
2382
		_lights.point.length = pointLength;
M
Mr.doob 已提交
2383
		_lights.hemi.length = hemiLength;
2384

2385
		_lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + hemiLength + ',' + _lights.shadows.length;
2386

M
Mr.doob 已提交
2387
	}
M
Mr.doob 已提交
2388 2389 2390 2391 2392

	// GL state setting

	this.setFaceCulling = function ( cullFace, frontFaceDirection ) {

T
tschw 已提交
2393
		state.setCullFace( cullFace );
R
Rich Harris 已提交
2394
		state.setFlipSided( frontFaceDirection === FrontFaceDirectionCW );
M
Mr.doob 已提交
2395 2396 2397 2398 2399

	};

	// Textures

T
tschw 已提交
2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415
	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;

	}

2416
	this.allocTextureUnit = allocTextureUnit;
T
tschw 已提交
2417

2418
	// this.setTexture2D = setTexture2D;
2419
	this.setTexture2D = ( function() {
T
tschw 已提交
2420

2421
		var warned = false;
T
tschw 已提交
2422

2423
		// backwards compatibility: peel texture.texture
W
WestLangley 已提交
2424
		return function setTexture2D( texture, slot ) {
T
tschw 已提交
2425

T
Takahiro 已提交
2426
			if ( texture && texture.isWebGLRenderTarget ) {
T
tschw 已提交
2427

2428
				if ( ! warned ) {
T
tschw 已提交
2429

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

2433
				}
T
tschw 已提交
2434

2435
				texture = texture.texture;
T
tschw 已提交
2436

2437
			}
T
tschw 已提交
2438

2439
			textures.setTexture2D( texture, slot );
T
tschw 已提交
2440

2441
		};
T
tschw 已提交
2442

2443
	}() );
T
tschw 已提交
2444

2445 2446 2447 2448
	this.setTexture = ( function() {

		var warned = false;

W
WestLangley 已提交
2449
		return function setTexture( texture, slot ) {
2450 2451 2452 2453 2454 2455 2456 2457

			if ( ! warned ) {

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

			}

2458
			textures.setTexture2D( texture, slot );
2459 2460 2461 2462 2463 2464 2465 2466 2467

		};

	}() );

	this.setTextureCube = ( function() {

		var warned = false;

W
WestLangley 已提交
2468
		return function setTextureCube( texture, slot ) {
2469 2470

			// backwards compatibility: peel texture.texture
T
Takahiro 已提交
2471
			if ( texture && texture.isWebGLRenderTargetCube ) {
2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485

				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 已提交
2486
			if ( ( texture && texture.isCubeTexture ) ||
2487 2488 2489 2490 2491
				 ( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {

				// CompressedTexture can have Array in image :/

				// this function alone should take care of cube textures
2492
				textures.setTextureCube( texture, slot );
2493 2494 2495 2496 2497

			} else {

				// assumed: texture property of THREE.WebGLRenderTargetCube

2498
				textures.setTextureCubeDynamic( texture, slot );
2499 2500 2501 2502 2503 2504

			}

		};

	}() );
T
tschw 已提交
2505

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

		return _currentRenderTarget;

M
Michael Herzog 已提交
2510
	};
2511

2512
	this.setRenderTarget = function ( renderTarget ) {
M
Mr.doob 已提交
2513

2514 2515
		_currentRenderTarget = renderTarget;

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

2518
			textures.setupRenderTarget( renderTarget );
M
Mr.doob 已提交
2519 2520 2521

		}

T
Takahiro 已提交
2522
		var isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube );
2523
		var framebuffer;
M
Mr.doob 已提交
2524 2525 2526

		if ( renderTarget ) {

2527
			var renderTargetProperties = properties.get( renderTarget );
F
Fordy 已提交
2528

M
Mr.doob 已提交
2529 2530
			if ( isCube ) {

2531
				framebuffer = renderTargetProperties.__webglFramebuffer[ renderTarget.activeCubeFace ];
M
Mr.doob 已提交
2532 2533 2534

			} else {

2535
				framebuffer = renderTargetProperties.__webglFramebuffer;
M
Mr.doob 已提交
2536 2537 2538

			}

2539 2540
			_currentScissor.copy( renderTarget.scissor );
			_currentScissorTest = renderTarget.scissorTest;
2541

2542
			_currentViewport.copy( renderTarget.viewport );
M
Mr.doob 已提交
2543 2544 2545 2546 2547

		} else {

			framebuffer = null;

2548
			_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio );
2549
			_currentScissorTest = _scissorTest;
2550

2551
			_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio );
M
Mr.doob 已提交
2552 2553 2554

		}

M
Mr.doob 已提交
2555
		if ( _currentFramebuffer !== framebuffer ) {
M
Mr.doob 已提交
2556 2557 2558 2559 2560 2561

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

		}

2562 2563
		state.scissor( _currentScissor );
		state.setScissorTest( _currentScissorTest );
2564

2565
		state.viewport( _currentViewport );
2566

M
Mr.doob 已提交
2567 2568 2569
		if ( isCube ) {

			var textureProperties = properties.get( renderTarget.texture );
2570
			_gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel );
M
Mr.doob 已提交
2571 2572 2573

		}

M
Mr.doob 已提交
2574 2575
	};

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

T
Takahiro 已提交
2578
		if ( ( renderTarget && renderTarget.isWebGLRenderTarget ) === false ) {
2579

2580
			console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
G
gero3 已提交
2581
			return;
2582

G
gero3 已提交
2583
		}
2584

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

M
Mr.doob 已提交
2587
		if ( framebuffer ) {
2588

G
gero3 已提交
2589
			var restore = false;
2590

M
Mr.doob 已提交
2591
			if ( framebuffer !== _currentFramebuffer ) {
2592

M
Mr.doob 已提交
2593
				_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
2594

G
gero3 已提交
2595
				restore = true;
2596

G
gero3 已提交
2597
			}
2598

M
Mr.doob 已提交
2599
			try {
2600

M
Mr.doob 已提交
2601
				var texture = renderTarget.texture;
M
Mr.doob 已提交
2602 2603
				var textureFormat = texture.format;
				var textureType = texture.type;
2604

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

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

M
Mr.doob 已提交
2610
				}
2611

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

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

M
Mr.doob 已提交
2619
				}
2620

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

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

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

M
Mr.doob 已提交
2627
						_gl.readPixels( x, y, width, height, paramThreeToGL( textureFormat ), paramThreeToGL( textureType ), buffer );
2628 2629

					}
2630

M
Mr.doob 已提交
2631
				} else {
M
Mr.doob 已提交
2632

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

				}
M
Mr.doob 已提交
2636

M
Mr.doob 已提交
2637
			} finally {
M
Mr.doob 已提交
2638

M
Mr.doob 已提交
2639 2640 2641
				if ( restore ) {

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

M
Mr.doob 已提交
2643 2644 2645
				}

			}
M
Mr.doob 已提交
2646 2647 2648

		}

M
Mr.doob 已提交
2649 2650
	};

M
Mr.doob 已提交
2651 2652
	// Map three.js constants to WebGL constants

M
Mr.doob 已提交
2653
	function paramThreeToGL( p ) {
M
Mr.doob 已提交
2654

2655 2656
		var extension;

R
Rich Harris 已提交
2657 2658 2659
		if ( p === RepeatWrapping ) return _gl.REPEAT;
		if ( p === ClampToEdgeWrapping ) return _gl.CLAMP_TO_EDGE;
		if ( p === MirroredRepeatWrapping ) return _gl.MIRRORED_REPEAT;
M
Mr.doob 已提交
2660

R
Rich Harris 已提交
2661 2662 2663
		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 已提交
2664

R
Rich Harris 已提交
2665 2666 2667
		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 已提交
2668

R
Rich Harris 已提交
2669 2670 2671 2672
		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 已提交
2673

R
Rich Harris 已提交
2674 2675 2676 2677 2678 2679
		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 已提交
2680

2681
		if ( p === HalfFloatType ) {
2682

2683
			extension = extensions.get( 'OES_texture_half_float' );
2684

2685
			if ( extension !== null ) return extension.HALF_FLOAT_OES;
2686 2687 2688

		}

R
Rich Harris 已提交
2689 2690 2691 2692 2693 2694
		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;
2695
		if ( p === DepthStencilFormat ) return _gl.DEPTH_STENCIL;
M
Mr.doob 已提交
2696

R
Rich Harris 已提交
2697 2698 2699
		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 已提交
2700

R
Rich Harris 已提交
2701 2702 2703 2704 2705 2706 2707 2708
		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 已提交
2709

R
Rich Harris 已提交
2710 2711 2712
		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 已提交
2713

2714 2715
		if ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format ||
			p === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) {
M
Mr.doob 已提交
2716

2717
			extension = extensions.get( 'WEBGL_compressed_texture_s3tc' );
2718

2719 2720 2721 2722 2723 2724 2725 2726
			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 已提交
2727 2728 2729

		}

2730 2731
		if ( p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format ||
			 p === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format ) {
2732

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

2735 2736 2737 2738 2739 2740 2741 2742
			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 已提交
2743 2744 2745

		}

2746
		if ( p === RGB_ETC1_Format ) {
2747

2748
			extension = extensions.get( 'WEBGL_compressed_texture_etc1' );
2749

2750
			if ( extension !== null ) return extension.COMPRESSED_RGB_ETC1_WEBGL;
2751 2752 2753

		}

2754 2755 2756
		if ( p === MinEquation || p === MaxEquation ) {

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

2758
			if ( extension !== null ) {
2759

2760 2761 2762 2763
				if ( p === MinEquation ) return extension.MIN_EXT;
				if ( p === MaxEquation ) return extension.MAX_EXT;

			}
2764 2765 2766

		}

2767
		if ( p === UnsignedInt248Type ) {
2768

2769
			extension = extensions.get( 'WEBGL_depth_texture' );
2770

2771
			if ( extension !== null ) return extension.UNSIGNED_INT_24_8_WEBGL;
2772 2773 2774

		}

M
Mr.doob 已提交
2775 2776
		return 0;

M
Mr.doob 已提交
2777
	}
M
Mr.doob 已提交
2778

M
Mr.doob 已提交
2779
}
R
Rich Harris 已提交
2780 2781

export { WebGLRenderer };