From 5eddba22a629ad71a87480056e416643e7dfd112 Mon Sep 17 00:00:00 2001 From: Elias Hasle Date: Mon, 26 Aug 2019 14:20:48 +0200 Subject: [PATCH] RangeFog(color, near, far) and DensityFog(color, density, squared) Added fog types example. Currently includes some extra examples that show functionality of legacy signatures, and mediump and lowp operation for all fog types. Includes the change to distance-based depth, as well as corrections to better support mediump. Makes #17316 and #17324 obsolete. Force update when squared is changed. Fix legacy example and mediump example Attempted fixes for editor Formatting + typos Fixed TS declarations (Not sure I am using IFog right) --- .../scenes/{FogExp2.html => DensityFog.html} | 16 +- .../api/en/scenes/{Fog.html => RangeFog.html} | 6 +- docs/api/zh/scenes/DensityFog.html | 55 ++++ docs/api/zh/scenes/FogExp2.html | 47 --- .../api/zh/scenes/{Fog.html => RangeFog.html} | 9 +- docs/list.js | 8 +- editor/js/Sidebar.Scene.js | 26 +- editor/js/Viewport.js | 15 +- examples/files.js | 1 + .../webgl_geometry_terrain_fog_types.html | 283 ++++++++++++++++++ ...eometry_terrain_fog_types_legacy_test.html | 281 +++++++++++++++++ ..._geometry_terrain_fog_types_lowp_test.html | 282 +++++++++++++++++ ...ometry_terrain_fog_types_mediump_test.html | 282 +++++++++++++++++ src/Three.Legacy.js | 16 + src/Three.d.ts | 4 +- src/Three.js | 4 +- src/loaders/ObjectLoader.js | 14 +- src/renderers/WebGLRenderer.d.ts | 4 +- src/renderers/WebGLRenderer.js | 11 +- .../shaders/ShaderChunk/fog_fragment.glsl.js | 17 +- .../ShaderChunk/fog_pars_fragment.glsl.js | 4 +- .../ShaderChunk/fog_pars_vertex.glsl.js | 2 +- .../shaders/ShaderChunk/fog_vertex.glsl.js | 2 +- src/renderers/webgl/WebGLProgram.js | 2 + src/renderers/webgl/WebGLPrograms.js | 5 +- src/scenes/DensityFog.d.ts | 28 ++ src/scenes/DensityFog.js | 62 ++++ src/scenes/FogExp2.d.ts | 22 -- src/scenes/FogExp2.js | 39 --- src/scenes/IFog.d.ts | 8 + src/scenes/{Fog.d.ts => RangeFog.d.ts} | 12 +- src/scenes/{Fog.js => RangeFog.js} | 12 +- src/scenes/Scene.d.ts | 2 +- test/three.source.unit.js | 4 +- .../{Fog.tests.js => DensityFog.tests.js} | 6 +- .../{FogExp2.tests.js => RangeFog.tests.js} | 6 +- 36 files changed, 1408 insertions(+), 189 deletions(-) rename docs/api/en/scenes/{FogExp2.html => DensityFog.html} (60%) rename docs/api/en/scenes/{Fog.html => RangeFog.html} (90%) create mode 100644 docs/api/zh/scenes/DensityFog.html delete mode 100644 docs/api/zh/scenes/FogExp2.html rename docs/api/zh/scenes/{Fog.html => RangeFog.html} (83%) create mode 100644 examples/webgl_geometry_terrain_fog_types.html create mode 100644 examples/webgl_geometry_terrain_fog_types_legacy_test.html create mode 100644 examples/webgl_geometry_terrain_fog_types_lowp_test.html create mode 100644 examples/webgl_geometry_terrain_fog_types_mediump_test.html create mode 100644 src/scenes/DensityFog.d.ts create mode 100644 src/scenes/DensityFog.js delete mode 100644 src/scenes/FogExp2.d.ts delete mode 100644 src/scenes/FogExp2.js create mode 100644 src/scenes/IFog.d.ts rename src/scenes/{Fog.d.ts => RangeFog.d.ts} (70%) rename src/scenes/{Fog.js => RangeFog.js} (69%) rename test/unit/src/scenes/{Fog.tests.js => DensityFog.tests.js} (80%) rename test/unit/src/scenes/{FogExp2.tests.js => RangeFog.tests.js} (81%) 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 + + + + + + + +
+
three.js - webgl terrain + 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 + + + + + + + +
+
three.js - webgl terrain + 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 + + + + + + + +
+
three.js - webgl terrain + 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 + + + + + + + +
+
three.js - webgl terrain + 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" );