diff --git a/docs/api/en/scenes/FogExp2.html b/docs/api/en/scenes/DensityFog.html
similarity index 60%
rename from docs/api/en/scenes/FogExp2.html
rename to docs/api/en/scenes/DensityFog.html
index c9f9a05541452d..0df74dcf74f8f6 100644
--- a/docs/api/en/scenes/FogExp2.html
+++ b/docs/api/en/scenes/DensityFog.html
@@ -10,13 +10,13 @@
[name]
- This class contains the parameters that define exponential squared fog, which gives a clear view near the camera and a faster than exponentially densening fog farther from the camera.
+ This class contains the parameters that define density-based fog.
Constructor
- [name]( [param:Integer color], [param:Float density] )
+ [name]( [param:Integer color], [param:Float density], [param:Boolean squared] )
The color parameter is passed to the [page:Color] constructor to set the color property. Color can be a hexadecimal integer or a CSS-style string.
Properties
@@ -30,14 +30,18 @@ [property:Color color]
[property:Float density]
Defines how fast the fog will grow dense.
Default is 0.00025.
+
+ [property:Boolean squared]
+ If false, the mode will be exponential fog, which is analogous to physical fog. If true, the mode will be exponential squared fog, which gives a clear view near the camera and a faster than exponentially densening fog farther from the camera.
+ Default is true, that is exponential squared fog.
Methods
- [method:FogExp2 clone]()
- Returns a new FogExp2 instance with the same parameters as this one.
+ [method:DensityFog clone]()
+ Returns a new DensityFog instance with the same parameters as this one.
- [method:FogExp2 toJSON]()
- Return FogExp2 data in JSON format.
+ [method:DensityFog toJSON]()
+ Return DensityFog data in JSON format.
Source
diff --git a/docs/api/en/scenes/Fog.html b/docs/api/en/scenes/RangeFog.html
similarity index 90%
rename from docs/api/en/scenes/Fog.html
rename to docs/api/en/scenes/RangeFog.html
index 197d612cb34e09..1509a5f1e8de72 100644
--- a/docs/api/en/scenes/Fog.html
+++ b/docs/api/en/scenes/RangeFog.html
@@ -10,7 +10,7 @@
[name]
- This class contains the parameters that define linear fog, i.e., that grows linearly denser with the distance.
+ This class contains the parameters that define smooth ranged fog, i.e., that grows smoothly denser from the near to the far distance.
Constructor
@@ -37,10 +37,10 @@ [property:Float far]
Methods
- [method:Fog clone]()
+ [method:RangeFog clone]()
Returns a new fog instance with the same parameters as this one.
- [method:Fog toJSON]()
+ [method:RangeFog toJSON]()
Return fog data in JSON format.
Source
diff --git a/docs/api/zh/scenes/DensityFog.html b/docs/api/zh/scenes/DensityFog.html
new file mode 100644
index 00000000000000..8f5c639a6a565b
--- /dev/null
+++ b/docs/api/zh/scenes/DensityFog.html
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ [name]
+
+ This class contains the parameters that define density-based fog.
+
+
+ Constructor
+
+
+ [name]( [param:Integer color], [param:Float density], [param:Boolean squared] )
+
+ The color parameter is passed to the [page:Color] constructor to set the color property. Color can be a hexadecimal integer or a CSS-style string.
+ Properties
+
+ [property:String name]
+ Optional name of the object (doesn't need to be unique). Default is an empty string.
+
+ [property:Color color]
+ Fog color. Example: If set to black, far away objects will be rendered black.
+
+ [property:Float density]
+ Defines how fast the fog will grow dense.
+ Default is 0.00025.
+
+ [property:Boolean squared]
+ If false, the mode will be exponential fog, which is analogous to physical fog. If true, the mode will be exponential squared fog, which gives a clear view near the camera and a faster than exponentially densening fog farther from the camera.
+ Default is true, that is exponential squared fog.
+
+ Methods
+
+ [method:DensityFog clone]()
+ Returns a new DensityFog instance with the same parameters as this one.
+
+ [method:DensityFog toJSON]()
+ Return DensityFog data in JSON format.
+
+ Source
+
+
+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+
+
+
diff --git a/docs/api/zh/scenes/FogExp2.html b/docs/api/zh/scenes/FogExp2.html
deleted file mode 100644
index e307097d9e0d36..00000000000000
--- a/docs/api/zh/scenes/FogExp2.html
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- 雾-指数([name])
-
- 该类所包含的参数定义了指数雾,它可以在相机附近提供清晰的视野,且距离相机越远,雾的浓度随着指数增长越快。
-
- 构造器
-
-
- [name]( [param:Integer color], [param:Float density] )
-
- 颜色参数传入[page:Color]构造函数中,来设置颜色属性。颜色可以是一个十六进制的整型数,或者是CSS风格的字符串。
- 属性
-
- [property:String name]
- 对象的名称,可选、不必唯一。默认值是一个空字符串。
-
- [property:Color color]
- 雾的颜色。比如说,如果将其设置为黑色,远处的物体将被渲染成黑色。
-
- [property:Float density]
- 定义雾的密度将会增长多块。
- 默认值是0.00025.
-
- 方法
-
- [method:FogExp2 clone]()
- 返回一个具有和当前雾参数相同的新的FogExp2实例。
-
- [method:FogExp2 toJSON]()
- 以JSON格式返回FogExp2的数据。
-
- 源代码
-
-
- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
-
-
-
diff --git a/docs/api/zh/scenes/Fog.html b/docs/api/zh/scenes/RangeFog.html
similarity index 83%
rename from docs/api/zh/scenes/Fog.html
rename to docs/api/zh/scenes/RangeFog.html
index 3964d1570c5ece..0b3f27d894da6a 100644
--- a/docs/api/zh/scenes/Fog.html
+++ b/docs/api/zh/scenes/RangeFog.html
@@ -1,4 +1,5 @@
+
@@ -38,11 +39,11 @@ [property:Float far]
方法
- [method:Fog clone]()
- 返回一个具有和当前雾参数相同的新的Fog实例。
+ [method:RangeFog clone]()
+ 返回一个具有和当前雾参数相同的新的RangeFog实例。
- [method:Fog toJSON]()
- 以JSON格式返回Fog的数据。
+ [method:RangeFog toJSON]()
+ 以JSON格式返回RangeFog的数据。
源代码
diff --git a/docs/list.js b/docs/list.js
index eee2418bfe9a2a..d1e2bdea4ca426 100644
--- a/docs/list.js
+++ b/docs/list.js
@@ -327,8 +327,8 @@ var list = {
},
"Scenes": {
- "Fog": "api/en/scenes/Fog",
- "FogExp2": "api/en/scenes/FogExp2",
+ "RangeFog": "api/en/scenes/RangeFog",
+ "DensityFog": "api/en/scenes/DensityFog",
"Scene": "api/en/scenes/Scene"
},
@@ -770,8 +770,8 @@ var list = {
},
"场景": {
- "Fog": "api/zh/scenes/Fog",
- "FogExp2": "api/zh/scenes/FogExp2",
+ "RangeFog": "api/zh/scenes/RangeFog",
+ "DensityFog": "api/zh/scenes/DensityFog",
"Scene": "api/zh/scenes/Scene"
},
diff --git a/editor/js/Sidebar.Scene.js b/editor/js/Sidebar.Scene.js
index 17dcee66e3df85..89abb936dc1158 100644
--- a/editor/js/Sidebar.Scene.js
+++ b/editor/js/Sidebar.Scene.js
@@ -134,7 +134,8 @@ Sidebar.Scene = function ( editor ) {
fogColor.getHexValue(),
fogNear.getValue(),
fogFar.getValue(),
- fogDensity.getValue()
+ fogDensity.getValue(),
+ fogSquared.getValue()
);
}
@@ -143,8 +144,8 @@ Sidebar.Scene = function ( editor ) {
var fogType = new UI.Select().setOptions( {
'None': 'None',
- 'Fog': 'Linear',
- 'FogExp2': 'Exponential'
+ 'RangeFog': 'Ranged',
+ 'DensityFog': 'Density-based'
} ).setWidth( '150px' );
fogType.onChange( function () {
@@ -185,6 +186,11 @@ Sidebar.Scene = function ( editor ) {
var fogDensity = new UI.Number( 0.05 ).setWidth( '40px' ).setRange( 0, 0.1 ).setStep( 0.001 ).setPrecision( 3 ).onChange( onFogChanged );
fogPropertiesRow.add( fogDensity );
+ // fog squared
+
+ var fogSquared = new UI.Checkbox( true ).onChange( onFogChanged );
+ fogPropertiesRow.add( fogSquared );
+
//
function refreshUI() {
@@ -231,16 +237,17 @@ Sidebar.Scene = function ( editor ) {
fogColor.setHexValue( scene.fog.color.getHex() );
- if ( scene.fog.isFog ) {
+ if ( scene.fog.isRangeFog ) {
fogType.setValue( "Fog" );
fogNear.setValue( scene.fog.near );
fogFar.setValue( scene.fog.far );
- } else if ( scene.fog.isFogExp2 ) {
+ } else if ( scene.fog.isDensityFog ) {
- fogType.setValue( "FogExp2" );
+ fogType.setValue( "DensityFog" );
fogDensity.setValue( scene.fog.density );
+ fogSquared.setValue( scene.fog.squared );
}
@@ -259,9 +266,10 @@ Sidebar.Scene = function ( editor ) {
var type = fogType.getValue();
fogPropertiesRow.setDisplay( type === 'None' ? 'none' : '' );
- fogNear.setDisplay( type === 'Fog' ? '' : 'none' );
- fogFar.setDisplay( type === 'Fog' ? '' : 'none' );
- fogDensity.setDisplay( type === 'FogExp2' ? '' : 'none' );
+ fogNear.setDisplay( type === 'RangeFog' ? '' : 'none' );
+ fogFar.setDisplay( type === 'RangeFog' ? '' : 'none' );
+ fogDensity.setDisplay( type === 'DensityFog' ? '' : 'none' );
+ fogSquared.setDisplay( type === 'DensityFog' ? '' : 'none' );
}
diff --git a/editor/js/Viewport.js b/editor/js/Viewport.js
index 085f384042d32e..586536c25bcbe7 100644
--- a/editor/js/Viewport.js
+++ b/editor/js/Viewport.js
@@ -458,7 +458,7 @@ var Viewport = function ( editor ) {
var currentFogType = null;
- signals.sceneFogChanged.add( function ( fogType, fogColor, fogNear, fogFar, fogDensity ) {
+ signals.sceneFogChanged.add( function ( fogType, fogColor, fogNear, fogFar, fogDensity, fogSquared ) {
if ( currentFogType !== fogType ) {
@@ -467,11 +467,11 @@ var Viewport = function ( editor ) {
case 'None':
scene.fog = null;
break;
- case 'Fog':
- scene.fog = new THREE.Fog();
+ case 'RangeFog':
+ scene.fog = new THREE.RangeFog();
break;
- case 'FogExp2':
- scene.fog = new THREE.FogExp2();
+ case 'DensityFog':
+ scene.fog = new THREE.DensityFog();
break;
}
@@ -482,16 +482,17 @@ var Viewport = function ( editor ) {
if ( scene.fog ) {
- if ( scene.fog.isFog ) {
+ if ( scene.fog.isRangeFog ) {
scene.fog.color.setHex( fogColor );
scene.fog.near = fogNear;
scene.fog.far = fogFar;
- } else if ( scene.fog.isFogExp2 ) {
+ } else if ( scene.fog.isDensityFog ) {
scene.fog.color.setHex( fogColor );
scene.fog.density = fogDensity;
+ scene.fog.squared = fogSquared;
}
diff --git a/examples/files.js b/examples/files.js
index 4dc14176b12a86..2da30432a03718 100644
--- a/examples/files.js
+++ b/examples/files.js
@@ -42,6 +42,7 @@ var files = {
"webgl_geometry_teapot",
"webgl_geometry_terrain",
"webgl_geometry_terrain_fog",
+ "webgl_geometry_terrain_fog_types",
"webgl_geometry_terrain_raycast",
"webgl_geometry_text",
"webgl_geometry_text_shapes",
diff --git a/examples/webgl_geometry_terrain_fog_types.html b/examples/webgl_geometry_terrain_fog_types.html
new file mode 100644
index 00000000000000..68f26ac3bb4fa8
--- /dev/null
+++ b/examples/webgl_geometry_terrain_fog_types.html
@@ -0,0 +1,283 @@
+
+
+
+ three.js webgl - fog types
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/webgl_geometry_terrain_fog_types_legacy_test.html b/examples/webgl_geometry_terrain_fog_types_legacy_test.html
new file mode 100644
index 00000000000000..e2ac4016167595
--- /dev/null
+++ b/examples/webgl_geometry_terrain_fog_types_legacy_test.html
@@ -0,0 +1,281 @@
+
+
+
+ three.js webgl - fog types
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/webgl_geometry_terrain_fog_types_lowp_test.html b/examples/webgl_geometry_terrain_fog_types_lowp_test.html
new file mode 100644
index 00000000000000..5d191c5b2a5daf
--- /dev/null
+++ b/examples/webgl_geometry_terrain_fog_types_lowp_test.html
@@ -0,0 +1,282 @@
+
+
+
+ three.js webgl - fog types
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/webgl_geometry_terrain_fog_types_mediump_test.html b/examples/webgl_geometry_terrain_fog_types_mediump_test.html
new file mode 100644
index 00000000000000..ed6e686b3af6db
--- /dev/null
+++ b/examples/webgl_geometry_terrain_fog_types_mediump_test.html
@@ -0,0 +1,282 @@
+
+
+
+ three.js webgl - fog types
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Three.Legacy.js b/src/Three.Legacy.js
index 08557138b288f7..2081418dabdc6e 100644
--- a/src/Three.Legacy.js
+++ b/src/Three.Legacy.js
@@ -80,6 +80,8 @@ import { WebVRManager } from './renderers/webvr/WebVRManager.js';
import { ImageUtils } from './extras/ImageUtils.js';
import { Shape } from './extras/core/Shape.js';
import { CubeCamera } from './cameras/CubeCamera.js';
+import { DensityFog } from './scenes/DensityFog.js';
+import { RangeFog } from './scenes/RangeFog.js';
export { BoxGeometry as CubeGeometry };
@@ -2003,3 +2005,17 @@ export function LensFlare() {
console.error( 'THREE.LensFlare has been moved to /examples/js/objects/Lensflare.js' );
}
+
+export function Fog( color, near, far ) {
+
+ console.warn( 'THREE.Fog has been renamed to THREE.RangeFog.' );
+ return new RangeFog( color, near, far );
+
+}
+
+export function FogExp2( color, density ) {
+
+ console.warn( 'THREE.FogExp2 has been deprecated. Use THREE.DensityFog( color, density, true) instead.' );
+ return new DensityFog( color, density, true );
+
+}
diff --git a/src/Three.d.ts b/src/Three.d.ts
index fc61e25f4633cc..81cf2e4dfcc28c 100644
--- a/src/Three.d.ts
+++ b/src/Three.d.ts
@@ -7,8 +7,8 @@ export * from './renderers/shaders/ShaderLib';
export * from './renderers/shaders/UniformsLib';
export * from './renderers/shaders/UniformsUtils';
export * from './renderers/shaders/ShaderChunk';
-export * from './scenes/FogExp2';
-export * from './scenes/Fog';
+export * from './scenes/RangeFog';
+export * from './scenes/DensityFog';
export * from './scenes/Scene';
export * from './objects/Sprite';
export * from './objects/LOD';
diff --git a/src/Three.js b/src/Three.js
index b95c7128b2b781..cbf8b31a6e0a46 100644
--- a/src/Three.js
+++ b/src/Three.js
@@ -9,8 +9,8 @@ export { ShaderLib } from './renderers/shaders/ShaderLib.js';
export { UniformsLib } from './renderers/shaders/UniformsLib.js';
export { UniformsUtils } from './renderers/shaders/UniformsUtils.js';
export { ShaderChunk } from './renderers/shaders/ShaderChunk.js';
-export { FogExp2 } from './scenes/FogExp2.js';
-export { Fog } from './scenes/Fog.js';
+export { RangeFog } from './scenes/RangeFog.js';
+export { DensityFog } from './scenes/DensityFog.js';
export { Scene } from './scenes/Scene.js';
export { Sprite } from './objects/Sprite.js';
export { LOD } from './objects/LOD.js';
diff --git a/src/loaders/ObjectLoader.js b/src/loaders/ObjectLoader.js
index d2b2afeea56f06..ae15f3c79e00d9 100644
--- a/src/loaders/ObjectLoader.js
+++ b/src/loaders/ObjectLoader.js
@@ -31,8 +31,8 @@ import { LOD } from '../objects/LOD.js';
import { Mesh } from '../objects/Mesh.js';
import { SkinnedMesh } from '../objects/SkinnedMesh.js';
import { Shape } from '../extras/core/Shape.js';
-import { Fog } from '../scenes/Fog.js';
-import { FogExp2 } from '../scenes/FogExp2.js';
+import { RangeFog } from '../scenes/RangeFog.js';
+import { DensityFog } from '../scenes/DensityFog.js';
import { HemisphereLight } from '../lights/HemisphereLight.js';
import { SpotLight } from '../lights/SpotLight.js';
import { PointLight } from '../lights/PointLight.js';
@@ -755,13 +755,15 @@ ObjectLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
if ( data.fog !== undefined ) {
- if ( data.fog.type === 'Fog' ) {
+ //Convert old fog types silently
- object.fog = new Fog( data.fog.color, data.fog.near, data.fog.far );
+ if ( data.fog.type === 'RangeFog' || data.fog.type === 'Fog' ) {
- } else if ( data.fog.type === 'FogExp2' ) {
+ object.fog = new RangeFog( data.fog.color, data.fog.near, data.fog.far );
- object.fog = new FogExp2( data.fog.color, data.fog.density );
+ } else if ( data.fog.type === 'DensityFog' || data.fog.type === 'FogExp2' ) {
+
+ object.fog = new DensityFog( data.fog.color, data.fog.density, data.fog.type === 'FogExp2' ? true : undefined );
}
diff --git a/src/renderers/WebGLRenderer.d.ts b/src/renderers/WebGLRenderer.d.ts
index e487c8d0aafc16..1c21ad31d76cf5 100644
--- a/src/renderers/WebGLRenderer.d.ts
+++ b/src/renderers/WebGLRenderer.d.ts
@@ -13,7 +13,7 @@ import { Color } from './../math/Color';
import { WebGLRenderTarget } from './WebGLRenderTarget';
import { Object3D } from './../core/Object3D';
import { Material } from './../materials/Material';
-import { Fog } from './../scenes/Fog';
+import { IFog } from './../scenes/IFog';
import { ToneMapping, ShadowMapType, CullFace } from '../constants';
import { WebVRManager } from '../renderers/webvr/WebVRManager';
import { RenderTarget } from './webgl/WebGLRenderLists';
@@ -315,7 +315,7 @@ export class WebGLRenderer implements Renderer {
renderBufferDirect(
camera: Camera,
- fog: Fog,
+ fog: IFog,
geometry: Geometry | BufferGeometry,
material: Material,
object: Object3D,
diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js
index 80c08b2c8ffc40..b6c196b2b245aa 100644
--- a/src/renderers/WebGLRenderer.js
+++ b/src/renderers/WebGLRenderer.js
@@ -1680,9 +1680,14 @@ function WebGLRenderer( parameters ) {
material.needsUpdate = true;
- } else if ( material.fog && materialProperties.fog !== fog ) {
+ } else if ( material.fog && ( materialProperties.fog !== fog || ( fog.isDensityFog && fog.needsUpdate ) ) ) {
material.needsUpdate = true;
+ if ( fog.isDensityFog ) {
+
+ fog.needsUpdate = false;
+
+ }
} else if ( material.lights && materialProperties.lightsStateVersion !== lights.state.version ) {
@@ -2215,12 +2220,12 @@ function WebGLRenderer( parameters ) {
uniforms.fogColor.value.copy( fog.color );
- if ( fog.isFog ) {
+ if ( fog.isRangeFog ) {
uniforms.fogNear.value = fog.near;
uniforms.fogFar.value = fog.far;
- } else if ( fog.isFogExp2 ) {
+ } else if ( fog.isDensityFog ) {
uniforms.fogDensity.value = fog.density;
diff --git a/src/renderers/shaders/ShaderChunk/fog_fragment.glsl.js b/src/renderers/shaders/ShaderChunk/fog_fragment.glsl.js
index 996a17e149d156..c7482d7c990d5c 100644
--- a/src/renderers/shaders/ShaderChunk/fog_fragment.glsl.js
+++ b/src/renderers/shaders/ShaderChunk/fog_fragment.glsl.js
@@ -2,12 +2,23 @@ export default /* glsl */`
#ifdef USE_FOG
#ifdef FOG_EXP2
-
- float fogFactor = 1.0 - exp( - fogDensity * fogDensity * fogDepth * fogDepth );
+
+ vec3 scaledFogPosition = fogDensity * fogPosition;
+ float fogFactor = 1.0 - exp( - dot( scaledFogPosition, scaledFogPosition ) );
#else
- float fogFactor = smoothstep( fogNear, fogFar, fogDepth );
+ float fogDepth = precisionSafeLength( fogPosition );
+
+ #ifdef FOG_EXP
+
+ float fogFactor = whiteComplement( exp( - fogDensity * fogDepth ) );
+
+ #else
+
+ float fogFactor = smoothstep( fogNear, fogFar, fogDepth );
+
+ #endif
#endif
diff --git a/src/renderers/shaders/ShaderChunk/fog_pars_fragment.glsl.js b/src/renderers/shaders/ShaderChunk/fog_pars_fragment.glsl.js
index 808c7c55cc222a..5207460468ffe3 100644
--- a/src/renderers/shaders/ShaderChunk/fog_pars_fragment.glsl.js
+++ b/src/renderers/shaders/ShaderChunk/fog_pars_fragment.glsl.js
@@ -2,9 +2,9 @@ export default /* glsl */`
#ifdef USE_FOG
uniform vec3 fogColor;
- varying float fogDepth;
+ varying vec3 fogPosition;
- #ifdef FOG_EXP2
+ #if defined( FOG_EXP ) || defined( FOG_EXP2 )
uniform float fogDensity;
diff --git a/src/renderers/shaders/ShaderChunk/fog_pars_vertex.glsl.js b/src/renderers/shaders/ShaderChunk/fog_pars_vertex.glsl.js
index 284d460f48543b..5e64204c8e8df3 100644
--- a/src/renderers/shaders/ShaderChunk/fog_pars_vertex.glsl.js
+++ b/src/renderers/shaders/ShaderChunk/fog_pars_vertex.glsl.js
@@ -1,7 +1,7 @@
export default /* glsl */`
#ifdef USE_FOG
- varying float fogDepth;
+ varying vec3 fogPosition;
#endif
`;
diff --git a/src/renderers/shaders/ShaderChunk/fog_vertex.glsl.js b/src/renderers/shaders/ShaderChunk/fog_vertex.glsl.js
index ecfc773911a311..0028bcbc19cfb2 100644
--- a/src/renderers/shaders/ShaderChunk/fog_vertex.glsl.js
+++ b/src/renderers/shaders/ShaderChunk/fog_vertex.glsl.js
@@ -1,7 +1,7 @@
export default /* glsl */`
#ifdef USE_FOG
- fogDepth = -mvPosition.z;
+ fogPosition = mvPosition.xyz;
#endif
`;
diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js
index 39e8378dc7f46e..6ec39d7afb96e0 100644
--- a/src/renderers/webgl/WebGLProgram.js
+++ b/src/renderers/webgl/WebGLProgram.js
@@ -448,6 +448,7 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters
'#define MAX_BONES ' + parameters.maxBones,
( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',
+ ( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP' : '',
( parameters.useFog && parameters.fogExp2 ) ? '#define FOG_EXP2' : '',
parameters.map ? '#define USE_MAP' : '',
@@ -585,6 +586,7 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters
'#define GAMMA_FACTOR ' + gammaFactorDefine,
( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',
+ ( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP' : '',
( parameters.useFog && parameters.fogExp2 ) ? '#define FOG_EXP2' : '',
parameters.map ? '#define USE_MAP' : '',
diff --git a/src/renderers/webgl/WebGLPrograms.js b/src/renderers/webgl/WebGLPrograms.js
index f7a08b7c54bee4..4ae1bd497f9d91 100644
--- a/src/renderers/webgl/WebGLPrograms.js
+++ b/src/renderers/webgl/WebGLPrograms.js
@@ -32,7 +32,7 @@ function WebGLPrograms( renderer, extensions, capabilities ) {
"map", "mapEncoding", "matcap", "matcapEncoding", "envMap", "envMapMode", "envMapEncoding",
"lightMap", "aoMap", "emissiveMap", "emissiveMapEncoding", "bumpMap", "normalMap", "objectSpaceNormalMap", "tangentSpaceNormalMap", "clearcoatNormalMap", "displacementMap", "specularMap",
"roughnessMap", "metalnessMap", "gradientMap",
- "alphaMap", "combine", "vertexColors", "vertexTangents", "fog", "useFog", "fogExp2",
+ "alphaMap", "combine", "vertexColors", "vertexTangents", "fog", "useFog", "fogExp", "fogExp2",
"flatShading", "sizeAttenuation", "logarithmicDepthBuffer", "skinning",
"maxBones", "useVertexTexture", "morphTargets", "morphNormals",
"maxMorphTargets", "maxMorphNormals", "premultipliedAlpha",
@@ -180,7 +180,8 @@ function WebGLPrograms( renderer, extensions, capabilities ) {
fog: !! fog,
useFog: material.fog,
- fogExp2: ( fog && fog.isFogExp2 ),
+ fogExp: ( fog && fog.isDensityFog && ! fog.squared ),
+ fogExp2: ( fog && fog.isDensityFog && fog.squared ),
flatShading: material.flatShading,
diff --git a/src/scenes/DensityFog.d.ts b/src/scenes/DensityFog.d.ts
new file mode 100644
index 00000000000000..e031bd52fe8835
--- /dev/null
+++ b/src/scenes/DensityFog.d.ts
@@ -0,0 +1,28 @@
+import { Color } from './../math/Color';
+import { IFog } from './IFog';
+/**
+ * This class contains the parameters that define density-based fog.
+ */
+export class DensityFog implements IFog {
+
+ constructor( hex: number | string, density?: number, squared?: boolean );
+
+ name: string;
+ color: Color;
+
+ /**
+ * Defines how fast the fog will grow dense.
+ * Default is 0.00025.
+ */
+ density: number;
+
+ /**
+ * If false, the mode will be exponential fog, which is analogous to physical fog. If true, the mode will be exponential squared fog, which gives a clear view near the camera and a faster than exponentially densening fog farther from the camera.
+ * Default is true, that is exponential squared fog.
+ */
+ squared: boolean;
+
+ clone(): this;
+ toJSON(): any;
+
+}
diff --git a/src/scenes/DensityFog.js b/src/scenes/DensityFog.js
new file mode 100644
index 00000000000000..21ad0c9afe3682
--- /dev/null
+++ b/src/scenes/DensityFog.js
@@ -0,0 +1,62 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ * @author alteredq / http://alteredqualia.com/
+ * @author EliasHasle / http://eliashasle.github.io/
+ */
+
+import { Color } from '../math/Color.js';
+
+function DensityFog( color, density, squared ) {
+
+ this.name = '';
+
+ this.color = new Color( color );
+ this.density = ( density !== undefined ) ? density : 0.00025;
+
+ this.needsUpdate = false;
+ squared = squared !== undefined ? squared : true;
+
+ Object.defineProperty( this, "squared", {
+
+ get() {
+
+ return squared;
+
+ },
+
+ set( value ) {
+
+ squared = value;
+ this.needsUpdate = true;
+
+ }
+
+ } );
+
+ this.squared = squared;
+
+}
+
+Object.assign( DensityFog.prototype, {
+
+ isDensityFog: true,
+
+ clone: function () {
+
+ return new DensityFog( this.color, this.density, this.squared );
+
+ },
+
+ toJSON: function ( /* meta */ ) {
+
+ return {
+ type: 'DensityFog',
+ color: this.color.getHex(),
+ density: this.density
+ };
+
+ }
+
+} );
+
+export { DensityFog };
diff --git a/src/scenes/FogExp2.d.ts b/src/scenes/FogExp2.d.ts
deleted file mode 100644
index b9897b29d9a33b..00000000000000
--- a/src/scenes/FogExp2.d.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import { Color } from './../math/Color';
-import { IFog } from './Fog';
-/**
- * This class contains the parameters that define linear fog, i.e., that grows exponentially denser with the distance.
- */
-export class FogExp2 implements IFog {
-
- constructor( hex: number | string, density?: number );
-
- name: string;
- color: Color;
-
- /**
- * Defines how fast the fog will grow dense.
- * Default is 0.00025.
- */
- density: number;
-
- clone(): this;
- toJSON(): any;
-
-}
diff --git a/src/scenes/FogExp2.js b/src/scenes/FogExp2.js
deleted file mode 100644
index 526e06446f176d..00000000000000
--- a/src/scenes/FogExp2.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * @author mrdoob / http://mrdoob.com/
- * @author alteredq / http://alteredqualia.com/
- */
-
-import { Color } from '../math/Color.js';
-
-function FogExp2( color, density ) {
-
- this.name = '';
-
- this.color = new Color( color );
- this.density = ( density !== undefined ) ? density : 0.00025;
-
-}
-
-Object.assign( FogExp2.prototype, {
-
- isFogExp2: true,
-
- clone: function () {
-
- return new FogExp2( this.color, this.density );
-
- },
-
- toJSON: function ( /* meta */ ) {
-
- return {
- type: 'FogExp2',
- color: this.color.getHex(),
- density: this.density
- };
-
- }
-
-} );
-
-export { FogExp2 };
diff --git a/src/scenes/IFog.d.ts b/src/scenes/IFog.d.ts
new file mode 100644
index 00000000000000..6faa07f9716847
--- /dev/null
+++ b/src/scenes/IFog.d.ts
@@ -0,0 +1,8 @@
+import { Color } from './../math/Color';
+
+export interface IFog {
+ name: string;
+ color: Color;
+ clone(): this;
+ toJSON(): any;
+}
diff --git a/src/scenes/Fog.d.ts b/src/scenes/RangeFog.d.ts
similarity index 70%
rename from src/scenes/Fog.d.ts
rename to src/scenes/RangeFog.d.ts
index e992d145b75417..166a6f91208175 100644
--- a/src/scenes/Fog.d.ts
+++ b/src/scenes/RangeFog.d.ts
@@ -1,16 +1,10 @@
import { Color } from './../math/Color';
-
-export interface IFog {
- name: string;
- color: Color;
- clone(): this;
- toJSON(): any;
-}
+import { IFog } from './IFog';
/**
- * This class contains the parameters that define linear fog, i.e., that grows linearly denser with the distance.
+ * This class contains the parameters that define smooth ranged fog, i.e., that grows smoothly denser from the near to the far distance.
*/
-export class Fog implements IFog {
+export class RangeFog implements IFog {
constructor( hex: number, near?: number, far?: number );
diff --git a/src/scenes/Fog.js b/src/scenes/RangeFog.js
similarity index 69%
rename from src/scenes/Fog.js
rename to src/scenes/RangeFog.js
index 2bcdfeff26188e..c42db6ce2649e1 100644
--- a/src/scenes/Fog.js
+++ b/src/scenes/RangeFog.js
@@ -5,7 +5,7 @@
import { Color } from '../math/Color.js';
-function Fog( color, near, far ) {
+function RangeFog( color, near, far ) {
this.name = '';
@@ -16,20 +16,20 @@ function Fog( color, near, far ) {
}
-Object.assign( Fog.prototype, {
+Object.assign( RangeFog.prototype, {
- isFog: true,
+ isRangeFog: true,
clone: function () {
- return new Fog( this.color, this.near, this.far );
+ return new RangeFog( this.color, this.near, this.far );
},
toJSON: function ( /* meta */ ) {
return {
- type: 'Fog',
+ type: 'RangeFog',
color: this.color.getHex(),
near: this.near,
far: this.far
@@ -39,4 +39,4 @@ Object.assign( Fog.prototype, {
} );
-export { Fog };
+export { RangeFog };
diff --git a/src/scenes/Scene.d.ts b/src/scenes/Scene.d.ts
index 1e776724c9bc1d..af2148ec8eb392 100644
--- a/src/scenes/Scene.d.ts
+++ b/src/scenes/Scene.d.ts
@@ -1,4 +1,4 @@
-import { IFog } from './Fog';
+import { IFog } from './IFog';
import { Material } from './../materials/Material';
import { Object3D } from './../core/Object3D';
import { Color } from '../math/Color';
diff --git a/test/three.source.unit.js b/test/three.source.unit.js
index 7ef2c85dbeb820..a203336d3520f5 100644
--- a/test/three.source.unit.js
+++ b/test/three.source.unit.js
@@ -272,8 +272,8 @@ import './unit/src/renderers/webvr/WebVRManager.tests';
//src/scenes
-import './unit/src/scenes/Fog.tests';
-import './unit/src/scenes/FogExp2.tests';
+import './unit/src/scenes/RangeFog.tests';
+import './unit/src/scenes/DensityFog.tests';
import './unit/src/scenes/Scene.tests';
diff --git a/test/unit/src/scenes/Fog.tests.js b/test/unit/src/scenes/DensityFog.tests.js
similarity index 80%
rename from test/unit/src/scenes/Fog.tests.js
rename to test/unit/src/scenes/DensityFog.tests.js
index c4376c1662b176..12a0c77fdd0d34 100644
--- a/test/unit/src/scenes/Fog.tests.js
+++ b/test/unit/src/scenes/DensityFog.tests.js
@@ -3,9 +3,9 @@
*/
/* global QUnit */
-import { Fog } from '../../../../src/scenes/Fog';
+import { DensityFog } from '../../../../src/scenes/DensityFog';
-export default QUnit.module( 'Fog', () => {
+export default QUnit.module( 'DensityFog', () => {
QUnit.module( 'Scene', () => {
@@ -24,7 +24,7 @@ export default QUnit.module( 'Fog', () => {
} );
// PUBLIC STUFF
- QUnit.todo( "isFog", ( assert ) => {
+ QUnit.todo( "isDensityFog", ( assert ) => {
assert.ok( false, "everything's gonna be alright" );
diff --git a/test/unit/src/scenes/FogExp2.tests.js b/test/unit/src/scenes/RangeFog.tests.js
similarity index 81%
rename from test/unit/src/scenes/FogExp2.tests.js
rename to test/unit/src/scenes/RangeFog.tests.js
index 2fcaeb5ebecdd4..e412e733ae9f2b 100644
--- a/test/unit/src/scenes/FogExp2.tests.js
+++ b/test/unit/src/scenes/RangeFog.tests.js
@@ -3,9 +3,9 @@
*/
/* global QUnit */
-import { FogExp2 } from '../../../../src/scenes/FogExp2';
+import { RangeFog } from '../../../../src/scenes/RangeFog';
-export default QUnit.module( 'FoxExp2', () => {
+export default QUnit.module( 'RangeFog', () => {
QUnit.module( 'Scene', () => {
@@ -24,7 +24,7 @@ export default QUnit.module( 'FoxExp2', () => {
} );
// PUBLIC STUFF
- QUnit.todo( "isFogExp2", ( assert ) => {
+ QUnit.todo( "isRangeFog", ( assert ) => {
assert.ok( false, "everything's gonna be alright" );