Skip to content

Commit

Permalink
Remove haze (#10613)
Browse files Browse the repository at this point in the history
* Remove haze

* Remove density

* Catch a couple more small cleanup items

* Fix broken shader

* Tighten/restore fog culling

* Update src/render/painter.js
  • Loading branch information
rreusser authored and karimnaaji committed May 4, 2021
1 parent 776af54 commit 414085b
Show file tree
Hide file tree
Showing 17 changed files with 15 additions and 308 deletions.
28 changes: 0 additions & 28 deletions debug/fog.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@
this.start = 2;
this.end = 12.0;
this.color = [255, 255, 255];
this.hazeColor = [109, 123, 180];
this.hazeOpacity = 0.5;
this.density = 1.0;
this.horizonBlend = 0.1;
this.showTileBoundaries = false;
};
Expand Down Expand Up @@ -103,8 +100,6 @@
map.setFog(value ? {
"range": [guiParams.start, guiParams.end],
"color": 'rgba(' + guiParams.color[0] + ', ' + guiParams.color[1] + ', ' + guiParams.color[2] + ', 1.0)',
"haze-color": 'rgba(' + guiParams.hazeColor[0] + ', ' + guiParams.hazeColor[1] + ', ' + guiParams.hazeColor[2] + ', ' + guiParams.hazeOpacity + ')',
"density": guiParams.density,
"horizon-blend": guiParams.horizonBlend
} : null);
});
Expand All @@ -123,13 +118,6 @@
});
});

var density = fog.add(guiParams, 'density', 0, 1);
density.onChange((value) => {
map.setFog({
"density": value,
});
});

var horizonBlend = fog.add(guiParams, 'horizonBlend', 0.0, 1.0);
horizonBlend.onChange((value) => {
map.setFog({
Expand All @@ -143,20 +131,6 @@
"color": 'rgba(' + value[0] + ', ' + value[1] + ', ' + value[2] + ', 1.0)',
});
});

var hazeColor = fog.addColor(guiParams, 'hazeColor');
hazeColor.onChange((value) => {
map.setFog({
"haze-color": 'rgba(' + value[0] + ', ' + value[1] + ', ' + value[2] + ', ' + guiParams.hazeOpacity + ')',
});
});

var hazeOpacity = fog.add(guiParams, 'hazeOpacity', 0, 1);
hazeOpacity.onChange((value) => {
map.setFog({
"haze-color": 'rgba(' + guiParams.hazeColor[0] + ', ' + guiParams.hazeColor[1] + ', ' + guiParams.hazeColor[2] + ', ' + guiParams.hazeOpacity + ')',
});
});
};

var popup = new mapboxgl.Popup().setHTML('Pitch Alignment: auto<br>Rotation Alignment: auto');
Expand Down Expand Up @@ -216,8 +190,6 @@
map.setFog(guiParams.enableFog ? {
"range": [guiParams.start, guiParams.end],
"color": 'rgba(' + guiParams.color[0] + ', ' + guiParams.color[1] + ', ' + guiParams.color[2] + ', 1.0)',
"haze-color": 'rgba(' + guiParams.hazeColor[0] + ', ' + guiParams.hazeColor[1] + ', ' + guiParams.hazeColor[2] + ', ' + guiParams.hazeOpacity + ')',
"density": guiParams.density,
"horizon-blend": guiParams.horizonBlend
} : null);

Expand Down
7 changes: 0 additions & 7 deletions src/render/fog.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,8 @@ export type FogUniformsType = {|
'u_fog_matrix': UniformMatrix4f,
'u_fog_range': Uniform2f,
'u_fog_color': Uniform3f,
'u_fog_exponent': Uniform1f,
'u_fog_horizon_blend': Uniform1f,
'u_fog_temporal_offset': Uniform1f,
'u_haze_color_linear': Uniform3f,

// Precision may differ, so we must pass uniforms separately for use in a vertex shader
'u_fog_opacity': Uniform1f,

|};
Expand All @@ -23,10 +19,7 @@ export const fogUniforms = (context: Context, locations: UniformLocations): FogU
'u_fog_matrix': new UniformMatrix4f(context, locations.u_fog_matrix),
'u_fog_range': new Uniform2f(context, locations.u_fog_range),
'u_fog_color': new Uniform3f(context, locations.u_fog_color),
'u_fog_exponent': new Uniform1f(context, locations.u_fog_exponent),
'u_fog_horizon_blend': new Uniform1f(context, locations.u_fog_horizon_blend),
'u_fog_temporal_offset': new Uniform1f(context, locations.u_fog_temporal_offset),
'u_haze_color_linear': new Uniform3f(context, locations.u_haze_color_linear),

'u_fog_opacity': new Uniform1f(context, locations.u_fog_opacity),
});
27 changes: 4 additions & 23 deletions src/render/painter.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,11 +188,10 @@ class Painter {
const fog = this.style.fog;
const fogStart = fog.properties.get('range')[0];
const fogEnd = fog.properties.get('range')[1];
const fogDensity = fog.properties.get('density');

// We start culling where the fog opacity function hits 98%, leaving
// a non-noticeable opacity change threshold. We use an arbitrary function
// which bounds the true answer. See: https://www.desmos.com/calculator/lw03ldsuhy
const fogBoundFraction = 1 - 0.22 * Math.exp(4 * (fogDensity - 1));
// a non-noticeable opacity change threshold.
const fogBoundFraction = 0.78;
const fogCullDist = fogStart + (fogEnd - fogStart) * fogBoundFraction;

this.transform.fogCullDistSq = fogCullDist * fogCullDist;
Expand Down Expand Up @@ -755,16 +754,12 @@ class Painter {
const rtt = this.terrain && this.terrain.renderingToTexture;
const fog = this.style && this.style.fog;
const fogOpacity = fog && fog.getFogPitchFactor(this.transform.pitch);
const haze = fog && fog.properties && fog.properties.get('haze-color').a > 0;

const defines = [];
if (terrain) defines.push('TERRAIN');
// When terrain is active, fog is rendered as part of draping, not as part of tile
// rendering. Removing the fog flag during tile rendering avoids additional defines.
if (fog && fogOpacity !== 0.0 && !rtt) {
defines.push('FOG');
if (haze) defines.push('FOG_HAZE');
}
if (fog && fogOpacity !== 0.0 && !rtt) defines.push('FOG');
if (rtt) defines.push('RENDER_TO_TEXTURE');
if (this._showOverdrawInspector) defines.push('OVERDRAW_INSPECTOR');
return defines;
Expand Down Expand Up @@ -857,24 +852,10 @@ class Painter {
uniforms['u_fog_matrix'] = tileID ? this.transform.calculateFogTileMatrix(tileID) : this.identityMat;
uniforms['u_fog_range'] = fog.properties.get('range');
uniforms['u_fog_color'] = fogColorUnpremultiplied;
uniforms['u_fog_exponent'] = Math.max(1e-3, 12 * Math.pow(1 - fog.properties.get('density'), 2));
uniforms['u_fog_horizon_blend'] = fog.properties.get('horizon-blend');
uniforms['u_fog_temporal_offset'] = temporalOffset;
uniforms['u_fog_opacity'] = fogOpacity;

if (fog.properties.get('haze-color').a > 0) {
const hazeColor = fog.properties.get('haze-color');
const hazeBaseAmpl = 5;
// Since there's no significant difference in visual effect, we use approximate
// sRGB -> linear RGB conversion with a power of 2 instead of 2.2 in order to
// avoid pow() functions in the shader.
uniforms['u_haze_color_linear'] = [
hazeBaseAmpl * Math.pow(hazeColor.r, 2),
hazeBaseAmpl * Math.pow(hazeColor.g, 2),
hazeBaseAmpl * Math.pow(hazeColor.b, 2),
];
}

program.setFogUniformValues(context, uniforms);
}
}
Expand Down
7 changes: 3 additions & 4 deletions src/shaders/_prelude.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ uniform mediump vec2 u_fog_range;
uniform mediump float u_fog_horizon_blend;

float fog_range(float depth) {
// Map [near, far] to [0, 1]
// Map [near, far] to [0, 1] without clamping
return (depth - u_fog_range[0]) / (u_fog_range[1] - u_fog_range[0]);
}

Expand All @@ -25,16 +25,15 @@ float fog_horizon_blending(vec3 camera_dir) {
return u_fog_opacity * exp(-3.0 * t * t);
}

// Computes the fog opacity when fog strength = 1. Otherwise it's multiplied
// by a smoothstep to a power to decrease the amount of fog relative to haze.
// Compute a ramp for fog opacity
// - t: depth, rescaled to 0 at fogStart and 1 at fogEnd
// See: https://www.desmos.com/calculator/3taufutxid
// This function much match src/style/fog.js and _prelude_fog.vertex.glsl
float fog_opacity(float t) {
const float decay = 6.0;
float falloff = 1.0 - min(1.0, exp(-decay * t));

// Cube without pow()
// Cube without pow() to smooth the onset
falloff *= falloff * falloff;

// Scale and clip to 1 at the far limit
Expand Down
32 changes: 3 additions & 29 deletions src/shaders/_prelude_fog.fragment.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -2,49 +2,23 @@

uniform vec3 u_fog_color;
uniform float u_fog_temporal_offset;
uniform mediump vec3 u_haze_color_linear;
uniform mediump float u_fog_exponent;

// This function is only used in rare places like heatmap where opacity is used
// directly, outside the normal fog_apply method.
float fog_opacity(vec3 pos) {
return fog_opacity(fog_range(length(pos)));
}

// This function applies haze to an input color using an approximation of the following algorithm:
// 1. convert color from sRGB to linear RGB
// 2. add haze (presuming haze is in linear RGB)
// 3. tone-map the output
// 4. convert the result back to sRGB
// The equation below is based on a curve fit of the above algorithm, with the additional approximation
// during linear-srgb conversion that gamma=2, in order to avoid transcendental function evaluations
// which don't affect the visual quality.
vec3 haze_apply(vec3 color, vec3 haze) {
vec3 color2 = color * color;
return sqrt((color2 + haze) / (1.0 + color2 * color * haze));
}

vec3 fog_apply(vec3 color, vec3 pos) {
float depth = length(pos);
float t = fog_range(depth);

float haze_opac = fog_opacity(t);
float fog_opac = haze_opac * pow(smoothstep(0.0, 1.0, t), u_fog_exponent);
fog_opac *= fog_horizon_blending(pos / depth);

#ifdef FOG_HAZE
color = haze_apply(color, haze_opac * u_haze_color_linear);
#endif
float fog_opac = fog_opacity(t) * fog_horizon_blending(pos / depth);

return mix(color, u_fog_color, fog_opac);
}

// Apply fog and haze which were computed in the vertex shader
vec3 fog_apply_from_vert(vec3 color, float fog_opac, vec3 haze) {
#ifdef FOG_HAZE
color = haze_apply(color, haze);
#endif

// Apply fog computed in the vertex shader
vec3 fog_apply_from_vert(vec3 color, float fog_opac) {
return mix(color, u_fog_color, fog_opac);
}

Expand Down
14 changes: 3 additions & 11 deletions src/shaders/_prelude_fog.vertex.glsl
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#ifdef FOG

uniform mat4 u_fog_matrix;
uniform mediump float u_fog_exponent;
uniform mediump vec3 u_haze_color_linear;

vec3 fog_position(vec3 pos) {
// The following function requires that u_fog_matrix be affine and result in
Expand All @@ -15,16 +13,10 @@ vec3 fog_position(vec2 pos) {
return fog_position(vec3(pos, 0));
}

void fog(vec3 pos, out float fog_opac, out vec3 haze) {
float fog(vec3 pos) {
float depth = length(pos);
float t = fog_range(depth);
float haze_opac = fog_opacity(t);
fog_opac = haze_opac * pow(smoothstep(0.0, 1.0, t), u_fog_exponent);
fog_opac *= fog_horizon_blending(pos / depth);

#ifdef FOG_HAZE
haze.rgb = haze_opac * u_haze_color_linear;
#endif
float opacity = fog_opacity(fog_range(depth));
return opacity * fog_horizon_blending(pos / depth);
}

#endif
10 changes: 1 addition & 9 deletions src/shaders/terrain_raster.fragment.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,12 @@ varying vec2 v_pos0;

#ifdef FOG
varying float v_fog_opacity;
#ifdef FOG_HAZE
varying vec3 v_haze_color;
#endif
#endif

void main() {
vec4 color = texture2D(u_image0, v_pos0);
#ifdef FOG
#ifdef FOG_HAZE
color.rgb = fog_dither(fog_apply_from_vert(color.rgb, v_fog_opacity, v_haze_color));
#else
vec3 unused;
color.rgb = fog_dither(fog_apply_from_vert(color.rgb, v_fog_opacity, unused));
#endif
color.rgb = fog_dither(fog_apply_from_vert(color.rgb, v_fog_opacity));
#endif
gl_FragColor = color;
#ifdef TERRAIN_WIREFRAME
Expand Down
10 changes: 1 addition & 9 deletions src/shaders/terrain_raster.vertex.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ varying vec2 v_pos0;

#ifdef FOG
varying float v_fog_opacity;
#ifdef FOG_HAZE
varying vec3 v_haze_color;
#endif
#endif

const float skirtOffset = 24575.0;
Expand All @@ -27,11 +24,6 @@ void main() {
gl_Position = u_matrix * vec4(decodedPos, elevation, 1.0);

#ifdef FOG
#ifdef FOG_HAZE
fog(fog_position(vec3(decodedPos, elevation)), v_fog_opacity, v_haze_color);
#else
vec3 unused;
fog(fog_position(vec3(decodedPos, elevation)), v_fog_opacity, unused);
#endif
v_fog_opacity = fog(fog_position(vec3(decodedPos, elevation)));
#endif
}
37 changes: 0 additions & 37 deletions src/style-spec/reference/v8.json
Original file line number Diff line number Diff line change
Expand Up @@ -3725,43 +3725,6 @@
}
}
},
"density": {
"type": "number",
"property-type": "data-constant",
"default": 1.0,
"minimum": 0.0,
"expression": {
"interpolated": true,
"parameters": [
"zoom"
]
},
"transition": true,
"doc": "Controls the strength of fog within the fog range. Reducing the density pushes the fog farther toward the horizon, leaving more visible space for haze, if enabled. When haze opacity is zero, density will usually be 1.0.",
"sdk-support": {
"basic functionality": {
"js": "2.3.0"
}
}
},
"haze-color": {
"type": "color",
"property-type": "data-constant",
"default": "rgba(114,135,213,0)",
"expression": {
"interpolated": true,
"parameters": [
"zoom"
]
},
"transition": true,
"doc": "The color of the haze component of fog. Alpha adjusts the amount of haze. Note that haze is disabled by default (zero alpha); increase this value to enable the effect.",
"sdk-support": {
"basic functionality": {
"js": "2.3.0"
}
}
},
"horizon-blend": {
"type": "number",
"property-type": "data-constant",
Expand Down
2 changes: 0 additions & 2 deletions src/style-spec/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,6 @@ export type TerrainSpecification = {|
export type FogSpecification = {|
"range"?: PropertyValueSpecification<[number, number]>,
"color"?: PropertyValueSpecification<ColorSpecification>,
"density"?: PropertyValueSpecification<number>,
"haze-color"?: PropertyValueSpecification<ColorSpecification>,
"horizon-blend"?: PropertyValueSpecification<number>
|}

Expand Down
5 changes: 0 additions & 5 deletions src/style/fog.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,12 @@ import type {FogState} from './fog_helpers.js';
type Props = {|
"range": DataConstantProperty<[number, number]>,
"color": DataConstantProperty<Color>,
"density": DataConstantProperty<number>,
"haze-color": DataConstantProperty<Color>,
"horizon-blend": DataConstantProperty<number>,
|};

const fogProperties: Properties<Props> = new Properties({
"range": new DataConstantProperty(styleSpec.fog.range),
"color": new DataConstantProperty(styleSpec.fog.color),
"density": new DataConstantProperty(styleSpec.fog["density"]),
"haze-color": new DataConstantProperty(styleSpec.fog["haze-color"]),
"horizon-blend": new DataConstantProperty(styleSpec.fog["horizon-blend"]),
});

Expand All @@ -47,7 +43,6 @@ class Fog extends Evented {
get state(): FogState {
return {
range: this.properties.get('range'),
density: this.properties.get('density'),
horizonBlend: this.properties.get('horizon-blend')
};
}
Expand Down
Loading

0 comments on commit 414085b

Please sign in to comment.