All files / engine/Source/Scene Fog.js

88.57% Statements 31/35
63.63% Branches 7/11
50% Functions 2/4
88.57% Lines 31/35

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167                                                733x                     733x                         733x           733x 733x           733x                     733x                 733x             733x     1x                                               1x           1x 11967x 11967x 255x     11712x   11712x 11712x     11712x         2605x 2605x 2605x     9107x   9107x               9107x       9107x 9107x   9107x 9107x 9107x 9107x      
import Cartesian3 from "../Core/Cartesian3.js";
import defined from "../Core/defined.js";
import DeveloperError from "../Core/DeveloperError.js";
import CesiumMath from "../Core/Math.js";
import SceneMode from "./SceneMode.js";
 
/**
 * Blends the atmosphere to geometry far from the camera for horizon views. Allows for additional
 * performance improvements by rendering less geometry and dispatching less terrain requests.
 *
 * @demo {@link https://sandcastle.cesium.com/index.html?src=Fog.html|Cesium Sandcastle Fog Demo}
 *
 * @alias Fog
 * @constructor
 */
function Fog() {
  /**
   * <code>true</code> if fog is enabled, <code>false</code> otherwise.
   * @type {boolean}
   * @default true
   * @example
   * // Disable fog in the scene
   * viewer.scene.fog.enabled = false;
   */
  this.enabled = true;
  /**
   * <code>true</code> if fog is renderable in shaders, <code>false</code> otherwise.
   * This allows to benefits from optimized tile loading strategy based on fog density without the actual visual rendering.
   * @type {boolean}
   * @default true
   * @example
   * // Use fog culling but don't render it
   * viewer.scene.fog.enabled = true;
   * viewer.scene.fog.renderable = false;
   */
  this.renderable = true;
  /**
   * A scalar that determines the density of the fog. Terrain that is in full fog are culled.
   * The density of the fog increases as this number approaches 1.0 and becomes less dense as it approaches zero.
   * The more dense the fog is, the more aggressively the terrain is culled. For example, if the camera is a height of
   * 1000.0m above the ellipsoid, increasing the value to 3.0e-3 will cause many tiles close to the viewer be culled.
   * Decreasing the value will push the fog further from the viewer, but decrease performance as more of the terrain is rendered.
   * @type {number}
   * @default 0.0006
   * @example
   * // Double the default fog density
   * viewer.scene.fog.density = 0.0012;
   */
  this.density = 0.0006;
  /**
   * A scalar used in the function to adjust density based on the height of the camera above the terrain.
   * @type {number}
   * @default 0.001
   */
  this.heightScalar = 0.001;
  this._heightFalloff = 0.59;
  /**
   * The maximum height fog is applied. If the camera is above this height fog will be disabled.
   * @type {number}
   * @default 800000.0
   */
  this.maxHeight = 800000.0;
  /**
   * A scalar that impacts the visual density of fog. This value does not impact the culling of terrain.
   * Use in combination with the {@link Fog.density} to make fog appear more or less dense.
   * @type {number}
   * @default 0.15
   * @experimental The value of this scalar may not be final and is subject to change.
   * @example
   * // Increase fog appearance effect
   * viewer.scene.fog.visualDensityScalar = 0.6;
   */
  this.visualDensityScalar = 0.15;
  /**
   * A factor used to increase the screen space error of terrain tiles when they are partially in fog. The effect is to reduce
   * the number of terrain tiles requested for rendering. If set to zero, the feature will be disabled. If the value is increased
   * for mountainous regions, less tiles will need to be requested, but the terrain meshes near the horizon may be a noticeably
   * lower resolution. If the value is increased in a relatively flat area, there will be little noticeable change on the horizon.
   * @type {number}
   * @default 2.0
   */
  this.screenSpaceErrorFactor = 2.0;
  /**
   * The minimum brightness of the fog color from lighting. A value of 0.0 can cause the fog to be completely black. A value of 1.0 will not affect
   * the brightness at all.
   * @type {number}
   * @default 0.03
   */
  this.minimumBrightness = 0.03;
}
 
Object.defineProperties(Fog.prototype, {
  /**
   * Exponent factor used in the function to adjust how density changes based on the height of the camera above the ellipsoid. Smaller values produce a more gradual transition as camera height increases.
   * Value must be greater than 0.
   * @memberof Fog.prototype
   * @type {number}
   * @default 0.59
   */
  heightFalloff: {
    get: function () {
      return this._heightFalloff;
    },
    set: function (value) {
      //>>includeStart('debug', pragmas.debug);
      if (defined(value) && value < 0) {
        throw new DeveloperError("value must be positive.");
      }
      //>>includeEnd('debug');
 
      this._heightFalloff = value;
    },
  },
});
 
const scratchPositionNormal = new Cartesian3();
 
/**
 * @param {FrameState} frameState
 * @private
 */
Fog.prototype.update = function (frameState) {
  const enabled = (frameState.fog.enabled = this.enabled);
  if (!enabled) {
    return;
  }
 
  frameState.fog.renderable = this.renderable;
 
  const camera = frameState.camera;
  const positionCartographic = camera.positionCartographic;
 
  // Turn off fog in space.
  if (
    !defined(positionCartographic) ||
    positionCartographic.height > this.maxHeight ||
    frameState.mode !== SceneMode.SCENE3D
  ) {
    frameState.fog.enabled = false;
    frameState.fog.density = 0;
    return;
  }
 
  const height = positionCartographic.height;
  let density =
    this.density *
    this.heightScalar *
    Math.pow(
      Math.max(height / this.maxHeight, CesiumMath.EPSILON4),
      -Math.max(this._heightFalloff, 0.0),
    );
 
  // Fade fog in as the camera tilts toward the horizon.
  const positionNormal = Cartesian3.normalize(
    camera.positionWC,
    scratchPositionNormal,
  );
  const dot = Math.abs(Cartesian3.dot(camera.directionWC, positionNormal));
  density *= 1.0 - dot;
 
  frameState.fog.density = density;
  frameState.fog.visualDensityScalar = this.visualDensityScalar;
  frameState.fog.sse = this.screenSpaceErrorFactor;
  frameState.fog.minimumBrightness = this.minimumBrightness;
};
export default Fog;