浏览代码

Merge branch 'dev' of git://github.com/mrdoob/three.js into dev_pmrem_refactor

WestLangley 5 年之前
父节点
当前提交
b8c2c5bcfe
共有 70 个文件被更改,包括 1177 次插入848 次删除
  1. 50 35
      build/three.js
  2. 446 446
      build/three.min.js
  3. 50 34
      build/three.module.js
  4. 1 1
      docs/api/en/materials/Material.html
  5. 1 1
      docs/api/zh/materials/Material.html
  6. 170 34
      examples/js/loaders/GLTFLoader.js
  7. 10 3
      examples/js/objects/Reflector.js
  8. 12 3
      examples/js/objects/Refractor.js
  9. 5 21
      examples/js/objects/Sky.js
  10. 19 1
      examples/js/objects/Water.js
  11. 172 34
      examples/jsm/loaders/GLTFLoader.js
  12. 20 20
      examples/jsm/nodes/effects/BlurNode.js
  13. 10 3
      examples/jsm/objects/Reflector.js
  14. 12 3
      examples/jsm/objects/Refractor.js
  15. 5 21
      examples/jsm/objects/Sky.js
  16. 21 1
      examples/jsm/objects/Water.js
  17. 二进制
      examples/screenshots/webgl_loader_gltf.jpg
  18. 二进制
      examples/screenshots/webgl_loader_gltf_extensions.jpg
  19. 二进制
      examples/screenshots/webgl_materials_car.jpg
  20. 二进制
      examples/screenshots/webgl_materials_envmaps_exr.jpg
  21. 二进制
      examples/screenshots/webgl_materials_envmaps_hdr.jpg
  22. 二进制
      examples/screenshots/webgl_materials_envmaps_hdr_nodes.jpg
  23. 二进制
      examples/screenshots/webgl_materials_envmaps_pmrem_nodes.jpg
  24. 二进制
      examples/screenshots/webgl_materials_physical_clearcoat.jpg
  25. 二进制
      examples/screenshots/webgl_materials_physical_transparency.jpg
  26. 二进制
      examples/screenshots/webgl_materials_variations_physical.jpg
  27. 二进制
      examples/screenshots/webgl_materials_variations_standard.jpg
  28. 二进制
      examples/screenshots/webgl_pmrem_test.jpg
  29. 二进制
      examples/screenshots/webgl_shaders_ocean.jpg
  30. 二进制
      examples/screenshots/webgl_shaders_sky.jpg
  31. 二进制
      examples/screenshots/webgl_shaders_tonemapping.jpg
  32. 二进制
      examples/screenshots/webgl_tonemapping.jpg
  33. 1 3
      examples/webgl2_buffergeometry_attributes_integer.html
  34. 1 4
      examples/webgl2_materials_texture2darray.html
  35. 1 3
      examples/webgl2_materials_texture3d.html
  36. 1 4
      examples/webgl2_multisampled_renderbuffers.html
  37. 1 4
      examples/webgl2_sandbox.html
  38. 1 1
      examples/webgl_buffergeometry_instancing.html
  39. 1 1
      examples/webgl_buffergeometry_instancing_billboards.html
  40. 1 1
      examples/webgl_buffergeometry_instancing_interleaved.html
  41. 1 1
      examples/webgl_depth_texture.html
  42. 2 2
      examples/webgl_lights_rectarealight.html
  43. 0 1
      examples/webgl_loader_gltf.html
  44. 6 8
      examples/webgl_loader_gltf_extensions.html
  45. 6 5
      examples/webgl_materials_car.html
  46. 1 1
      examples/webgl_materials_envmaps_exr.html
  47. 1 1
      examples/webgl_materials_envmaps_hdr.html
  48. 1 1
      examples/webgl_materials_envmaps_hdr_nodes.html
  49. 1 1
      examples/webgl_materials_envmaps_pmrem_nodes.html
  50. 1 1
      examples/webgl_materials_physical_clearcoat.html
  51. 0 1
      examples/webgl_materials_variations_physical.html
  52. 0 1
      examples/webgl_materials_variations_standard.html
  53. 4 4
      examples/webgl_pmrem_test.html
  54. 0 12
      examples/webgl_postprocessing_ssao.html
  55. 20 49
      examples/webgl_shaders_ocean.html
  56. 12 22
      examples/webgl_shaders_sky.html
  57. 3 2
      examples/webgl_shaders_tonemapping.html
  58. 1 1
      examples/webgl_tonemapping.html
  59. 22 21
      package-lock.json
  60. 2 2
      package.json
  61. 19 6
      src/core/BufferAttribute.js
  62. 1 3
      src/core/BufferGeometry.js
  63. 10 2
      src/extras/ImageUtils.js
  64. 6 6
      src/extras/PMREMGenerator.js
  65. 1 1
      src/renderers/WebGLCubeRenderTarget.js
  66. 2 2
      src/renderers/WebGLRenderer.js
  67. 34 3
      src/renderers/shaders/ShaderChunk/tonemapping_pars_fragment.glsl.js
  68. 2 2
      src/renderers/webgl/WebGLBackground.js
  69. 4 2
      src/renderers/webgl/WebGLProgram.js
  70. 2 2
      src/renderers/webgl/WebGLPrograms.js

+ 50 - 35
build/three.js

@@ -151,9 +151,8 @@
 	var NoToneMapping = 0;
 	var LinearToneMapping = 1;
 	var ReinhardToneMapping = 2;
-	var Uncharted2ToneMapping = 3;
-	var CineonToneMapping = 4;
-	var ACESFilmicToneMapping = 5;
+	var CineonToneMapping = 3;
+	var ACESFilmicToneMapping = 4;
 
 	var UVMapping = 300;
 	var CubeReflectionMapping = 301;
@@ -1454,13 +1453,21 @@
 
 		getDataURL: function ( image ) {
 
-			var canvas;
+			if ( /^data:/i.test( image.src ) ) {
+
+				return image.src;
+
+			}
 
 			if ( typeof HTMLCanvasElement == 'undefined' ) {
 
 				return image.src;
 
-			} else if ( image instanceof HTMLCanvasElement ) {
+			}
+
+			var canvas;
+
+			if ( image instanceof HTMLCanvasElement ) {
 
 				canvas = image;
 
@@ -9265,6 +9272,7 @@
 	 */
 
 	var _vector$3 = new Vector3();
+	var _vector2$1 = new Vector2();
 
 	function BufferAttribute( array, itemSize, normalized ) {
 
@@ -9455,15 +9463,27 @@
 
 		applyMatrix3: function ( m ) {
 
-			for ( var i = 0, l = this.count; i < l; i ++ ) {
+			if ( this.itemSize === 2 ) {
 
-				_vector$3.x = this.getX( i );
-				_vector$3.y = this.getY( i );
-				_vector$3.z = this.getZ( i );
+				for ( var i = 0, l = this.count; i < l; i ++ ) {
 
-				_vector$3.applyMatrix3( m );
+					_vector2$1.fromBufferAttribute( this, i );
+					_vector2$1.applyMatrix3( m );
 
-				this.setXYZ( i, _vector$3.x, _vector$3.y, _vector$3.z );
+					this.setXY( i, _vector2$1.x, _vector2$1.y );
+
+				}
+
+			} else if ( this.itemSize === 3 ) {
+
+				for ( var i$1 = 0, l$1 = this.count; i$1 < l$1; i$1 ++ ) {
+
+					_vector$3.fromBufferAttribute( this, i$1 );
+					_vector$3.applyMatrix3( m );
+
+					this.setXYZ( i$1, _vector$3.x, _vector$3.y, _vector$3.z );
+
+				}
 
 			}
 
@@ -10896,9 +10916,7 @@
 
 			for ( var i = 0, il = normals.count; i < il; i ++ ) {
 
-				_vector$4.x = normals.getX( i );
-				_vector$4.y = normals.getY( i );
-				_vector$4.z = normals.getZ( i );
+				_vector$4.fromBufferAttribute( normals, i );
 
 				_vector$4.normalize();
 
@@ -14084,7 +14102,7 @@
 
 		var material = new ShaderMaterial( {
 
-			type: 'CubemapFromEquirect',
+			name: 'CubemapFromEquirect',
 
 			uniforms: cloneUniforms( shader.uniforms ),
 			vertexShader: shader.vertexShader,
@@ -15013,7 +15031,7 @@
 
 	var tonemapping_fragment = "#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif";
 
-	var tonemapping_pars_fragment = "#ifndef saturate\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\n#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )\nvec3 Uncharted2ToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( 1.0 ) ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( ( color * ( 2.51 * color + 0.03 ) ) / ( color * ( 2.43 * color + 0.59 ) + 0.14 ) );\n}";
+	var tonemapping_pars_fragment = "#ifndef saturate\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 RRTAndODTFit( vec3 v ) {\n    vec3 a = v * ( v + 0.0245786 ) - 0.000090537;\n    vec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081;\n    return a / b;\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n    const mat3 ACESInputMat = mat3(\n        vec3( 0.59719, 0.07600, 0.02840 ),        vec3( 0.35458, 0.90834, 0.13383 ),\n        vec3( 0.04823, 0.01566, 0.83777 )\n    );\n    const mat3 ACESOutputMat = mat3(\n        vec3(  1.60475, -0.10208, -0.00327 ),        vec3( -0.53108,  1.10813, -0.07276 ),\n        vec3( -0.07367, -0.00605,  1.07602 )\n    );\n    color *= toneMappingExposure;\n    color = ACESInputMat * color;\n    color = RRTAndODTFit( color );\n    color = ACESOutputMat * color;\n    return saturate( color );\n}";
 
 	var uv_pars_fragment = "#if ( defined( USE_UV ) && ! defined( UVS_VERTEX_ONLY ) )\n\tvarying vec2 vUv;\n#endif";
 
@@ -15588,7 +15606,7 @@
 					boxMesh = new Mesh(
 						new BoxBufferGeometry( 1, 1, 1 ),
 						new ShaderMaterial( {
-							type: 'BackgroundCubeMaterial',
+							name: 'BackgroundCubeMaterial',
 							uniforms: cloneUniforms( ShaderLib.cube.uniforms ),
 							vertexShader: ShaderLib.cube.vertexShader,
 							fragmentShader: ShaderLib.cube.fragmentShader,
@@ -15650,7 +15668,7 @@
 					planeMesh = new Mesh(
 						new PlaneBufferGeometry( 2, 2 ),
 						new ShaderMaterial( {
-							type: 'BackgroundMaterial',
+							name: 'BackgroundMaterial',
 							uniforms: cloneUniforms( ShaderLib.background.uniforms ),
 							vertexShader: ShaderLib.background.vertexShader,
 							fragmentShader: ShaderLib.background.fragmentShader,
@@ -17729,7 +17747,8 @@
 			case LogLuvEncoding:
 				return [ 'LogLuv', '( value )' ];
 			default:
-				throw new Error( 'unsupported encoding: ' + encoding );
+				console.warn( 'THREE.WebGLProgram: Unsupported encoding:', encoding );
+				return [ 'Linear', '( value )' ];
 
 		}
 
@@ -17779,10 +17798,6 @@
 				toneMappingName = 'Reinhard';
 				break;
 
-			case Uncharted2ToneMapping:
-				toneMappingName = 'Uncharted2';
-				break;
-
 			case CineonToneMapping:
 				toneMappingName = 'OptimizedCineon';
 				break;
@@ -17792,7 +17807,8 @@
 				break;
 
 			default:
-				throw new Error( 'unsupported toneMapping: ' + toneMapping );
+				console.warn( 'THREE.WebGLProgram: Unsupported toneMapping:', toneMapping );
+				toneMappingName = 'Linear';
 
 		}
 
@@ -18600,7 +18616,7 @@
 				var shader = ShaderLib[ shaderID ];
 
 				shaderobject = {
-					name: material.type,
+					name: material.name || material.type,
 					uniforms: UniformsUtils.clone( shader.uniforms ),
 					vertexShader: shader.vertexShader,
 					fragmentShader: shader.fragmentShader
@@ -18609,7 +18625,7 @@
 			} else {
 
 				shaderobject = {
-					name: material.type,
+					name: material.name || material.type,
 					uniforms: material.uniforms,
 					vertexShader: material.vertexShader,
 					fragmentShader: material.fragmentShader
@@ -24367,11 +24383,11 @@
 			_canvas.addEventListener( 'webglcontextlost', onContextLost, false );
 			_canvas.addEventListener( 'webglcontextrestored', onContextRestore, false );
 
-			_gl = _context || _canvas.getContext( 'webgl', contextAttributes ) || _canvas.getContext( 'experimental-webgl', contextAttributes );
+			_gl = _context || _canvas.getContext( 'webgl2', contextAttributes ) || _canvas.getContext( 'webgl', contextAttributes ) || _canvas.getContext( 'experimental-webgl', contextAttributes );
 
 			if ( _gl === null ) {
 
-				if ( _canvas.getContext( 'webgl' ) !== null ) {
+				if ( _canvas.getContext( 'webgl2' ) || _canvas.getContext( 'webgl' ) || _canvas.getContext( 'experimental-webgl' ) ) {
 
 					throw new Error( 'Error creating WebGL context with your selected attributes.' );
 
@@ -48765,6 +48781,8 @@
 		var poleAxis = new Vector3( 0, 1, 0 );
 		var shaderMaterial = new RawShaderMaterial( {
 
+			name: 'SphericalGaussianBlur',
+
 			defines: { 'n': maxSamples },
 
 			uniforms: {
@@ -48789,8 +48807,6 @@
 
 		} );
 
-		shaderMaterial.type = 'SphericalGaussianBlur';
-
 		return shaderMaterial;
 
 	}
@@ -48800,6 +48816,8 @@
 		var texelSize = new Vector2( 1, 1 );
 		var shaderMaterial = new RawShaderMaterial( {
 
+			name: 'EquirectangularToCubeUV',
+
 			uniforms: {
 				'envMap': { value: null },
 				'texelSize': { value: texelSize },
@@ -48817,8 +48835,6 @@
 
 		} );
 
-		shaderMaterial.type = 'EquirectangularToCubeUV';
-
 		return shaderMaterial;
 
 	}
@@ -48827,6 +48843,8 @@
 
 		var shaderMaterial = new RawShaderMaterial( {
 
+			name: 'CubemapToCubeUV',
+
 			uniforms: {
 				'envMap': { value: null },
 				'inputEncoding': { value: ENCODINGS[ LinearEncoding ] },
@@ -48843,8 +48861,6 @@
 
 		} );
 
-		shaderMaterial.type = 'CubemapToCubeUV';
-
 		return shaderMaterial;
 
 	}
@@ -51424,7 +51440,6 @@
 	exports.Uint8BufferAttribute = Uint8BufferAttribute;
 	exports.Uint8ClampedAttribute = Uint8ClampedAttribute;
 	exports.Uint8ClampedBufferAttribute = Uint8ClampedBufferAttribute;
-	exports.Uncharted2ToneMapping = Uncharted2ToneMapping;
 	exports.Uniform = Uniform;
 	exports.UniformsLib = UniformsLib;
 	exports.UniformsUtils = UniformsUtils;

文件差异内容过多而无法显示
+ 446 - 446
build/three.min.js


文件差异内容过多而无法显示
+ 50 - 34
build/three.module.js


+ 1 - 1
docs/api/en/materials/Material.html

@@ -211,7 +211,7 @@
 		<h3>[property:Boolean premultipliedAlpha]</h3>
 		<p>
 		Whether to premultiply the alpha (transparency) value.
-		See [Example:webgl_materials_transparency WebGL / Materials / Transparency] for an example of the difference.
+		See [Example:webgl_materials_physical_transparency WebGL / Materials / Physical / Transparency] for an example of the difference.
 		Default is *false*.
 		</p>
 

+ 1 - 1
docs/api/zh/materials/Material.html

@@ -182,7 +182,7 @@ Which stencil operation to perform when the comparison function returns true and
 </p>
 
 <h3>[property:Boolean premultipliedAlpha]</h3>
-<p> 是否预乘alpha(透明度)值。有关差异的示例,请参阅[Example:webgl_materials_transparency WebGL / Materials / Transparency]。
+<p> 是否预乘alpha(透明度)值。有关差异的示例,请参阅[Example:webgl_materials_physical_transparency WebGL / Materials / Physical / Transparency]。
 	默认值为*false*。
 </p>
 

+ 170 - 34
examples/js/loaders/GLTFLoader.js

@@ -16,6 +16,9 @@ THREE.GLTFLoader = ( function () {
 		this.dracoLoader = null;
 		this.ddsLoader = null;
 
+		this.pluginCallbacks = [];
+		this.register( function ( parser ) { return new GLTFMaterialsClearcoatExtension( parser ); } );
+
 	}
 
 	GLTFLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), {
@@ -112,10 +115,35 @@ THREE.GLTFLoader = ( function () {
 
 		},
 
+		register: function ( callback ) {
+
+			if ( this.pluginCallbacks.indexOf( callback ) === -1 ) {
+
+				this.pluginCallbacks.push( callback );
+
+			}
+
+			return this;
+
+		},
+
+		unregister: function ( callback ) {
+
+			if ( this.pluginCallbacks.indexOf( callback ) !== -1 ) {
+
+				this.pluginCallbacks.splice( this.pluginCallbacks.indexOf( callback ), 1 );
+
+			}
+
+			return this;
+
+		},
+
 		parse: function ( data, path, onLoad, onError ) {
 
 			var content;
 			var extensions = {};
+			var plugins = {};
 
 			if ( typeof data === 'string' ) {
 
@@ -157,6 +185,29 @@ THREE.GLTFLoader = ( function () {
 
 			}
 
+			var parser = new GLTFParser( json, {
+
+				path: path || this.resourcePath || '',
+				crossOrigin: this.crossOrigin,
+				manager: this.manager
+
+			} );
+
+			parser.fileLoader.setRequestHeader( this.requestHeader );
+
+			for ( var i = 0; i < this.pluginCallbacks.length; i ++ ) {
+
+				var plugin = this.pluginCallbacks[ i ]( parser );
+				plugins[ plugin.name ] = plugin;
+
+				// Workaround to avoid determining as unknown extension
+				// in addUnknownExtensionsToUserData().
+				// Remove this workaround if we move all the existing
+				// extension handlers to plugin system
+				extensions[ plugin.name ] = true;
+
+			}
+
 			if ( json.extensionsUsed ) {
 
 				for ( var i = 0; i < json.extensionsUsed.length; ++ i ) {
@@ -170,10 +221,6 @@ THREE.GLTFLoader = ( function () {
 							extensions[ extensionName ] = new GLTFLightsExtension( json );
 							break;
 
-						case EXTENSIONS.KHR_MATERIALS_CLEARCOAT:
-							extensions[ extensionName ] = new GLTFMaterialsClearcoatExtension();
-							break;
-
 						case EXTENSIONS.KHR_MATERIALS_UNLIT:
 							extensions[ extensionName ] = new GLTFMaterialsUnlitExtension();
 							break;
@@ -200,7 +247,7 @@ THREE.GLTFLoader = ( function () {
 
 						default:
 
-							if ( extensionsRequired.indexOf( extensionName ) >= 0 ) {
+							if ( extensionsRequired.indexOf( extensionName ) >= 0 && plugins[ extensionName ] === undefined ) {
 
 								console.warn( 'THREE.GLTFLoader: Unknown extension "' + extensionName + '".' );
 
@@ -212,15 +259,8 @@ THREE.GLTFLoader = ( function () {
 
 			}
 
-			var parser = new GLTFParser( json, extensions, {
-
-				path: path || this.resourcePath || '',
-				crossOrigin: this.crossOrigin,
-				manager: this.manager
-
-			} );
-
-			parser.fileLoader.setRequestHeader( this.requestHeader );
+			parser.setExtensions( extensions );
+			parser.setPlugins( plugins );
 			parser.parse( onLoad, onError );
 
 		}
@@ -421,19 +461,29 @@ THREE.GLTFLoader = ( function () {
 	 *
 	 * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_clearcoat
 	 */
-	function GLTFMaterialsClearcoatExtension() {
+	function GLTFMaterialsClearcoatExtension( parser ) {
 
+		this.parser = parser;
 		this.name = EXTENSIONS.KHR_MATERIALS_CLEARCOAT;
 
 	}
 
-	GLTFMaterialsClearcoatExtension.prototype.getMaterialType = function () {
+	GLTFMaterialsClearcoatExtension.prototype.getMaterialType = function ( materialIndex ) {
 
 		return THREE.MeshPhysicalMaterial;
 
 	};
 
-	GLTFMaterialsClearcoatExtension.prototype.extendParams = function ( materialParams, materialDef, parser ) {
+	GLTFMaterialsClearcoatExtension.prototype.extendMaterialParams = function ( materialIndex, materialParams ) {
+
+		var parser = this.parser;
+		var materialDef = parser.json.materials[ materialIndex ];
+
+		if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {
+
+			return Promise.resolve();
+
+		}
 
 		var pending = [];
 
@@ -1398,10 +1448,11 @@ THREE.GLTFLoader = ( function () {
 
 	/* GLTF PARSER */
 
-	function GLTFParser( json, extensions, options ) {
+	function GLTFParser( json, options ) {
 
 		this.json = json || {};
-		this.extensions = extensions || {};
+		this.extensions = {};
+		this.plugins = {};
 		this.options = options || {};
 
 		// loader object cache
@@ -1413,7 +1464,15 @@ THREE.GLTFLoader = ( function () {
 		// BufferGeometry caching
 		this.primitiveCache = {};
 
-		this.textureLoader = new THREE.TextureLoader( this.options.manager );
+		this.useImageBitmap = typeof createImageBitmap !== 'undefined';
+
+		// Use an ImageBitmapLoader if imageBitmaps are supported. Moves much of the
+		// expensive work of uploading a texture to the GPU off the main thread.
+		if ( this.useImageBitmap ) {
+			this.textureLoader = new THREE.ImageBitmapLoader( this.options.manager );
+		} else {
+			this.textureLoader = new THREE.TextureLoader( this.options.manager );
+		}
 		this.textureLoader.setCrossOrigin( this.options.crossOrigin );
 
 		this.fileLoader = new THREE.FileLoader( this.options.manager );
@@ -1427,6 +1486,18 @@ THREE.GLTFLoader = ( function () {
 
 	}
 
+	GLTFParser.prototype.setExtensions = function ( extensions ) {
+
+		this.extensions = extensions;
+
+	};
+
+	GLTFParser.prototype.setPlugins = function ( plugins ) {
+
+		this.plugins = plugins;
+
+	};
+
 	GLTFParser.prototype.parse = function ( onLoad, onError ) {
 
 		var parser = this;
@@ -1530,6 +1601,38 @@ THREE.GLTFLoader = ( function () {
 
 	};
 
+	GLTFParser.prototype._invokeOne = function ( func ) {
+
+		var extensions = Object.values( this.plugins );
+		extensions.push( this );
+
+		for ( var i = 0; i < extensions.length; i ++ ) {
+
+			var result = func( extensions[ i ] );
+
+			if ( result ) return result;
+
+		}
+
+	};
+
+	GLTFParser.prototype._invokeAll = function ( func ) {
+
+		var extensions = Object.values( this.plugins );
+		extensions.unshift( this );
+
+		var pending = [];
+
+		for ( var i = 0; i < extensions.length; i ++ ) {
+
+			pending.push( func( extensions[ i ] ) );
+
+		}
+
+		return Promise.all( pending );
+
+	};
+
 	/**
 	 * Requests the specified dependency asynchronously, with caching.
 	 * @param {string} type
@@ -1554,7 +1657,11 @@ THREE.GLTFLoader = ( function () {
 					break;
 
 				case 'mesh':
-					dependency = this.loadMesh( index );
+					dependency = this._invokeOne( function ( ext ) {
+
+						return ext.loadMesh && ext.loadMesh( index );
+
+					} );
 					break;
 
 				case 'accessor':
@@ -1562,7 +1669,11 @@ THREE.GLTFLoader = ( function () {
 					break;
 
 				case 'bufferView':
-					dependency = this.loadBufferView( index );
+					dependency = this._invokeOne( function ( ext ) {
+
+						return ext.loadBufferView && ext.loadBufferView( index );
+
+					} );
 					break;
 
 				case 'buffer':
@@ -1570,7 +1681,11 @@ THREE.GLTFLoader = ( function () {
 					break;
 
 				case 'material':
-					dependency = this.loadMaterial( index );
+					dependency = this._invokeOne( function ( ext ) {
+
+						return ext.loadMaterial && ext.loadMaterial( index );
+
+					} );
 					break;
 
 				case 'texture':
@@ -1832,6 +1947,7 @@ THREE.GLTFLoader = ( function () {
 		var parser = this;
 		var json = this.json;
 		var options = this.options;
+		var useImageBitmap = this.useImageBitmap;
 		var textureLoader = this.textureLoader;
 
 		var URL = self.URL || self.webkitURL;
@@ -1886,7 +2002,19 @@ THREE.GLTFLoader = ( function () {
 
 			return new Promise( function ( resolve, reject ) {
 
-				loader.load( resolveURL( sourceURI, options.path ), resolve, undefined, reject );
+				var onLoad = resolve;
+
+				if ( useImageBitmap ) {
+
+					onLoad = function ( imageBitmap ) {
+
+						resolve( new THREE.CanvasTexture( imageBitmap ) );
+
+					};
+
+				}
+
+				loader.load( resolveURL( sourceURI, options.path ), onLoad, undefined, reject );
 
 			} );
 
@@ -2108,6 +2236,12 @@ THREE.GLTFLoader = ( function () {
 
 	};
 
+	GLTFParser.prototype.getMaterialType = function ( materialIndex ) {
+
+		return THREE.MeshStandardMaterial;
+
+	};
+
 	/**
 	 * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#materials
 	 * @param {number} materialIndex
@@ -2143,8 +2277,6 @@ THREE.GLTFLoader = ( function () {
 			// Specification:
 			// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#metallic-roughness-material
 
-			materialType = THREE.MeshStandardMaterial;
-
 			var metallicRoughness = materialDef.pbrMetallicRoughness || {};
 
 			materialParams.color = new THREE.Color( 1.0, 1.0, 1.0 );
@@ -2175,6 +2307,18 @@ THREE.GLTFLoader = ( function () {
 
 			}
 
+			materialType = this._invokeOne( function ( ext ) {
+
+				return ext.getMaterialType && ext.getMaterialType( materialIndex );
+
+			} );
+
+			pending.push( this._invokeAll( function ( ext ) {
+
+				return ext.extendMaterialParams && ext.extendMaterialParams( materialIndex, materialParams );
+
+			} ) );
+
 		}
 
 		if ( materialDef.doubleSided === true ) {
@@ -2242,14 +2386,6 @@ THREE.GLTFLoader = ( function () {
 
 		}
 
-		if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_CLEARCOAT ] ) {
-
-			var clearcoatExtension = extensions[ EXTENSIONS.KHR_MATERIALS_CLEARCOAT ];
-			materialType = clearcoatExtension.getMaterialType();
-			pending.push( clearcoatExtension.extendParams( materialParams, { extensions: materialExtensions }, parser ) );
-
-		}
-
 		return Promise.all( pending ).then( function () {
 
 			var material;

+ 10 - 3
examples/js/objects/Reflector.js

@@ -18,7 +18,6 @@ THREE.Reflector = function ( geometry, options ) {
 	var textureHeight = options.textureHeight || 512;
 	var clipBias = options.clipBias || 0;
 	var shader = options.shader || THREE.Reflector.ReflectorShader;
-	var encoding = options.encoding !== undefined ? options.encoding : THREE.LinearEncoding;
 
 	//
 
@@ -41,8 +40,7 @@ THREE.Reflector = function ( geometry, options ) {
 		minFilter: THREE.LinearFilter,
 		magFilter: THREE.LinearFilter,
 		format: THREE.RGBFormat,
-		stencilBuffer: false,
-		encoding: encoding
+		stencilBuffer: false
 	};
 
 	var renderTarget = new THREE.WebGLRenderTarget( textureWidth, textureHeight, parameters );
@@ -141,6 +139,15 @@ THREE.Reflector = function ( geometry, options ) {
 
 		// Render
 
+		if ( renderer.outputEncoding !== THREE.LinearEncoding ) {
+
+			console.warn( 'THREE.Reflector: WebGLRenderer must use LinearEncoding as outputEncoding.' );
+			scope.onBeforeRender = function () {};
+
+			return;
+
+		}
+
 		scope.visible = false;
 
 		var currentRenderTarget = renderer.getRenderTarget();

+ 12 - 3
examples/js/objects/Refractor.js

@@ -19,7 +19,6 @@ THREE.Refractor = function ( geometry, options ) {
 	var textureHeight = options.textureHeight || 512;
 	var clipBias = options.clipBias || 0;
 	var shader = options.shader || THREE.Refractor.RefractorShader;
-	var encoding = options.encoding !== undefined ? options.encoding : THREE.LinearEncoding;
 
 	//
 
@@ -38,8 +37,7 @@ THREE.Refractor = function ( geometry, options ) {
 		minFilter: THREE.LinearFilter,
 		magFilter: THREE.LinearFilter,
 		format: THREE.RGBFormat,
-		stencilBuffer: false,
-		encoding: encoding
+		stencilBuffer: false
 	};
 
 	var renderTarget = new THREE.WebGLRenderTarget( textureWidth, textureHeight, parameters );
@@ -224,6 +222,17 @@ THREE.Refractor = function ( geometry, options ) {
 
 	this.onBeforeRender = function ( renderer, scene, camera ) {
 
+		// Render
+
+		if ( renderer.outputEncoding !== THREE.LinearEncoding ) {
+
+			console.warn( 'THREE.Refractor: WebGLRenderer must use LinearEncoding as outputEncoding.' );
+			scope.onBeforeRender = function () {};
+
+			return;
+
+		}
+
 		// ensure refractors are rendered only once per frame
 
 		if ( camera.userData.refractor === true ) return;

+ 5 - 21
examples/js/objects/Sky.js

@@ -20,6 +20,7 @@ THREE.Sky = function () {
 	var shader = THREE.Sky.SkyShader;
 
 	var material = new THREE.ShaderMaterial( {
+		name: 'SkyShader',
 		fragmentShader: shader.fragmentShader,
 		vertexShader: shader.vertexShader,
 		uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
@@ -36,7 +37,6 @@ THREE.Sky.prototype = Object.create( THREE.Mesh.prototype );
 THREE.Sky.SkyShader = {
 
 	uniforms: {
-		"luminance": { value: 1 },
 		"turbidity": { value: 2 },
 		"rayleigh": { value: 1 },
 		"mieCoefficient": { value: 0.005 },
@@ -126,7 +126,6 @@ THREE.Sky.SkyShader = {
 		'varying vec3 vBetaM;',
 		'varying float vSunE;',
 
-		'uniform float luminance;',
 		'uniform float mieDirectionalG;',
 		'uniform vec3 up;',
 
@@ -159,21 +158,6 @@ THREE.Sky.SkyShader = {
 		'	return ONE_OVER_FOURPI * ( ( 1.0 - g2 ) * inverse );',
 		'}',
 
-		// Filmic ToneMapping http://filmicgames.com/archives/75
-		'const float A = 0.15;',
-		'const float B = 0.50;',
-		'const float C = 0.10;',
-		'const float D = 0.20;',
-		'const float E = 0.02;',
-		'const float F = 0.30;',
-
-		'const float whiteScale = 1.0748724675633854;', // 1.0 / Uncharted2Tonemap(1000.0)
-
-		'vec3 Uncharted2Tonemap( vec3 x ) {',
-		'	return ( ( x * ( A * x + C * B ) + D * E ) / ( x * ( A * x + B ) + D * F ) ) - E / F;',
-		'}',
-
-
 		'void main() {',
 
 		'	vec3 direction = normalize( vWorldPosition - cameraPos );',
@@ -212,13 +196,13 @@ THREE.Sky.SkyShader = {
 
 		'	vec3 texColor = ( Lin + L0 ) * 0.04 + vec3( 0.0, 0.0003, 0.00075 );',
 
-		'	vec3 curr = Uncharted2Tonemap( ( log2( 2.0 / pow( luminance, 4.0 ) ) ) * texColor );',
-		'	vec3 color = curr * whiteScale;',
-
-		'	vec3 retColor = pow( color, vec3( 1.0 / ( 1.2 + ( 1.2 * vSunfade ) ) ) );',
+		'	vec3 retColor = pow( texColor, vec3( 1.0 / ( 1.2 + ( 1.2 * vSunfade ) ) ) );',
 
 		'	gl_FragColor = vec4( retColor, 1.0 );',
 
+		'#include <tonemapping_fragment>',
+		'#include <encodings_fragment>',
+
 		'}'
 	].join( '\n' )
 

+ 19 - 1
examples/js/objects/Water.js

@@ -283,7 +283,25 @@ THREE.Water = function ( geometry, options ) {
 
 		eye.setFromMatrixPosition( camera.matrixWorld );
 
-		//
+		// Render
+
+		if ( renderer.outputEncoding !== THREE.LinearEncoding ) {
+
+			console.warn( 'THREE.Water: WebGLRenderer must use LinearEncoding as outputEncoding.' );
+			scope.onBeforeRender = function () {};
+
+			return;
+
+		}
+
+		if ( renderer.toneMapping !== THREE.NoToneMapping ) {
+
+			console.warn( 'THREE.Water: WebGLRenderer must use NoToneMapping as toneMapping.' );
+			scope.onBeforeRender = function () {};
+
+			return;
+
+		}
 
 		var currentRenderTarget = renderer.getRenderTarget();
 

+ 172 - 34
examples/jsm/loaders/GLTFLoader.js

@@ -12,6 +12,7 @@ import {
 	Box3,
 	BufferAttribute,
 	BufferGeometry,
+	CanvasTexture,
 	ClampToEdgeWrapping,
 	Color,
 	DirectionalLight,
@@ -19,6 +20,7 @@ import {
 	FileLoader,
 	FrontSide,
 	Group,
+	ImageBitmapLoader,
 	InterleavedBuffer,
 	InterleavedBufferAttribute,
 	Interpolant,
@@ -79,6 +81,9 @@ var GLTFLoader = ( function () {
 		this.dracoLoader = null;
 		this.ddsLoader = null;
 
+		this.pluginCallbacks = [];
+		this.register( function ( parser ) { return new GLTFMaterialsClearcoatExtension( parser ); } );
+
 	}
 
 	GLTFLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
@@ -175,10 +180,35 @@ var GLTFLoader = ( function () {
 
 		},
 
+		register: function ( callback ) {
+
+			if ( this.pluginCallbacks.indexOf( callback ) === -1 ) {
+
+				this.pluginCallbacks.push( callback );
+
+			}
+
+			return this;
+
+		},
+
+		unregister: function ( callback ) {
+
+			if ( this.pluginCallbacks.indexOf( callback ) !== -1 ) {
+
+				this.pluginCallbacks.splice( this.pluginCallbacks.indexOf( callback ), 1 );
+
+			}
+
+			return this;
+
+		},
+
 		parse: function ( data, path, onLoad, onError ) {
 
 			var content;
 			var extensions = {};
+			var plugins = {};
 
 			if ( typeof data === 'string' ) {
 
@@ -220,6 +250,29 @@ var GLTFLoader = ( function () {
 
 			}
 
+			var parser = new GLTFParser( json, {
+
+				path: path || this.resourcePath || '',
+				crossOrigin: this.crossOrigin,
+				manager: this.manager
+
+			} );
+
+			parser.fileLoader.setRequestHeader( this.requestHeader );
+
+			for ( var i = 0; i < this.pluginCallbacks.length; i ++ ) {
+
+				var plugin = this.pluginCallbacks[ i ]( parser );
+				plugins[ plugin.name ] = plugin;
+
+				// Workaround to avoid determining as unknown extension
+				// in addUnknownExtensionsToUserData().
+				// Remove this workaround if we move all the existing
+				// extension handlers to plugin system
+				extensions[ plugin.name ] = true;
+
+			}
+
 			if ( json.extensionsUsed ) {
 
 				for ( var i = 0; i < json.extensionsUsed.length; ++ i ) {
@@ -233,10 +286,6 @@ var GLTFLoader = ( function () {
 							extensions[ extensionName ] = new GLTFLightsExtension( json );
 							break;
 
-						case EXTENSIONS.KHR_MATERIALS_CLEARCOAT:
-							extensions[ extensionName ] = new GLTFMaterialsClearcoatExtension();
-							break;
-
 						case EXTENSIONS.KHR_MATERIALS_UNLIT:
 							extensions[ extensionName ] = new GLTFMaterialsUnlitExtension();
 							break;
@@ -263,7 +312,7 @@ var GLTFLoader = ( function () {
 
 						default:
 
-							if ( extensionsRequired.indexOf( extensionName ) >= 0 ) {
+							if ( extensionsRequired.indexOf( extensionName ) >= 0 && plugins[ extensionName ] === undefined ) {
 
 								console.warn( 'THREE.GLTFLoader: Unknown extension "' + extensionName + '".' );
 
@@ -275,15 +324,8 @@ var GLTFLoader = ( function () {
 
 			}
 
-			var parser = new GLTFParser( json, extensions, {
-
-				path: path || this.resourcePath || '',
-				crossOrigin: this.crossOrigin,
-				manager: this.manager
-
-			} );
-
-			parser.fileLoader.setRequestHeader( this.requestHeader );
+			parser.setExtensions( extensions );
+			parser.setPlugins( plugins );
 			parser.parse( onLoad, onError );
 
 		}
@@ -484,19 +526,29 @@ var GLTFLoader = ( function () {
 	 *
 	 * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_clearcoat
 	 */
-	function GLTFMaterialsClearcoatExtension() {
+	function GLTFMaterialsClearcoatExtension( parser ) {
 
+		this.parser = parser;
 		this.name = EXTENSIONS.KHR_MATERIALS_CLEARCOAT;
 
 	}
 
-	GLTFMaterialsClearcoatExtension.prototype.getMaterialType = function () {
+	GLTFMaterialsClearcoatExtension.prototype.getMaterialType = function ( materialIndex ) {
 
 		return MeshPhysicalMaterial;
 
 	};
 
-	GLTFMaterialsClearcoatExtension.prototype.extendParams = function ( materialParams, materialDef, parser ) {
+	GLTFMaterialsClearcoatExtension.prototype.extendMaterialParams = function ( materialIndex, materialParams ) {
+
+		var parser = this.parser;
+		var materialDef = parser.json.materials[ materialIndex ];
+
+		if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {
+
+			return Promise.resolve();
+
+		}
 
 		var pending = [];
 
@@ -1461,10 +1513,11 @@ var GLTFLoader = ( function () {
 
 	/* GLTF PARSER */
 
-	function GLTFParser( json, extensions, options ) {
+	function GLTFParser( json, options ) {
 
 		this.json = json || {};
-		this.extensions = extensions || {};
+		this.extensions = {};
+		this.plugins = {};
 		this.options = options || {};
 
 		// loader object cache
@@ -1476,7 +1529,15 @@ var GLTFLoader = ( function () {
 		// BufferGeometry caching
 		this.primitiveCache = {};
 
-		this.textureLoader = new TextureLoader( this.options.manager );
+		this.useImageBitmap = typeof createImageBitmap !== 'undefined';
+
+		// Use an ImageBitmapLoader if imageBitmaps are supported. Moves much of the
+		// expensive work of uploading a texture to the GPU off the main thread.
+		if ( this.useImageBitmap ) {
+			this.textureLoader = new ImageBitmapLoader( this.options.manager );
+		} else {
+			this.textureLoader = new TextureLoader( this.options.manager );
+		}
 		this.textureLoader.setCrossOrigin( this.options.crossOrigin );
 
 		this.fileLoader = new FileLoader( this.options.manager );
@@ -1490,6 +1551,18 @@ var GLTFLoader = ( function () {
 
 	}
 
+	GLTFParser.prototype.setExtensions = function ( extensions ) {
+
+		this.extensions = extensions;
+
+	};
+
+	GLTFParser.prototype.setPlugins = function ( plugins ) {
+
+		this.plugins = plugins;
+
+	};
+
 	GLTFParser.prototype.parse = function ( onLoad, onError ) {
 
 		var parser = this;
@@ -1593,6 +1666,38 @@ var GLTFLoader = ( function () {
 
 	};
 
+	GLTFParser.prototype._invokeOne = function ( func ) {
+
+		var extensions = Object.values( this.plugins );
+		extensions.push( this );
+
+		for ( var i = 0; i < extensions.length; i ++ ) {
+
+			var result = func( extensions[ i ] );
+
+			if ( result ) return result;
+
+		}
+
+	};
+
+	GLTFParser.prototype._invokeAll = function ( func ) {
+
+		var extensions = Object.values( this.plugins );
+		extensions.unshift( this );
+
+		var pending = [];
+
+		for ( var i = 0; i < extensions.length; i ++ ) {
+
+			pending.push( func( extensions[ i ] ) );
+
+		}
+
+		return Promise.all( pending );
+
+	};
+
 	/**
 	 * Requests the specified dependency asynchronously, with caching.
 	 * @param {string} type
@@ -1617,7 +1722,11 @@ var GLTFLoader = ( function () {
 					break;
 
 				case 'mesh':
-					dependency = this.loadMesh( index );
+					dependency = this._invokeOne( function ( ext ) {
+
+						return ext.loadMesh && ext.loadMesh( index );
+
+					} );
 					break;
 
 				case 'accessor':
@@ -1625,7 +1734,11 @@ var GLTFLoader = ( function () {
 					break;
 
 				case 'bufferView':
-					dependency = this.loadBufferView( index );
+					dependency = this._invokeOne( function ( ext ) {
+
+						return ext.loadBufferView && ext.loadBufferView( index );
+
+					} );
 					break;
 
 				case 'buffer':
@@ -1633,7 +1746,11 @@ var GLTFLoader = ( function () {
 					break;
 
 				case 'material':
-					dependency = this.loadMaterial( index );
+					dependency = this._invokeOne( function ( ext ) {
+
+						return ext.loadMaterial && ext.loadMaterial( index );
+
+					} );
 					break;
 
 				case 'texture':
@@ -1895,6 +2012,7 @@ var GLTFLoader = ( function () {
 		var parser = this;
 		var json = this.json;
 		var options = this.options;
+		var useImageBitmap = this.useImageBitmap;
 		var textureLoader = this.textureLoader;
 
 		var URL = self.URL || self.webkitURL;
@@ -1949,7 +2067,19 @@ var GLTFLoader = ( function () {
 
 			return new Promise( function ( resolve, reject ) {
 
-				loader.load( resolveURL( sourceURI, options.path ), resolve, undefined, reject );
+				var onLoad = resolve;
+
+				if ( useImageBitmap ) {
+
+					onLoad = function ( imageBitmap ) {
+
+						resolve( new CanvasTexture( imageBitmap ) );
+
+					};
+
+				}
+
+				loader.load( resolveURL( sourceURI, options.path ), onLoad, undefined, reject );
 
 			} );
 
@@ -2171,6 +2301,12 @@ var GLTFLoader = ( function () {
 
 	};
 
+	GLTFParser.prototype.getMaterialType = function ( materialIndex ) {
+
+		return MeshStandardMaterial;
+
+	};
+
 	/**
 	 * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#materials
 	 * @param {number} materialIndex
@@ -2206,8 +2342,6 @@ var GLTFLoader = ( function () {
 			// Specification:
 			// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#metallic-roughness-material
 
-			materialType = MeshStandardMaterial;
-
 			var metallicRoughness = materialDef.pbrMetallicRoughness || {};
 
 			materialParams.color = new Color( 1.0, 1.0, 1.0 );
@@ -2238,6 +2372,18 @@ var GLTFLoader = ( function () {
 
 			}
 
+			materialType = this._invokeOne( function ( ext ) {
+
+				return ext.getMaterialType && ext.getMaterialType( materialIndex );
+
+			} );
+
+			pending.push( this._invokeAll( function ( ext ) {
+
+				return ext.extendMaterialParams && ext.extendMaterialParams( materialIndex, materialParams );
+
+			} ) );
+
 		}
 
 		if ( materialDef.doubleSided === true ) {
@@ -2305,14 +2451,6 @@ var GLTFLoader = ( function () {
 
 		}
 
-		if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_CLEARCOAT ] ) {
-
-			var clearcoatExtension = extensions[ EXTENSIONS.KHR_MATERIALS_CLEARCOAT ];
-			materialType = clearcoatExtension.getMaterialType();
-			pending.push( clearcoatExtension.extendParams( materialParams, { extensions: materialExtensions }, parser ) );
-
-		}
-
 		return Promise.all( pending ).then( function () {
 
 			var material;

+ 20 - 20
examples/jsm/nodes/effects/BlurNode.js

@@ -31,33 +31,33 @@ function BlurNode( value, uv, radius, size ) {
 BlurNode.Nodes = ( function () {
 
 	var blurX = new FunctionNode( [
-		"vec4 blurX( sampler2D texture, vec2 uv, float s ) {",
+		"vec4 blurX( sampler2D tex, vec2 uv, float s ) {",
 		"	vec4 sum = vec4( 0.0 );",
-		"	sum += texture2D( texture, vec2( uv.x - 4.0 * s, uv.y ) ) * 0.051;",
-		"	sum += texture2D( texture, vec2( uv.x - 3.0 * s, uv.y ) ) * 0.0918;",
-		"	sum += texture2D( texture, vec2( uv.x - 2.0 * s, uv.y ) ) * 0.12245;",
-		"	sum += texture2D( texture, vec2( uv.x - 1.0 * s, uv.y ) ) * 0.1531;",
-		"	sum += texture2D( texture, vec2( uv.x, uv.y ) ) * 0.1633;",
-		"	sum += texture2D( texture, vec2( uv.x + 1.0 * s, uv.y ) ) * 0.1531;",
-		"	sum += texture2D( texture, vec2( uv.x + 2.0 * s, uv.y ) ) * 0.12245;",
-		"	sum += texture2D( texture, vec2( uv.x + 3.0 * s, uv.y ) ) * 0.0918;",
-		"	sum += texture2D( texture, vec2( uv.x + 4.0 * s, uv.y ) ) * 0.051;",
+		"	sum += texture2D( tex, vec2( uv.x - 4.0 * s, uv.y ) ) * 0.051;",
+		"	sum += texture2D( tex, vec2( uv.x - 3.0 * s, uv.y ) ) * 0.0918;",
+		"	sum += texture2D( tex, vec2( uv.x - 2.0 * s, uv.y ) ) * 0.12245;",
+		"	sum += texture2D( tex, vec2( uv.x - 1.0 * s, uv.y ) ) * 0.1531;",
+		"	sum += texture2D( tex, vec2( uv.x, uv.y ) ) * 0.1633;",
+		"	sum += texture2D( tex, vec2( uv.x + 1.0 * s, uv.y ) ) * 0.1531;",
+		"	sum += texture2D( tex, vec2( uv.x + 2.0 * s, uv.y ) ) * 0.12245;",
+		"	sum += texture2D( tex, vec2( uv.x + 3.0 * s, uv.y ) ) * 0.0918;",
+		"	sum += texture2D( tex, vec2( uv.x + 4.0 * s, uv.y ) ) * 0.051;",
 		"	return sum * .667;",
 		"}"
 	].join( "\n" ) );
 
 	var blurY = new FunctionNode( [
-		"vec4 blurY( sampler2D texture, vec2 uv, float s ) {",
+		"vec4 blurY( sampler2D tex, vec2 uv, float s ) {",
 		"	vec4 sum = vec4( 0.0 );",
-		"	sum += texture2D( texture, vec2( uv.x, uv.y - 4.0 * s ) ) * 0.051;",
-		"	sum += texture2D( texture, vec2( uv.x, uv.y - 3.0 * s ) ) * 0.0918;",
-		"	sum += texture2D( texture, vec2( uv.x, uv.y - 2.0 * s ) ) * 0.12245;",
-		"	sum += texture2D( texture, vec2( uv.x, uv.y - 1.0 * s ) ) * 0.1531;",
-		"	sum += texture2D( texture, vec2( uv.x, uv.y ) ) * 0.1633;",
-		"	sum += texture2D( texture, vec2( uv.x, uv.y + 1.0 * s ) ) * 0.1531;",
-		"	sum += texture2D( texture, vec2( uv.x, uv.y + 2.0 * s ) ) * 0.12245;",
-		"	sum += texture2D( texture, vec2( uv.x, uv.y + 3.0 * s ) ) * 0.0918;",
-		"	sum += texture2D( texture, vec2( uv.x, uv.y + 4.0 * s ) ) * 0.051;",
+		"	sum += texture2D( tex, vec2( uv.x, uv.y - 4.0 * s ) ) * 0.051;",
+		"	sum += texture2D( tex, vec2( uv.x, uv.y - 3.0 * s ) ) * 0.0918;",
+		"	sum += texture2D( tex, vec2( uv.x, uv.y - 2.0 * s ) ) * 0.12245;",
+		"	sum += texture2D( tex, vec2( uv.x, uv.y - 1.0 * s ) ) * 0.1531;",
+		"	sum += texture2D( tex, vec2( uv.x, uv.y ) ) * 0.1633;",
+		"	sum += texture2D( tex, vec2( uv.x, uv.y + 1.0 * s ) ) * 0.1531;",
+		"	sum += texture2D( tex, vec2( uv.x, uv.y + 2.0 * s ) ) * 0.12245;",
+		"	sum += texture2D( tex, vec2( uv.x, uv.y + 3.0 * s ) ) * 0.0918;",
+		"	sum += texture2D( tex, vec2( uv.x, uv.y + 4.0 * s ) ) * 0.051;",
 		"	return sum * .667;",
 		"}"
 	].join( "\n" ) );

+ 10 - 3
examples/jsm/objects/Reflector.js

@@ -34,7 +34,6 @@ var Reflector = function ( geometry, options ) {
 	var textureHeight = options.textureHeight || 512;
 	var clipBias = options.clipBias || 0;
 	var shader = options.shader || Reflector.ReflectorShader;
-	var encoding = options.encoding !== undefined ? options.encoding : LinearEncoding;
 
 	//
 
@@ -57,8 +56,7 @@ var Reflector = function ( geometry, options ) {
 		minFilter: LinearFilter,
 		magFilter: LinearFilter,
 		format: RGBFormat,
-		stencilBuffer: false,
-		encoding: encoding
+		stencilBuffer: false
 	};
 
 	var renderTarget = new WebGLRenderTarget( textureWidth, textureHeight, parameters );
@@ -157,6 +155,15 @@ var Reflector = function ( geometry, options ) {
 
 		// Render
 
+		if ( renderer.outputEncoding !== LinearEncoding ) {
+
+			console.warn( 'THREE.Reflector: WebGLRenderer must use LinearEncoding as outputEncoding.' );
+			scope.onBeforeRender = function () {};
+
+			return;
+
+		}
+
 		scope.visible = false;
 
 		var currentRenderTarget = renderer.getRenderTarget();

+ 12 - 3
examples/jsm/objects/Refractor.js

@@ -36,7 +36,6 @@ var Refractor = function ( geometry, options ) {
 	var textureHeight = options.textureHeight || 512;
 	var clipBias = options.clipBias || 0;
 	var shader = options.shader || Refractor.RefractorShader;
-	var encoding = options.encoding !== undefined ? options.encoding : LinearEncoding;
 
 	//
 
@@ -55,8 +54,7 @@ var Refractor = function ( geometry, options ) {
 		minFilter: LinearFilter,
 		magFilter: LinearFilter,
 		format: RGBFormat,
-		stencilBuffer: false,
-		encoding: encoding
+		stencilBuffer: false
 	};
 
 	var renderTarget = new WebGLRenderTarget( textureWidth, textureHeight, parameters );
@@ -241,6 +239,17 @@ var Refractor = function ( geometry, options ) {
 
 	this.onBeforeRender = function ( renderer, scene, camera ) {
 
+		// Render
+
+		if ( renderer.outputEncoding !== LinearEncoding ) {
+
+			console.warn( 'THREE.Refractor: WebGLRenderer must use LinearEncoding as outputEncoding.' );
+			scope.onBeforeRender = function () {};
+
+			return;
+
+		}
+
 		// ensure refractors are rendered only once per frame
 
 		if ( camera.userData.refractor === true ) return;

+ 5 - 21
examples/jsm/objects/Sky.js

@@ -28,6 +28,7 @@ var Sky = function () {
 	var shader = Sky.SkyShader;
 
 	var material = new ShaderMaterial( {
+		name: 'SkyShader',
 		fragmentShader: shader.fragmentShader,
 		vertexShader: shader.vertexShader,
 		uniforms: UniformsUtils.clone( shader.uniforms ),
@@ -44,7 +45,6 @@ Sky.prototype = Object.create( Mesh.prototype );
 Sky.SkyShader = {
 
 	uniforms: {
-		"luminance": { value: 1 },
 		"turbidity": { value: 2 },
 		"rayleigh": { value: 1 },
 		"mieCoefficient": { value: 0.005 },
@@ -134,7 +134,6 @@ Sky.SkyShader = {
 		'varying vec3 vBetaM;',
 		'varying float vSunE;',
 
-		'uniform float luminance;',
 		'uniform float mieDirectionalG;',
 		'uniform vec3 up;',
 
@@ -167,21 +166,6 @@ Sky.SkyShader = {
 		'	return ONE_OVER_FOURPI * ( ( 1.0 - g2 ) * inverse );',
 		'}',
 
-		// Filmic ToneMapping http://filmicgames.com/archives/75
-		'const float A = 0.15;',
-		'const float B = 0.50;',
-		'const float C = 0.10;',
-		'const float D = 0.20;',
-		'const float E = 0.02;',
-		'const float F = 0.30;',
-
-		'const float whiteScale = 1.0748724675633854;', // 1.0 / Uncharted2Tonemap(1000.0)
-
-		'vec3 Uncharted2Tonemap( vec3 x ) {',
-		'	return ( ( x * ( A * x + C * B ) + D * E ) / ( x * ( A * x + B ) + D * F ) ) - E / F;',
-		'}',
-
-
 		'void main() {',
 
 		'	vec3 direction = normalize( vWorldPosition - cameraPos );',
@@ -220,13 +204,13 @@ Sky.SkyShader = {
 
 		'	vec3 texColor = ( Lin + L0 ) * 0.04 + vec3( 0.0, 0.0003, 0.00075 );',
 
-		'	vec3 curr = Uncharted2Tonemap( ( log2( 2.0 / pow( luminance, 4.0 ) ) ) * texColor );',
-		'	vec3 color = curr * whiteScale;',
-
-		'	vec3 retColor = pow( color, vec3( 1.0 / ( 1.2 + ( 1.2 * vSunfade ) ) ) );',
+		'	vec3 retColor = pow( texColor, vec3( 1.0 / ( 1.2 + ( 1.2 * vSunfade ) ) ) );',
 
 		'	gl_FragColor = vec4( retColor, 1.0 );',
 
+		'#include <tonemapping_fragment>',
+		'#include <encodings_fragment>',
+
 		'}'
 	].join( '\n' )
 

+ 21 - 1
examples/jsm/objects/Water.js

@@ -10,10 +10,12 @@
 import {
 	Color,
 	FrontSide,
+	LinearEncoding,
 	LinearFilter,
 	MathUtils,
 	Matrix4,
 	Mesh,
+	NoToneMapping,
 	PerspectiveCamera,
 	Plane,
 	RGBFormat,
@@ -300,7 +302,25 @@ var Water = function ( geometry, options ) {
 
 		eye.setFromMatrixPosition( camera.matrixWorld );
 
-		//
+		// Render
+
+		if ( renderer.outputEncoding !== LinearEncoding ) {
+
+			console.warn( 'THREE.Water: WebGLRenderer must use LinearEncoding as outputEncoding.' );
+			scope.onBeforeRender = function () {};
+
+			return;
+
+		}
+
+		if ( renderer.toneMapping !== NoToneMapping ) {
+
+			console.warn( 'THREE.Water: WebGLRenderer must use NoToneMapping as toneMapping.' );
+			scope.onBeforeRender = function () {};
+
+			return;
+
+		}
 
 		var currentRenderTarget = renderer.getRenderTarget();
 

二进制
examples/screenshots/webgl_loader_gltf.jpg


二进制
examples/screenshots/webgl_loader_gltf_extensions.jpg


二进制
examples/screenshots/webgl_materials_car.jpg


二进制
examples/screenshots/webgl_materials_envmaps_exr.jpg


二进制
examples/screenshots/webgl_materials_envmaps_hdr.jpg


二进制
examples/screenshots/webgl_materials_envmaps_hdr_nodes.jpg


二进制
examples/screenshots/webgl_materials_envmaps_pmrem_nodes.jpg


二进制
examples/screenshots/webgl_materials_physical_clearcoat.jpg


二进制
examples/screenshots/webgl_materials_physical_transparency.jpg


二进制
examples/screenshots/webgl_materials_variations_physical.jpg


二进制
examples/screenshots/webgl_materials_variations_standard.jpg


二进制
examples/screenshots/webgl_pmrem_test.jpg


二进制
examples/screenshots/webgl_shaders_ocean.jpg


二进制
examples/screenshots/webgl_shaders_sky.jpg


二进制
examples/screenshots/webgl_shaders_tonemapping.jpg


二进制
examples/screenshots/webgl_tonemapping.jpg


+ 1 - 3
examples/webgl2_buffergeometry_attributes_integer.html

@@ -144,9 +144,7 @@
 
 				// renderer
 
-				var canvas = document.createElement( 'canvas' );
-				var context = canvas.getContext( 'webgl2', { alpha: false } );
-				renderer = new THREE.WebGLRenderer( { canvas: canvas, context: context } );
+				renderer = new THREE.WebGLRenderer( { antialias: true } );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				document.body.appendChild( renderer.domElement );
 

+ 1 - 4
examples/webgl2_materials_texture2darray.html

@@ -122,10 +122,7 @@
 
 				// 2D Texture array is available on WebGL 2.0
 
-				var canvas = document.createElement( 'canvas' );
-				var context = canvas.getContext( 'webgl2', { alpha: false, antialias: false } );
-
-				renderer = new THREE.WebGLRenderer( { canvas: canvas, context: context } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				container.appendChild( renderer.domElement );

+ 1 - 3
examples/webgl2_materials_texture3d.html

@@ -43,9 +43,7 @@
 			scene = new THREE.Scene();
 
 			// Create renderer
-			var canvas = document.createElement( 'canvas' );
-			var context = canvas.getContext( 'webgl2', { alpha: false, antialias: false } );
-			renderer = new THREE.WebGLRenderer( { canvas: canvas, context: context } );
+			renderer = new THREE.WebGLRenderer();
 			renderer.setPixelRatio( window.devicePixelRatio );
 			renderer.setSize( window.innerWidth, window.innerHeight );
 			document.body.appendChild( renderer.domElement );

+ 1 - 4
examples/webgl2_multisampled_renderbuffers.html

@@ -106,10 +106,7 @@
 
 				//
 
-				var canvas = document.createElement( 'canvas' );
-				var context = canvas.getContext( 'webgl2', { alpha: false, antialias: false } );
-
-				renderer = new THREE.WebGLRenderer( { canvas: canvas, context: context } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.autoClear = false;
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( container.offsetWidth, container.offsetHeight );

+ 1 - 4
examples/webgl2_sandbox.html

@@ -62,10 +62,7 @@
 
 				}
 
-				var canvas = document.createElement( 'canvas' );
-				var context = canvas.getContext( 'webgl2', { alpha: false, antialias: true } );
-
-				renderer = new THREE.WebGLRenderer( { canvas: canvas, context: context } );
+				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				document.body.appendChild( renderer.domElement );

+ 1 - 1
examples/webgl_buffergeometry_instancing.html

@@ -169,7 +169,7 @@
 			renderer.setSize( window.innerWidth, window.innerHeight );
 			container.appendChild( renderer.domElement );
 
-			if ( renderer.extensions.get( 'ANGLE_instanced_arrays' ) === null ) {
+			if ( renderer.capabilities.isWebGL2 === false && renderer.extensions.get( 'ANGLE_instanced_arrays' ) === null ) {
 
 				document.getElementById( 'notSupported' ).style.display = '';
 				return;

+ 1 - 1
examples/webgl_buffergeometry_instancing_billboards.html

@@ -84,7 +84,7 @@
 
 			renderer = new THREE.WebGLRenderer();
 
-			if ( renderer.extensions.get( 'ANGLE_instanced_arrays' ) === null ) {
+			if ( renderer.capabilities.isWebGL2 === false && renderer.extensions.get( 'ANGLE_instanced_arrays' ) === null ) {
 
 				document.getElementById( 'notSupported' ).style.display = '';
 				return false;

+ 1 - 1
examples/webgl_buffergeometry_instancing_interleaved.html

@@ -154,7 +154,7 @@
 			renderer.setSize( window.innerWidth, window.innerHeight );
 			container.appendChild( renderer.domElement );
 
-			if ( renderer.extensions.get( 'ANGLE_instanced_arrays' ) === null ) {
+			if ( renderer.capabilities.isWebGL2 === false && renderer.extensions.get( 'ANGLE_instanced_arrays' ) === null ) {
 
 				document.getElementById( 'notSupported' ).style.display = '';
 				return;

+ 1 - 1
examples/webgl_depth_texture.html

@@ -91,7 +91,7 @@
 
 				renderer = new THREE.WebGLRenderer();
 
-				if ( ! renderer.extensions.get( 'WEBGL_depth_texture' ) ) {
+				if ( renderer.capabilities.isWebGL2 === false && ! renderer.extensions.get( 'WEBGL_depth_texture' ) ) {
 
 					supportsExtension = false;
 					document.querySelector( '#error' ).style.display = 'block';

+ 2 - 2
examples/webgl_lights_rectarealight.html

@@ -48,14 +48,14 @@
 				// Check for float-RT support
 				// TODO (abelnation): figure out fall-back for float textures
 
-				if ( ! renderer.extensions.get( 'OES_texture_float' ) ) {
+				if ( renderer.capabilities.isWebGL2 === false && ! renderer.extensions.get( 'OES_texture_float' ) ) {
 
 					alert( 'OES_texture_float not supported' );
 					throw 'missing webgl extension';
 
 				}
 
-				if ( ! renderer.extensions.get( 'OES_texture_float_linear' ) ) {
+				if ( renderer.capabilities.isWebGL2 === false && ! renderer.extensions.get( 'OES_texture_float_linear' ) ) {
 
 					alert( 'OES_texture_float_linear not supported' );
 					throw 'missing webgl extension';

+ 0 - 1
examples/webgl_loader_gltf.html

@@ -87,7 +87,6 @@
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.toneMapping = THREE.ACESFilmicToneMapping;
-				renderer.toneMappingExposure = 0.8;
 				renderer.outputEncoding = THREE.sRGBEncoding;
 				container.appendChild( renderer.domElement );
 

+ 6 - 8
examples/webgl_loader_gltf_extensions.html

@@ -14,8 +14,6 @@
 			<div id="description"></div>
 		</div>
 
-		<div id="container"></div>
-
 		<script type="module">
 
 			import * as THREE from '../build/three.module.js';
@@ -28,7 +26,7 @@
 			import { RGBELoader } from './jsm/loaders/RGBELoader.js';
 
 			var orbitControls;
-			var container, camera, scene, renderer, loader;
+			var camera, scene, renderer, loader;
 			var gltf, background, envMap, mixer, gui, extensionControls;
 
 			var clock = new THREE.Clock();
@@ -147,14 +145,14 @@
 
 			function onload() {
 
-				container = document.getElementById( 'container' );
-
 				renderer = new THREE.WebGLRenderer( { antialias: true } );
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.outputEncoding = THREE.sRGBEncoding;
+				renderer.toneMapping = THREE.ACESFilmicToneMapping;
+				renderer.toneMappingExposure = 1.25;
 				renderer.physicallyCorrectLights = true;
-				container.appendChild( renderer.domElement );
+				document.body.appendChild( renderer.domElement );
 
 				window.addEventListener( 'resize', onWindowResize, false );
 
@@ -196,7 +194,7 @@
 				scene = new THREE.Scene();
 				scene.background = new THREE.Color( 0x222222 );
 
-				camera = new THREE.PerspectiveCamera( 45, container.offsetWidth / container.offsetHeight, 0.001, 1000 );
+				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.001, 1000 );
 				scene.add( camera );
 
 				var spot1;
@@ -388,7 +386,7 @@
 
 			function onWindowResize() {
 
-				camera.aspect = container.offsetWidth / container.offsetHeight;
+				camera.aspect = window.innerWidth / window.innerHeight;
 				camera.updateProjectionMatrix();
 
 				renderer.setSize( window.innerWidth, window.innerHeight );

+ 6 - 5
examples/webgl_materials_car.html

@@ -25,7 +25,7 @@
 			<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> car materials<br/>
 			Ferrari 458 Italia model by <a href="https://sketchfab.com/models/57bf6cc56931426e87494f554df1dab6" target="_blank" rel="noopener">vicent091036</a>
 			<br><br>
-			<span class="colorPicker"><input id="body-color" type="color" value="#000333"></input><br/>Body</span>
+			<span class="colorPicker"><input id="body-color" type="color" value="#ff0000"></input><br/>Body</span>
 			<span class="colorPicker"><input id="details-color" type="color" value="#ffffff"></input><br/>Details</span>
 			<span class="colorPicker"><input id="glass-color" type="color" value="#ffffff"></input><br/>Glass</span>
 		</div>
@@ -60,6 +60,7 @@
 				renderer.setAnimationLoop( render );
 				renderer.outputEncoding = THREE.sRGBEncoding;
 				renderer.toneMapping = THREE.ACESFilmicToneMapping;
+				renderer.toneMappingExposure = 1.25;
 				container.appendChild( renderer.domElement );
 
 				window.addEventListener( 'resize', onWindowResize, false );
@@ -69,8 +70,8 @@
 
 				//
 
-				camera = new THREE.PerspectiveCamera( 30, window.innerWidth / window.innerHeight, 0.1, 100 );
-				camera.position.set( 6, 2, - 5 );
+				camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 0.1, 100 );
+				camera.position.set( 3.5, 2, - 4.5 );
 
 				controls = new OrbitControls( camera, container );
 				controls.target.set( 0, 0.5, 0 );
@@ -90,7 +91,7 @@
 				// materials
 
 				var bodyMaterial = new THREE.MeshPhysicalMaterial( {
-					color: 0x000333, metalness: 1.0, roughness: 0.5, clearcoat: 0.02, clearcoatRoughness: 0.01
+					color: 0xff0000, metalness: 0.6, roughness: 0.4, clearcoat: 0.05, clearcoatRoughness: 0.05
 				} );
 
 				var detailsMaterial = new THREE.MeshStandardMaterial( {
@@ -98,7 +99,7 @@
 				} );
 
 				var glassMaterial = new THREE.MeshPhysicalMaterial( {
-					color: 0xffffff, metalness: 0, roughness: 0, transparency: 0.8, transparent: true
+					color: 0xffffff, metalness: 0, roughness: 0.1, transparency: 0.9, transparent: true
 				} );
 
 				var bodyColorInput = document.getElementById( 'body-color' );

+ 1 - 1
examples/webgl_materials_envmaps_exr.html

@@ -25,7 +25,7 @@
 				envMap: 'EXR',
 				roughness: 0.0,
 				metalness: 0.0,
-				exposure: 1.0,
+				exposure: 2.0,
 				debug: false,
 			};
 

+ 1 - 1
examples/webgl_materials_envmaps_hdr.html

@@ -28,7 +28,7 @@
 				envMap: 'HDR',
 				roughness: 0.0,
 				metalness: 0.0,
-				exposure: 1.0,
+				exposure: 2.0,
 				debug: false
 			};
 

+ 1 - 1
examples/webgl_materials_envmaps_hdr_nodes.html

@@ -30,7 +30,7 @@
 				envMap: 'HDR',
 				roughness: 0.0,
 				metalness: 0.0,
-				exposure: 1.0,
+				exposure: 2.0,
 				nodes: true,
 				animate: true,
 				debug: false

+ 1 - 1
examples/webgl_materials_envmaps_pmrem_nodes.html

@@ -52,7 +52,7 @@
 			var params = {
 				roughness: 0.0,
 				metalness: 0.0,
-				exposure: 1.0,
+				exposure: 2.0,
 				intensity: 1.0,
 				animate: true,
 				debug: false

+ 1 - 1
examples/webgl_materials_physical_clearcoat.html

@@ -176,7 +176,7 @@
 				//
 
 				renderer.toneMapping = THREE.ACESFilmicToneMapping;
-				renderer.toneMappingExposure = 1;
+				renderer.toneMappingExposure = 2;
 
 				//
 

+ 0 - 1
examples/webgl_materials_variations_physical.html

@@ -159,7 +159,6 @@
 
 				renderer.outputEncoding = THREE.sRGBEncoding;
 				renderer.toneMapping = THREE.ACESFilmicToneMapping;
-				renderer.toneMappingExposure = 0.75;
 
 				//
 

+ 0 - 1
examples/webgl_materials_variations_standard.html

@@ -164,7 +164,6 @@
 
 				renderer.outputEncoding = THREE.sRGBEncoding;
 				renderer.toneMapping = THREE.ACESFilmicToneMapping;
-				renderer.toneMappingExposure = 0.75;
 
 				//
 

+ 4 - 4
examples/webgl_pmrem_test.html

@@ -29,7 +29,7 @@
 			import { RGBELoader } from './jsm/loaders/RGBELoader.js';
 
 			var scene, camera, controls, renderer;
-			
+
 			function init() {
 
 				var width = window.innerWidth;
@@ -46,7 +46,7 @@
 
 				// tonemapping
 				renderer.toneMapping = THREE.ACESFilmicToneMapping;
-				renderer.toneMappingExposure = 1;
+				renderer.toneMappingExposure = 1.75;
 
 				document.body.appendChild( renderer.domElement );
 
@@ -182,7 +182,7 @@
 				render();
 
 			}
-			
+
 			function updateCamera() {
 
 				var horizontalFoV = 40;
@@ -197,7 +197,7 @@
 				renderer.render( scene, camera );
 
 			}
-			
+
 			Promise.resolve()
 				.then( init )
 				.then( createObjects )

+ 0 - 12
examples/webgl_postprocessing_ssao.html

@@ -14,11 +14,6 @@
 	<body>
 		<div id="info">
 			<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - screen space ambient occlusion<br/>
-
-			<div id="error" style="display: none;">
-				Your browser does not support <strong>WEBGL_depth_texture</strong>.<br/><br/>
-				This demo will not work.
-			</div>
 		</div>
 
 		<script type="module">
@@ -48,13 +43,6 @@
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				document.body.appendChild( renderer.domElement );
 
-				if ( ! renderer.extensions.get( 'WEBGL_depth_texture' ) ) {
-
-					document.querySelector( '#error' ).style.display = 'block';
-					return;
-
-				}
-
 				camera = new THREE.PerspectiveCamera( 65, window.innerWidth / window.innerHeight, 100, 700 );
 				camera.position.z = 500;
 

+ 20 - 49
examples/webgl_shaders_ocean.html

@@ -25,8 +25,8 @@
 			import { Sky } from './jsm/objects/Sky.js';
 
 			var container, stats;
-			var camera, scene, renderer, light;
-			var controls, water, sphere;
+			var camera, scene, renderer;
+			var controls, water, sun, mesh;
 
 			init();
 			animate();
@@ -46,15 +46,12 @@
 
 				scene = new THREE.Scene();
 
-				//
-
 				camera = new THREE.PerspectiveCamera( 55, window.innerWidth / window.innerHeight, 1, 20000 );
 				camera.position.set( 30, 30, 100 );
 
 				//
 
-				light = new THREE.DirectionalLight( 0xffffff, 0.8 );
-				scene.add( light );
+				sun = new THREE.Vector3();
 
 				// Water
 
@@ -71,7 +68,7 @@
 
 						} ),
 						alpha: 1.0,
-						sunDirection: light.position.clone().normalize(),
+						sunDirection: new THREE.Vector3(),
 						sunColor: 0xffffff,
 						waterColor: 0x001e0f,
 						distortionScale: 3.7,
@@ -86,39 +83,36 @@
 				// Skybox
 
 				var sky = new Sky();
+				sky.scale.setScalar( 10000 );
+				scene.add( sky );
 
 				var uniforms = sky.material.uniforms;
 
 				uniforms[ 'turbidity' ].value = 10;
 				uniforms[ 'rayleigh' ].value = 2;
-				uniforms[ 'luminance' ].value = 1;
 				uniforms[ 'mieCoefficient' ].value = 0.005;
 				uniforms[ 'mieDirectionalG' ].value = 0.8;
 
 				var parameters = {
-					distance: 400,
 					inclination: 0.49,
 					azimuth: 0.205
 				};
 
-				var cubeRenderTarget = new THREE.WebGLCubeRenderTarget( 512, { format: THREE.RGBFormat, generateMipmaps: true, minFilter: THREE.LinearMipmapLinearFilter } );
-				var cubeCamera = new THREE.CubeCamera( 0.1, 1, cubeRenderTarget );
-
-				scene.background = cubeRenderTarget;
+				var pmremGenerator = new THREE.PMREMGenerator( renderer );
 
 				function updateSun() {
 
 					var theta = Math.PI * ( parameters.inclination - 0.5 );
 					var phi = 2 * Math.PI * ( parameters.azimuth - 0.5 );
 
-					light.position.x = parameters.distance * Math.cos( phi );
-					light.position.y = parameters.distance * Math.sin( phi ) * Math.sin( theta );
-					light.position.z = parameters.distance * Math.sin( phi ) * Math.cos( theta );
+					sun.x = Math.cos( phi );
+					sun.y = Math.sin( phi ) * Math.sin( theta );
+					sun.z = Math.sin( phi ) * Math.cos( theta );
 
-					sky.material.uniforms[ 'sunPosition' ].value = light.position.copy( light.position );
-					water.material.uniforms[ 'sunDirection' ].value.copy( light.position ).normalize();
+					sky.material.uniforms[ 'sunPosition' ].value.copy( sun );
+					water.material.uniforms[ 'sunDirection' ].value.copy( sun ).normalize();
 
-					cubeCamera.update( renderer, sky );
+					scene.environment = pmremGenerator.fromScene( sky ).texture;
 
 				}
 
@@ -126,34 +120,11 @@
 
 				//
 
-				var geometry = new THREE.IcosahedronBufferGeometry( 20, 1 );
-				var count = geometry.attributes.position.count;
-
-				var colors = [];
-				var color = new THREE.Color();
-
-				for ( var i = 0; i < count; i += 3 ) {
-
-					color.setHex( Math.random() * 0xffffff );
-
-					colors.push( color.r, color.g, color.b );
-					colors.push( color.r, color.g, color.b );
-					colors.push( color.r, color.g, color.b );
-
-				}
-
-				geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) );
-
-				var material = new THREE.MeshStandardMaterial( {
-					vertexColors: true,
-					roughness: 0.0,
-					flatShading: true,
-					envMap: cubeRenderTarget.texture,
-					side: THREE.DoubleSide
-				} );
+				var geometry = new THREE.BoxBufferGeometry( 30, 30, 30 );
+				var material = new THREE.MeshStandardMaterial( { roughness: 0 } );
 
-				sphere = new THREE.Mesh( geometry, material );
-				scene.add( sphere );
+				mesh = new THREE.Mesh( geometry, material );
+				scene.add( mesh );
 
 				//
 
@@ -213,9 +184,9 @@
 
 				var time = performance.now() * 0.001;
 
-				sphere.position.y = Math.sin( time ) * 20 + 5;
-				sphere.rotation.x = time * 0.5;
-				sphere.rotation.z = time * 0.51;
+				mesh.position.y = Math.sin( time ) * 20 + 5;
+				mesh.rotation.x = time * 0.5;
+				mesh.rotation.z = time * 0.51;
 
 				water.material.uniforms[ 'time' ].value += 1.0 / 60.0;
 

+ 12 - 22
examples/webgl_shaders_sky.html

@@ -21,7 +21,7 @@
 
 			var camera, controls, scene, renderer;
 
-			var sky, sunSphere;
+			var sky, sun;
 
 			init();
 			render();
@@ -33,14 +33,7 @@
 				sky.scale.setScalar( 450000 );
 				scene.add( sky );
 
-				// Add Sun Helper
-				sunSphere = new THREE.Mesh(
-					new THREE.SphereBufferGeometry( 20000, 16, 8 ),
-					new THREE.MeshBasicMaterial( { color: 0xffffff } )
-				);
-				sunSphere.position.y = - 700000;
-				sunSphere.visible = false;
-				scene.add( sunSphere );
+				sun = new THREE.Vector3();
 
 				/// GUI
 
@@ -49,14 +42,11 @@
 					rayleigh: 2,
 					mieCoefficient: 0.005,
 					mieDirectionalG: 0.8,
-					luminance: 1,
 					inclination: 0.49, // elevation / inclination
 					azimuth: 0.25, // Facing front,
-					sun: ! true
+					exposure: renderer.toneMappingExposure
 				};
 
-				var distance = 400000;
-
 				function guiChanged() {
 
 					var uniforms = sky.material.uniforms;
@@ -64,19 +54,17 @@
 					uniforms[ "rayleigh" ].value = effectController.rayleigh;
 					uniforms[ "mieCoefficient" ].value = effectController.mieCoefficient;
 					uniforms[ "mieDirectionalG" ].value = effectController.mieDirectionalG;
-					uniforms[ "luminance" ].value = effectController.luminance;
 
 					var theta = Math.PI * ( effectController.inclination - 0.5 );
 					var phi = 2 * Math.PI * ( effectController.azimuth - 0.5 );
 
-					sunSphere.position.x = distance * Math.cos( phi );
-					sunSphere.position.y = distance * Math.sin( phi ) * Math.sin( theta );
-					sunSphere.position.z = distance * Math.sin( phi ) * Math.cos( theta );
-
-					sunSphere.visible = effectController.sun;
+					sun.x = Math.cos( phi );
+					sun.y = Math.sin( phi ) * Math.sin( theta );
+					sun.z = Math.sin( phi ) * Math.cos( theta );
 
-					uniforms[ "sunPosition" ].value.copy( sunSphere.position );
+					uniforms[ "sunPosition" ].value.copy( sun );
 
+					renderer.toneMappingExposure = effectController.exposure;
 					renderer.render( scene, camera );
 
 				}
@@ -87,10 +75,9 @@
 				gui.add( effectController, "rayleigh", 0.0, 4, 0.001 ).onChange( guiChanged );
 				gui.add( effectController, "mieCoefficient", 0.0, 0.1, 0.001 ).onChange( guiChanged );
 				gui.add( effectController, "mieDirectionalG", 0.0, 1, 0.001 ).onChange( guiChanged );
-				gui.add( effectController, "luminance", 0.0, 2 ).onChange( guiChanged );
 				gui.add( effectController, "inclination", 0, 1, 0.0001 ).onChange( guiChanged );
 				gui.add( effectController, "azimuth", 0, 1, 0.0001 ).onChange( guiChanged );
-				gui.add( effectController, "sun" ).onChange( guiChanged );
+				gui.add( effectController, "exposure", 0, 1, 0.0001 ).onChange( guiChanged );
 
 				guiChanged();
 
@@ -109,6 +96,9 @@
 				renderer = new THREE.WebGLRenderer();
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
+				renderer.outputEncoding = THREE.sRGBEncoding;
+				renderer.toneMapping = THREE.ACESFilmicToneMapping;
+				renderer.toneMappingExposure = 0.5;
 				document.body.appendChild( renderer.domElement );
 
 				controls = new OrbitControls( camera, renderer.domElement );

+ 3 - 2
examples/webgl_shaders_tonemapping.html

@@ -333,11 +333,12 @@
 				var regularRenderTarget = new THREE.WebGLRenderTarget( windowThirdX, height, parameters );
 				ldrEffectComposer = new EffectComposer( renderer, regularRenderTarget );
 
-				if ( renderer.extensions.get( 'OES_texture_half_float_linear' ) ) {
+				if ( renderer.capabilities.isWebGL2 === false && renderer.extensions.get( 'OES_texture_half_float_linear' ) ) {
 
 					parameters.type = THREE.FloatType;
 
-	}
+				}
+
 				var hdrRenderTarget = new THREE.WebGLRenderTarget( windowThirdX, height, parameters );
 				dynamicHdrEffectComposer = new EffectComposer( renderer, hdrRenderTarget );
 				dynamicHdrEffectComposer.setSize( window.innerWidth, window.innerHeight );

+ 1 - 1
examples/webgl_tonemapping.html

@@ -28,7 +28,7 @@
 			var gui, guiExposure = null;
 
 			var params = {
-				exposure: 0.8,
+				exposure: 1.5,
 				toneMapping: 'ACESFilmic'
 			};
 

+ 22 - 21
package-lock.json

@@ -43,51 +43,52 @@
       "dev": true
     },
     "@types/json-schema": {
-      "version": "7.0.4",
-      "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz",
-      "integrity": "sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==",
+      "version": "7.0.5",
+      "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz",
+      "integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==",
       "dev": true
     },
     "@typescript-eslint/eslint-plugin": {
-      "version": "2.34.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.34.0.tgz",
-      "integrity": "sha512-4zY3Z88rEE99+CNvTbXSyovv2z9PNOVffTWD2W8QF5s2prBQtwN2zadqERcrHpcR7O/+KMI3fcTAmUUhK/iQcQ==",
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.2.0.tgz",
+      "integrity": "sha512-t9RTk/GyYilIXt6BmZurhBzuMT9kLKw3fQoJtK9ayv0tXTlznXEAnx07sCLXdkN3/tZDep1s1CEV95CWuARYWA==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/experimental-utils": "2.34.0",
+        "@typescript-eslint/experimental-utils": "3.2.0",
         "functional-red-black-tree": "^1.0.1",
         "regexpp": "^3.0.0",
+        "semver": "^7.3.2",
         "tsutils": "^3.17.1"
       }
     },
     "@typescript-eslint/experimental-utils": {
-      "version": "2.34.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz",
-      "integrity": "sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA==",
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.2.0.tgz",
+      "integrity": "sha512-UbJBsk+xO9dIFKtj16+m42EvUvsjZbbgQ2O5xSTSfVT1Z3yGkL90DVu0Hd3029FZ5/uBgl+F3Vo8FAcEcqc6aQ==",
       "dev": true,
       "requires": {
         "@types/json-schema": "^7.0.3",
-        "@typescript-eslint/typescript-estree": "2.34.0",
+        "@typescript-eslint/typescript-estree": "3.2.0",
         "eslint-scope": "^5.0.0",
         "eslint-utils": "^2.0.0"
       }
     },
     "@typescript-eslint/parser": {
-      "version": "2.34.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.34.0.tgz",
-      "integrity": "sha512-03ilO0ucSD0EPTw2X4PntSIRFtDPWjrVq7C3/Z3VQHRC7+13YB55rcJI3Jt+YgeHbjUdJPcPa7b23rXCBokuyA==",
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-3.2.0.tgz",
+      "integrity": "sha512-Vhu+wwdevDLVDjK1lIcoD6ZbuOa93fzqszkaO3iCnmrScmKwyW/AGkzc2UvfE5TCoCXqq7Jyt6SOXjsIlpqF4A==",
       "dev": true,
       "requires": {
         "@types/eslint-visitor-keys": "^1.0.0",
-        "@typescript-eslint/experimental-utils": "2.34.0",
-        "@typescript-eslint/typescript-estree": "2.34.0",
+        "@typescript-eslint/experimental-utils": "3.2.0",
+        "@typescript-eslint/typescript-estree": "3.2.0",
         "eslint-visitor-keys": "^1.1.0"
       }
     },
     "@typescript-eslint/typescript-estree": {
-      "version": "2.34.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz",
-      "integrity": "sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==",
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.2.0.tgz",
+      "integrity": "sha512-uh+Y2QO7dxNrdLw7mVnjUqkwO/InxEqwN0wF+Za6eo3coxls9aH9kQ/5rSvW2GcNanebRTmsT5w1/92lAOb1bA==",
       "dev": true,
       "requires": {
         "debug": "^4.1.1",
@@ -1431,7 +1432,7 @@
     },
     "os-tmpdir": {
       "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+      "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
       "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
       "dev": true
     },
@@ -1901,7 +1902,7 @@
     },
     "through": {
       "version": "2.3.8",
-      "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+      "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz",
       "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
       "dev": true
     },

+ 2 - 2
package.json

@@ -80,8 +80,8 @@
   },
   "homepage": "https://threejs.org/",
   "devDependencies": {
-    "@typescript-eslint/eslint-plugin": "^2.34.0",
-    "@typescript-eslint/parser": "^2.34.0",
+    "@typescript-eslint/eslint-plugin": "^3.2.0",
+    "@typescript-eslint/parser": "^3.2.0",
     "concurrently": "^5.2.0",
     "eslint": "^7.2.0",
     "eslint-config-mdcs": "^5.0.0",

+ 19 - 6
src/core/BufferAttribute.js

@@ -9,6 +9,7 @@ import { StaticDrawUsage } from '../constants.js';
  */
 
 const _vector = new Vector3();
+const _vector2 = new Vector2();
 
 function BufferAttribute( array, itemSize, normalized ) {
 
@@ -199,15 +200,27 @@ Object.assign( BufferAttribute.prototype, {
 
 	applyMatrix3: function ( m ) {
 
-		for ( let i = 0, l = this.count; i < l; i ++ ) {
+		if ( this.itemSize === 2 ) {
 
-			_vector.x = this.getX( i );
-			_vector.y = this.getY( i );
-			_vector.z = this.getZ( i );
+			for ( let i = 0, l = this.count; i < l; i ++ ) {
 
-			_vector.applyMatrix3( m );
+				_vector2.fromBufferAttribute( this, i );
+				_vector2.applyMatrix3( m );
 
-			this.setXYZ( i, _vector.x, _vector.y, _vector.z );
+				this.setXY( i, _vector2.x, _vector2.y, );
+
+			}
+
+		} else if ( this.itemSize === 3 ) {
+
+			for ( let i = 0, l = this.count; i < l; i ++ ) {
+
+				_vector.fromBufferAttribute( this, i );
+				_vector.applyMatrix3( m );
+
+				this.setXYZ( i, _vector.x, _vector.y, _vector.z );
+
+			}
 
 		}
 

+ 1 - 3
src/core/BufferGeometry.js

@@ -858,9 +858,7 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy
 
 		for ( let i = 0, il = normals.count; i < il; i ++ ) {
 
-			_vector.x = normals.getX( i );
-			_vector.y = normals.getY( i );
-			_vector.z = normals.getZ( i );
+			_vector.fromBufferAttribute( normals, i );
 
 			_vector.normalize();
 

+ 10 - 2
src/extras/ImageUtils.js

@@ -10,13 +10,21 @@ const ImageUtils = {
 
 	getDataURL: function ( image ) {
 
-		let canvas;
+		if ( /^data:/i.test( image.src ) ) {
+
+			return image.src;
+
+		}
 
 		if ( typeof HTMLCanvasElement == 'undefined' ) {
 
 			return image.src;
 
-		} else if ( image instanceof HTMLCanvasElement ) {
+		}
+
+		let canvas;
+
+		if ( image instanceof HTMLCanvasElement ) {
 
 			canvas = image;
 

+ 6 - 6
src/extras/PMREMGenerator.js

@@ -610,6 +610,8 @@ function _getBlurShader( maxSamples ) {
 	const poleAxis = new Vector3( 0, 1, 0 );
 	const shaderMaterial = new RawShaderMaterial( {
 
+		name: 'SphericalGaussianBlur',
+
 		defines: { 'n': maxSamples },
 
 		uniforms: {
@@ -676,8 +678,6 @@ void main() {
 
 	} );
 
-	shaderMaterial.type = 'SphericalGaussianBlur';
-
 	return shaderMaterial;
 
 }
@@ -687,6 +687,8 @@ function _getEquirectShader() {
 	const texelSize = new Vector2( 1, 1 );
 	const shaderMaterial = new RawShaderMaterial( {
 
+		name: 'EquirectangularToCubeUV',
+
 		uniforms: {
 			'envMap': { value: null },
 			'texelSize': { value: texelSize },
@@ -733,8 +735,6 @@ void main() {
 
 	} );
 
-	shaderMaterial.type = 'EquirectangularToCubeUV';
-
 	return shaderMaterial;
 
 }
@@ -743,6 +743,8 @@ function _getCubemapShader() {
 
 	const shaderMaterial = new RawShaderMaterial( {
 
+		name: 'CubemapToCubeUV',
+
 		uniforms: {
 			'envMap': { value: null },
 			'inputEncoding': { value: ENCODINGS[ LinearEncoding ] },
@@ -772,8 +774,6 @@ void main() {
 
 	} );
 
-	shaderMaterial.type = 'CubemapToCubeUV';
-
 	return shaderMaterial;
 
 }

+ 1 - 1
src/renderers/WebGLCubeRenderTarget.js

@@ -89,7 +89,7 @@ WebGLCubeRenderTarget.prototype.fromEquirectangularTexture = function ( renderer
 
 	const material = new ShaderMaterial( {
 
-		type: 'CubemapFromEquirect',
+		name: 'CubemapFromEquirect',
 
 		uniforms: cloneUniforms( shader.uniforms ),
 		vertexShader: shader.vertexShader,

+ 2 - 2
src/renderers/WebGLRenderer.js

@@ -204,11 +204,11 @@ function WebGLRenderer( parameters ) {
 		_canvas.addEventListener( 'webglcontextlost', onContextLost, false );
 		_canvas.addEventListener( 'webglcontextrestored', onContextRestore, false );
 
-		_gl = _context || _canvas.getContext( 'webgl', contextAttributes ) || _canvas.getContext( 'experimental-webgl', contextAttributes );
+		_gl = _context || _canvas.getContext( 'webgl2', contextAttributes ) || _canvas.getContext( 'webgl', contextAttributes ) || _canvas.getContext( 'experimental-webgl', contextAttributes );
 
 		if ( _gl === null ) {
 
-			if ( _canvas.getContext( 'webgl' ) !== null ) {
+			if ( _canvas.getContext( 'webgl2' ) || _canvas.getContext( 'webgl' ) || _canvas.getContext( 'experimental-webgl' ) ) {
 
 				throw new Error( 'Error creating WebGL context with your selected attributes.' );
 

+ 34 - 3
src/renderers/shaders/ShaderChunk/tonemapping_pars_fragment.glsl.js

@@ -31,11 +31,42 @@ vec3 OptimizedCineonToneMapping( vec3 color ) {
 
 }
 
-// source: https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/
+// source: https://github.com/selfshadow/ltc_code/blob/master/webgl/shaders/ltc/ltc_blit.fs
+vec3 RRTAndODTFit( vec3 v ) {
+
+    vec3 a = v * ( v + 0.0245786 ) - 0.000090537;
+    vec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081;
+    return a / b;
+
+}
+
 vec3 ACESFilmicToneMapping( vec3 color ) {
 
-	color *= toneMappingExposure;
-	return saturate( ( color * ( 2.51 * color + 0.03 ) ) / ( color * ( 2.43 * color + 0.59 ) + 0.14 ) );
+    // sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT
+    const mat3 ACESInputMat = mat3(
+        vec3( 0.59719, 0.07600, 0.02840 ), // transposed from source
+        vec3( 0.35458, 0.90834, 0.13383 ),
+        vec3( 0.04823, 0.01566, 0.83777 )
+    );
+
+    // ODT_SAT => XYZ => D60_2_D65 => sRGB
+    const mat3 ACESOutputMat = mat3(
+        vec3(  1.60475, -0.10208, -0.00327 ), // transposed from source
+        vec3( -0.53108,  1.10813, -0.07276 ),
+        vec3( -0.07367, -0.00605,  1.07602 )
+    );
+
+    color *= toneMappingExposure;
+
+    color = ACESInputMat * color;
+
+    // Apply RRT and ODT
+    color = RRTAndODTFit( color );
+
+    color = ACESOutputMat * color;
+
+    // Clamp to [0, 1]
+    return saturate( color );
 
 }
 `;

+ 2 - 2
src/renderers/webgl/WebGLBackground.js

@@ -63,7 +63,7 @@ function WebGLBackground( renderer, state, objects, premultipliedAlpha ) {
 				boxMesh = new Mesh(
 					new BoxBufferGeometry( 1, 1, 1 ),
 					new ShaderMaterial( {
-						type: 'BackgroundCubeMaterial',
+						name: 'BackgroundCubeMaterial',
 						uniforms: cloneUniforms( ShaderLib.cube.uniforms ),
 						vertexShader: ShaderLib.cube.vertexShader,
 						fragmentShader: ShaderLib.cube.fragmentShader,
@@ -125,7 +125,7 @@ function WebGLBackground( renderer, state, objects, premultipliedAlpha ) {
 				planeMesh = new Mesh(
 					new PlaneBufferGeometry( 2, 2 ),
 					new ShaderMaterial( {
-						type: 'BackgroundMaterial',
+						name: 'BackgroundMaterial',
 						uniforms: cloneUniforms( ShaderLib.background.uniforms ),
 						vertexShader: ShaderLib.background.vertexShader,
 						fragmentShader: ShaderLib.background.fragmentShader,

+ 4 - 2
src/renderers/webgl/WebGLProgram.js

@@ -44,7 +44,8 @@ function getEncodingComponents( encoding ) {
 		case LogLuvEncoding:
 			return [ 'LogLuv', '( value )' ];
 		default:
-			throw new Error( 'unsupported encoding: ' + encoding );
+			console.warn( 'THREE.WebGLProgram: Unsupported encoding:', encoding );
+			return [ 'Linear', '( value )' ];
 
 	}
 
@@ -103,7 +104,8 @@ function getToneMappingFunction( functionName, toneMapping ) {
 			break;
 
 		default:
-			throw new Error( 'unsupported toneMapping: ' + toneMapping );
+			console.warn( 'THREE.WebGLProgram: Unsupported toneMapping:', toneMapping );
+			toneMappingName = 'Linear';
 
 	}
 

+ 2 - 2
src/renderers/webgl/WebGLPrograms.js

@@ -62,7 +62,7 @@ function WebGLPrograms( renderer, extensions, capabilities ) {
 			const shader = ShaderLib[ shaderID ];
 
 			shaderobject = {
-				name: material.type,
+				name: material.name || material.type,
 				uniforms: UniformsUtils.clone( shader.uniforms ),
 				vertexShader: shader.vertexShader,
 				fragmentShader: shader.fragmentShader
@@ -71,7 +71,7 @@ function WebGLPrograms( renderer, extensions, capabilities ) {
 		} else {
 
 			shaderobject = {
-				name: material.type,
+				name: material.name || material.type,
 				uniforms: material.uniforms,
 				vertexShader: material.vertexShader,
 				fragmentShader: material.fragmentShader

部分文件因为文件数量过多而无法显示