| A vector of length 3 indicating the direction from the surface to the sun. | [1, 1, 1] |
diff --git a/src/lib/components/LeafletMap/components/Controls/components/Colorbar.js b/src/lib/components/LeafletMap/components/Controls/components/Colorbar.js
index bb85c4be6..3b781a296 100644
--- a/src/lib/components/LeafletMap/components/Controls/components/Colorbar.js
+++ b/src/lib/components/LeafletMap/components/Controls/components/Colorbar.js
@@ -110,10 +110,10 @@ const ColorBar = props => {
)}
- {minMaxValue[0]} {unit}
+ {minMaxValue[0].toFixed(2)} {unit}
- {minMaxValue[1]} {unit}
+ {minMaxValue[1].toFixed(2)} {unit}
,
control.panelDiv
diff --git a/src/lib/components/LeafletMap/components/Controls/components/MousePosition.js b/src/lib/components/LeafletMap/components/Controls/components/MousePosition.js
index 4fd547780..5229830f7 100644
--- a/src/lib/components/LeafletMap/components/Controls/components/MousePosition.js
+++ b/src/lib/components/LeafletMap/components/Controls/components/MousePosition.js
@@ -191,10 +191,10 @@ const MousePosition = props => {
const x = Math.round(event.latlng.lng);
const y = Math.round(event.latlng.lat);
- const red = ctx.getImageData(screenX, screenY, 1, 1).data[0]; // TODO: store this locally
- const z = mapZValue(red);
+ const [r, g, b, a] = ctx.getImageData(screenX, screenY, 1, 1).data; // TODO: store this locally
+ const z = mapZValue(r, g, b);
- setLatLng(x, y, z, red > 0);
+ setLatLng(x, y, z, a > 0);
};
const mapXCoordinateToCanvas = (x, clientRect, canvas) => {
@@ -228,8 +228,8 @@ const MousePosition = props => {
const x = Math.round(event.latlng.lng);
const y = Math.round(event.latlng.lat);
- const red = ctx.getImageData(screenX, screenY, 1, 1).data[0]; // TODO: store this locally
- const z = mapZValue(red);
+ const [r, g, b] = ctx.getImageData(screenX, screenY, 1, 1).data; // TODO: store this locally
+ const z = mapZValue(r, g, b);
// Used to disable map.on("click") events when pressed on the controls
const controlsList = document.getElementsByClassName(
@@ -300,11 +300,13 @@ const MousePosition = props => {
props.map.addEventListener("mouseup", onCanvasMouseClick);
};
- const mapZValue = redColorvalue => {
+ const mapZValue = (r, g, b) => {
const { minvalue, maxvalue } = stateRef.current || {};
- return roundOff(
- minvalue + ((maxvalue - minvalue) / (255 - 0)) * (redColorvalue - 0)
- );
+
+ const elevation = r * 256.0 * 256.0 + g * 256.0 + b;
+ const scaleFactor =
+ (maxvalue - minvalue) / (256.0 * 256.0 * 256.0 - 1.0);
+ return roundOff(elevation * scaleFactor + minvalue);
};
const roundOff = n => {
diff --git a/src/lib/components/LeafletMap/shaders/blackalpha.fs.glsl b/src/lib/components/LeafletMap/shaders/blackalpha.fs.glsl
deleted file mode 100644
index 6d71fda21..000000000
--- a/src/lib/components/LeafletMap/shaders/blackalpha.fs.glsl
+++ /dev/null
@@ -1,21 +0,0 @@
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at https://mozilla.org/MPL/2.0/.
-//
-// Copyright (C) 2020 - Equinor ASA.
-
-precision highp float;
-
-uniform sampler2D u_image;
-uniform vec2 u_resolution;
-
-
-void main() {
- vec4 colors = texture2D(u_image, gl_FragCoord.xy/u_resolution);
-
- if(colors.r == 0.0 && colors.g == 0.0 && colors.b == 0.0) {
- gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
- } else {
- gl_FragColor = colors;
- }
-}
\ No newline at end of file
diff --git a/src/lib/components/LeafletMap/shaders/color.fs.glsl b/src/lib/components/LeafletMap/shaders/color.fs.glsl
deleted file mode 100644
index f0b9add6e..000000000
--- a/src/lib/components/LeafletMap/shaders/color.fs.glsl
+++ /dev/null
@@ -1,68 +0,0 @@
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at https://mozilla.org/MPL/2.0/.
-//
-// Copyright (C) 2020 - Equinor ASA.
-
-precision highp float;
-
-uniform sampler2D u_image;
-uniform sampler2D u_raw_image;
-uniform vec2 u_resolution;
-
-// Colorscale configurations
-uniform sampler2D u_colormap;
-uniform float u_colormap_length;
-uniform float u_max_color_value;
-uniform float u_min_color_value;
-uniform float u_scale_type;
-uniform bool u_black_to_alpha;
-
-// Maps a value from a given interval to a target interval
-// For example can take in a 0.0-1.0, and map it to 0-255
-float map(float value, float from1, float to1, float from2, float to2) {
- float linear_value = ((value - from1)/(to1 - from1))*(to2 - from2) + from2;
- return linear_value;
-}
-
-
-// See: https://stackoverflow.com/questions/28125439/algorithm-to-map-values-to-unit-scale-with-logarithmic-spacing
-float map_log(float value, float from1, float to1, float from2, float to2) {
- float linear_value = map(value, from1, to1, from2, to2) + 1.0; // + 1.0 is to avoid negative log-values
- float logarithmic_value = ((to2 - from2) * log(linear_value))/log((to2 - from2));
- return logarithmic_value;
-}
-
-// Calculate color value
-vec4 calcColorValue(vec4 colors, vec4 raw_colors, float scale_type) {
- float color_value = colors.r;
- if(color_value < 0.0) {
- color_value = 0.0;
- }
- float raw_value = raw_colors.r;
-
- float mapped_color_value = 0.0;
- if (scale_type == 1.0) {
- mapped_color_value = map_log(color_value, 0.0, 1.0, 0.0, u_colormap_length - 1.0); // from 0 to 1 and from 0 to 255
- } else {
- mapped_color_value = map(color_value, 0.0, 1.0, 0.0, u_colormap_length - 1.0); // from 0 to 1 and from 0 to 255
- }
-
- if (u_black_to_alpha == true && raw_colors.r == 0.0 && raw_colors.g == 0.0 && raw_colors.b == 0.0) {
- return vec4(0.0, 0.0, 0.0, 0.0);
- }
-
- if (raw_value > u_max_color_value/255.0 || raw_value < u_min_color_value/255.0 || colors.a == 0.0) {
- return vec4(0.0, 0.0, 0.0, 0.0);
- }
-
- vec2 colormap_coord = vec2((mapped_color_value) / u_colormap_length, 0.0);
- return texture2D(u_colormap, colormap_coord);
-}
-
-void main() {
- vec4 colors = texture2D(u_image, gl_FragCoord.xy/u_resolution).rgba;
- vec4 raw_colors = texture2D(u_raw_image, gl_FragCoord.xy/u_resolution).rgba;
-
- gl_FragColor = calcColorValue(colors, raw_colors, u_scale_type);
-}
\ No newline at end of file
diff --git a/src/lib/components/LeafletMap/shaders/hillshading/ambient.fs.glsl b/src/lib/components/LeafletMap/shaders/hillshading/ambient.fs.glsl
deleted file mode 100644
index 4e4aa09ec..000000000
--- a/src/lib/components/LeafletMap/shaders/hillshading/ambient.fs.glsl
+++ /dev/null
@@ -1,54 +0,0 @@
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at https://mozilla.org/MPL/2.0/.
-//
-// Copyright (C) 2020 - Equinor ASA.
-
-precision highp float;
-
-uniform sampler2D tElevation;
-uniform sampler2D tNormal;
-uniform sampler2D tSrc;
-uniform vec3 direction;
-uniform vec2 resolution;
-uniform float pixelScale;
-uniform float n;
-
-void main() {
- vec2 ires = 1.0 / resolution;
- vec3 src = texture2D(tSrc, gl_FragCoord.xy * ires).rgb;
- vec4 e0 = texture2D(tElevation, gl_FragCoord.xy * ires);
- vec4 n0 = texture2D(tNormal, gl_FragCoord.xy * ires).rgba;
- vec3 sr3d = normalize(n0.rgb + direction);
-
- vec2 sr = normalize(sr3d.xy);
- vec2 p0 = gl_FragCoord.xy;
- vec2 p = floor(p0);
- vec2 stp = sign(sr);
- vec2 tMax = step(0.0, sr) * (1.0 - fract(p0)) + (1.0 - step(0.0, sr)) * fract(p0);
- tMax /= abs(sr);
- vec2 tDelta = 1.0 / abs(sr);
- for (int i = 0; i < 65536; i++) {
- if (tMax.x < tMax.y) {
- tMax.x += tDelta.x;
- p.x += stp.x;
- } else {
- tMax.y += tDelta.y;
- p.y += stp.y;
- }
- vec2 ptex = ires * (p + 0.5);
- if (ptex.x < 0.0 || ptex.x > 1.0 || ptex.y < 0.0 || ptex.y > 1.0) {
- gl_FragColor = vec4(src + vec3(1.0/n), n0.a);
- return;
- }
- vec4 e = texture2D(tElevation, ptex);
- float t = distance(p + 0.5, p0);
- float z = e0.r + t * pixelScale * sr3d.z;
- if (e.r > z) {
- gl_FragColor = vec4(src, n0.a);
- return;
- }
- }
- gl_FragColor = vec4(src + vec3(1.0/n), n0.a);
-}
-
\ No newline at end of file
diff --git a/src/lib/components/LeafletMap/shaders/hillshading/combined.fs.glsl b/src/lib/components/LeafletMap/shaders/hillshading/combined.fs.glsl
deleted file mode 100644
index b348634b4..000000000
--- a/src/lib/components/LeafletMap/shaders/hillshading/combined.fs.glsl
+++ /dev/null
@@ -1,24 +0,0 @@
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at https://mozilla.org/MPL/2.0/.
-//
-// Copyright (C) 2020 - Equinor ASA.
-
-precision highp float;
-
-uniform sampler2D tSoftShadow;
-uniform sampler2D tAmbient;
-uniform vec2 resolution;
-
-void main() {
-
- vec2 ires = 1.0 / resolution;
- vec4 softShadowColors = texture2D(tSoftShadow, ires * gl_FragCoord.xy).rgba;
-
- float softShadow = softShadowColors.r;
- float ambient = texture2D(tAmbient, ires * gl_FragCoord.xy).r;
-
- // float l = 4.0 * softShadow + 0.25 * ambient;
- float l = 1.0 * softShadow + 0.25 * ambient;
- gl_FragColor = vec4(l,l,l, softShadowColors.a);
-}
\ No newline at end of file
diff --git a/src/lib/components/LeafletMap/shaders/hillshading/directlightning.fs.glsl b/src/lib/components/LeafletMap/shaders/hillshading/directlightning.fs.glsl
deleted file mode 100644
index 6e8695c54..000000000
--- a/src/lib/components/LeafletMap/shaders/hillshading/directlightning.fs.glsl
+++ /dev/null
@@ -1,20 +0,0 @@
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at https://mozilla.org/MPL/2.0/.
-//
-// Copyright (C) 2020 - Equinor ASA.
-
-precision highp float;
-
-uniform sampler2D tNormal;
-uniform vec2 resolution;
-uniform vec3 sunDirection;
-
-void main() {
- vec2 dr = 1.0/resolution;
- vec4 n = texture2D(tNormal, gl_FragCoord.xy/resolution).rgba;
- float light = dot(n.rgb, sunDirection);
- //light = 1.0 * light + 5.0;
- gl_FragColor = vec4(light, light, light, n.a);
-}
-
diff --git a/src/lib/components/LeafletMap/shaders/hillshading/elevation.fs.glsl b/src/lib/components/LeafletMap/shaders/hillshading/elevation.fs.glsl
deleted file mode 100644
index 1e501b80f..000000000
--- a/src/lib/components/LeafletMap/shaders/hillshading/elevation.fs.glsl
+++ /dev/null
@@ -1,23 +0,0 @@
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at https://mozilla.org/MPL/2.0/.
-//
-// Copyright (C) 2020 - Equinor ASA.
-
-precision highp float;
-
-uniform sampler2D tElevation;
-uniform vec2 resolution;
-uniform float elevationScale;
-
-void main() {
- // Sample the terrain-rgb tile at the current fragment location.
- vec4 rgb = texture2D(tElevation, gl_FragCoord.xy/resolution).rgba;
-
- // Convert the red, green, and blue channels into an elevation.
- float e = -10000.0 + ((rgb.r * 255.0 * 256.0 * 256.0 + rgb.g * 255.0 * 256.0 + rgb.b * 255.0) * 0.1);
-
- // Scale the elevation and write it out.
- gl_FragColor = vec4(vec3(e * elevationScale), rgb.a);
- // gl_FragColor = 10000.0*vec4(e, e, e, 1.0);
-}
\ No newline at end of file
diff --git a/src/lib/components/LeafletMap/shaders/hillshading/normals.fs.glsl b/src/lib/components/LeafletMap/shaders/hillshading/normals.fs.glsl
deleted file mode 100644
index b68288798..000000000
--- a/src/lib/components/LeafletMap/shaders/hillshading/normals.fs.glsl
+++ /dev/null
@@ -1,25 +0,0 @@
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at https://mozilla.org/MPL/2.0/.
-//
-// Copyright (C) 2020 - Equinor ASA.
-
-precision highp float;
-
-uniform sampler2D tElevation;
-uniform vec2 resolution;
-uniform float pixelScale;
-
-void main() {
- vec2 dr = 1.0/resolution;
- vec4 colors = texture2D(tElevation, dr * (gl_FragCoord.xy + vec2(0.0, 0.0))).rgba;
-
- float p0 = colors.r;
- float px = texture2D(tElevation, dr * (gl_FragCoord.xy + vec2(1.0, 0.0))).r;
- float py = texture2D(tElevation, dr * (gl_FragCoord.xy + vec2(0.0, 1.0))).r;
- vec3 dx = vec3(pixelScale, 0.0, px - p0);
- vec3 dy = vec3(0.0, pixelScale, py - p0);
- vec3 n = normalize(cross(dx, dy));
- // gl_FragColor = vec4(0.5 * n + 0.5, 1.0);
- gl_FragColor = vec4(n, colors.a);
-}
\ No newline at end of file
diff --git a/src/lib/components/LeafletMap/shaders/hillshading/soft/softHillshading.fs.glsl b/src/lib/components/LeafletMap/shaders/hillshading/soft/softHillshading.fs.glsl
deleted file mode 100644
index 19f84e3bd..000000000
--- a/src/lib/components/LeafletMap/shaders/hillshading/soft/softHillshading.fs.glsl
+++ /dev/null
@@ -1,42 +0,0 @@
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at https://mozilla.org/MPL/2.0/.
-//
-// Copyright (C) 2020 - Equinor ASA.
-
-
-precision mediump float;
-
-uniform sampler2D u_image;
-uniform sampler2D u_colormap;
-
-uniform float u_colormap_length;
-uniform vec2 u_resolution;
-uniform float u_elevation_scale;
-uniform vec3 u_light_direction;
-
-varying vec2 v_texCoord;
-
-void main() {
- vec2 pixelPos = vec2(gl_FragCoord.x, u_resolution.y - gl_FragCoord.y);
-
- vec4 rgba = texture2D(u_image, pixelPos / u_resolution).rgba;
- float v0 = rgba.r;
- float vx = texture2D(u_image, (pixelPos + vec2(1.0, 0.0)) / u_resolution).r;
- float vy = texture2D(u_image, (pixelPos + vec2(0.0, 1.0)) / u_resolution).r;
-
- // Create tangent vector components along terrain
- // in x and y directions respectively:
- vec3 dx = vec3(u_elevation_scale, 0.0, vx - v0);
- vec3 dy = vec3(0.0, u_elevation_scale, v0 - vy);
-
- // Calculate terrain normal vector by taking cross product of dx and dy.
- // Then calculate simple hill shading by taking dot product between
- // normal vector and light direction vector.
- float light = 0.5 * dot(normalize(cross(dx, dy)), u_light_direction) + 0.5;
-
- float map_array = texture2D(u_image, v_texCoord).r;
- vec4 color = texture2D(u_colormap, vec2((map_array * (u_colormap_length - 1.0) + 0.5) / u_colormap_length, 0.5));
-
- gl_FragColor = color * vec4(light, light, light, rgba.a);
-}
\ No newline at end of file
diff --git a/src/lib/components/LeafletMap/shaders/hillshading/soft/softHillshading.vs.glsl b/src/lib/components/LeafletMap/shaders/hillshading/soft/softHillshading.vs.glsl
deleted file mode 100644
index 0054c93bb..000000000
--- a/src/lib/components/LeafletMap/shaders/hillshading/soft/softHillshading.vs.glsl
+++ /dev/null
@@ -1,25 +0,0 @@
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at https://mozilla.org/MPL/2.0/.
-//
-// Copyright (C) 2020 - Equinor ASA.
-
-precision mediump float;
-
-attribute vec2 a_position;
-attribute vec2 a_texCoord;
-
-uniform vec2 u_resolution;
-
-varying vec2 v_texCoord;
-
-void main() {
- // Convert from pixel range ([0, w] x [0, h]) to clip space ([-1, 1] x [-1, 1]):
- vec2 clipSpace = (a_position / u_resolution) * 2.0 - 1.0;
-
- // Flip y axis
- gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);
-
- // Pass the texCoord to the fragment shader
- v_texCoord = a_texCoord;
-}
diff --git a/src/lib/components/LeafletMap/shaders/hillshading/softshadow.fs.glsl b/src/lib/components/LeafletMap/shaders/hillshading/softshadow.fs.glsl
deleted file mode 100644
index 614046574..000000000
--- a/src/lib/components/LeafletMap/shaders/hillshading/softshadow.fs.glsl
+++ /dev/null
@@ -1,58 +0,0 @@
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at https://mozilla.org/MPL/2.0/.
-//
-// Copyright (C) 2020 - Equinor ASA.
-
-precision highp float;
-
-uniform sampler2D tElevation;
-uniform sampler2D tNormal;
-uniform sampler2D tSrc;
-uniform vec3 sunDirection;
-uniform vec2 resolution;
-uniform float pixelScale;
-uniform float n; // The number of iterations
-
-void main() {
- vec2 ires = 1.0 / resolution;
- vec3 src = texture2D(tSrc, gl_FragCoord.xy * ires).rgb;
- vec4 e0 = texture2D(tElevation, gl_FragCoord.xy * ires);
- vec4 n0 = texture2D(tNormal, gl_FragCoord.xy * ires).rgba;
- vec2 sr = normalize(sunDirection.xy);
-
- vec2 p0 = gl_FragCoord.xy;
- vec2 p = floor(p0);
- vec2 stp = sign(sr);
- vec2 tMax = step(0.0, sr) * (1.0 - fract(p0)) + (1.0 - step(0.0, sr)) * fract(p0);
- tMax /= abs(sr);
- vec2 tDelta = 1.0 / abs(sr);
-
- for (int i = 0; i < 65536; i++) { // 256x256
- if (tMax.x < tMax.y) {
- tMax.x += tDelta.x;
- p.x += stp.x;
- } else {
- tMax.y += tDelta.y;
- p.y += stp.y;
- }
-
- // Did we exit the tile?
- vec2 ptex = ires * (p + 0.5);
- if (ptex.x < 0.0 || ptex.x > 1.0 || ptex.y < 0.0 || ptex.y > 1.0) {
- gl_FragColor = vec4(src + vec3(1.0/n) * clamp(dot(n0.rgb, sunDirection), 0.0, 1.0), n0.a);
- return;
- }
-
- // Have we hit the terrain?
- vec4 e = texture2D(tElevation, ptex);
- float t = distance(p + 0.5, p0);
- float z = e0.r + t * pixelScale * sunDirection.z;
- if (e.r > z) {
- gl_FragColor = vec4(src, n0.a);
- return;
- }
- }
- gl_FragColor = vec4(src + vec3(1.0/n) * clamp(dot(n0.rgb, sunDirection), 0.0, 1.0), n0.a);
-}
-
diff --git a/src/lib/components/LeafletMap/shaders/image.fs.glsl b/src/lib/components/LeafletMap/shaders/image.fs.glsl
deleted file mode 100644
index f6800e3c2..000000000
--- a/src/lib/components/LeafletMap/shaders/image.fs.glsl
+++ /dev/null
@@ -1,23 +0,0 @@
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at https://mozilla.org/MPL/2.0/.
-//
-// Copyright (C) 2020 - Equinor ASA.
-
-precision highp float;
-
-uniform sampler2D u_image;
-uniform vec2 u_resolution;
-uniform float u_max_color_value;
-uniform float u_min_color_value;
-
-
-void main() {
- vec4 colors = texture2D(u_image, gl_FragCoord.xy/u_resolution);
-
- if (colors.r > u_max_color_value/255.0 || colors.r < u_min_color_value/255.0) {
- colors = vec4(0.0, 0.0, 0.0, 0.0);
- }
-
- gl_FragColor = colors;
-}
\ No newline at end of file
diff --git a/src/lib/components/LeafletMap/shaders/terrainRGB.fs.glsl b/src/lib/components/LeafletMap/shaders/terrainRGB.fs.glsl
new file mode 100644
index 000000000..e0a2c6375
--- /dev/null
+++ b/src/lib/components/LeafletMap/shaders/terrainRGB.fs.glsl
@@ -0,0 +1,100 @@
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at https://mozilla.org/MPL/2.0/.
+//
+// Copyright (C) 2020 - Equinor ASA.
+
+precision highp float;
+
+const int INTERP_LINEAR = 0;
+const int INTERP_LOG = 1;
+
+uniform sampler2D u_data_texture;
+uniform vec2 u_resolution;
+
+uniform sampler2D u_colormap;
+uniform int u_interpolation_type;
+uniform float u_value_range;
+uniform vec2 u_remap_colormap;
+uniform vec2 u_clamp_colormap;
+
+uniform bool u_apply_color_scale;
+uniform bool u_apply_hillshading;
+
+uniform vec3 u_sun_direction;
+uniform float u_ambient_light_intensity;
+uniform float u_diffuse_light_intensity;
+
+uniform float u_elevation_scale;
+
+// TODO: Investigate using R32 textures (webgl2) to avoid this transformation.
+float elevation_from_rgb(vec3 col) {
+ // Decode elevation data. Format is similar to the Mapbox Terrain RGB:
+ // https://docs.mapbox.com/help/troubleshooting/access-elevation-data/
+ // but without the -10000 offset and the 0.1 scale.
+ // The elevations are also scaled to cover the whole RGB domain, for better precision,
+ // so we need to scale them down to the original domain.
+ float elevation = col.r * 255.0 * 256.0 * 256.0 + col.g * 255.0 * 256.0 + col.b * 255.0 ;
+ float scale_factor = u_value_range / (256.0*256.0*256.0 - 1.0);
+ return elevation * scale_factor * u_elevation_scale;
+}
+
+vec4 color_map(float elevation) {
+ float colormap_u = 0.0;
+ if (u_interpolation_type == INTERP_LOG) {
+ // Add one to avoid log(0). The result should be the same.
+ colormap_u = log(elevation + 1.0) / log(u_value_range + 1.0);
+ }
+ else { // u_interpolation_type == INTERP_LINEAR
+ colormap_u = elevation / u_value_range;
+ }
+
+ // Cutoff
+ if (colormap_u < u_clamp_colormap.x || colormap_u > u_clamp_colormap.y) {
+ discard;
+ }
+
+ // Remap
+ colormap_u = mix(u_remap_colormap.x, u_remap_colormap.y, colormap_u);
+
+ return texture2D(u_colormap, vec2(colormap_u, 0.0));
+}
+
+vec3 normal(float elevation) {
+ vec2 dr = 1.0/u_resolution;
+ float p0 = elevation;
+ float px = elevation_from_rgb(texture2D(u_data_texture, dr * (gl_FragCoord.xy + vec2(1.0, 0.0))).rgb);
+ float py = elevation_from_rgb(texture2D(u_data_texture, dr * (gl_FragCoord.xy + vec2(0.0, 1.0))).rgb);
+ vec3 dx = vec3(1.0, 0.0, px - p0);
+ vec3 dy = vec3(0.0, 1.0, py - p0);
+
+ return normalize(cross(dx, dy));
+}
+
+float light(vec3 normal) {
+ float diffuse = u_diffuse_light_intensity * dot(normal, u_sun_direction);
+
+ return clamp(u_ambient_light_intensity + diffuse, 0.0, 1.0);
+}
+
+void main() {
+ vec4 final_color = texture2D(u_data_texture, gl_FragCoord.xy/u_resolution);
+
+ if (final_color.a == 0.0) {
+ discard;
+ }
+
+ float elevation = elevation_from_rgb(final_color.rgb);
+
+ if (u_apply_color_scale) {
+ // The colorscale shouldn't be affected by the elevation scale.
+ final_color = color_map(elevation / u_elevation_scale);
+ }
+
+ if (u_apply_hillshading) {
+ vec3 normal = normal(elevation);
+ final_color.rgb = final_color.rgb * light(normal);
+ }
+
+ gl_FragColor = final_color;
+}
\ No newline at end of file
diff --git a/src/lib/components/LeafletMap/webgl/commands/drawRawImage.js b/src/lib/components/LeafletMap/webgl/commands/drawRawImage.js
deleted file mode 100644
index 82ae359a6..000000000
--- a/src/lib/components/LeafletMap/webgl/commands/drawRawImage.js
+++ /dev/null
@@ -1,76 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- *
- * Copyright (C) 2020 - Equinor ASA. */
-
-import EQGL from "../eqGL";
-
-// Shaders
-import positionVShader from "../../shaders/position.vs.glsl";
-import imageFShader from "../../shaders/image.fs.glsl";
-import blackAlphaFShader from "../../shaders/blackalpha.fs.glsl";
-
-/**
- * @param {WebGLRenderingContext} gl
- */
-export default (gl, canvas, loadedImage, options = {}) => {
- const {
- cutPointMin = 0.0,
- cutPointMax = 1000.0,
-
- setBlackToAlpha = false,
- } = options;
-
- gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
-
- const width = loadedImage.width;
- const height = loadedImage.height;
-
- canvas.width = width;
- canvas.height = height;
-
- const eqGL = EQGL(gl, canvas);
-
- const rawTexture = eqGL.texture({ image: loadedImage });
- let inputTexture = rawTexture;
-
- if (setBlackToAlpha) {
- // Set black (0, 0, 0) color-values with alpha = 0
- const fboBlackAlpha = eqGL.framebuffer({
- width: width,
- height: height,
- });
-
- const blackToAlphaCmd = eqGL
- .new()
- .vert(positionVShader)
- .frag(blackAlphaFShader)
- .attribute("position", [-1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1])
- .texture("u_image", inputTexture)
- .uniformf("u_resolution", loadedImage.width, loadedImage.height)
- .viewport(0, 0, width, height)
- .framebuffer(fboBlackAlpha)
- .vertexCount(6)
- .build();
-
- blackToAlphaCmd();
-
- inputTexture = fboBlackAlpha;
- }
-
- const drawCmd = eqGL
- .new()
- .vert(positionVShader)
- .frag(imageFShader)
- .attribute("position", [-1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1])
- .texture("u_image", inputTexture)
- .uniformf("u_resolution", loadedImage.width, loadedImage.height)
- .uniformf("u_max_color_value", cutPointMax)
- .uniformf("u_min_color_value", cutPointMin)
- .viewport(0, 0, width, height)
- .vertexCount(6)
- .build();
-
- drawCmd();
-};
diff --git a/src/lib/components/LeafletMap/webgl/commands/drawWithAdvancedHillShading.js b/src/lib/components/LeafletMap/webgl/commands/drawWithAdvancedHillShading.js
deleted file mode 100644
index c0b163c81..000000000
--- a/src/lib/components/LeafletMap/webgl/commands/drawWithAdvancedHillShading.js
+++ /dev/null
@@ -1,321 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- *
- * Copyright (C) 2020 - Equinor ASA. */
-
-import EQGL from "../eqGL";
-import vec3 from "../vec3";
-
-// Shaders
-import positionVShader from "../../shaders/position.vs.glsl";
-import elevationFShader from "../../shaders/hillshading/elevation.fs.glsl";
-import normalsFShader from "../../shaders/hillshading/normals.fs.glsl";
-import directLightningsFShader from "../../shaders/hillshading/directlightning.fs.glsl";
-import softShadowFShader from "../../shaders/hillshading/softshadow.fs.glsl";
-import ambientFShader from "../../shaders/hillshading/ambient.fs.glsl";
-import combinedFShader from "../../shaders/hillshading/combined.fs.glsl";
-import colorFShader from "../../shaders/color.fs.glsl";
-
-// CONSTANTS
-const DEFAULT_PIXEL_SCALE = 8000;
-const DEFAULT_ELEVATION_SCALE = 1.0;
-const DEFAULT_SUN_DIRECTION = vec3.normalize([], [1, 1, 1]);
-
-/**
- * @typedef {Object} HillshadingOptions
- * @property {Number} pixelScale
- * @property {Number} elevationScale
- * @property {Boolean} shadows
- * @property {Number} shadowIterations
- * @property {String} scaleType
- * @property {Number} cutPointMin
- * @property {Number} cutPointMax
- */
-
-/**
- * @description - This hillshader is heavly inspiried by the Rye Terrell's advanced map shading tutorial:
- * https://wwwtyro.net/2019/03/21/advanced-map-shading.html
- *
- * A known issue is that the soft-shadows are quite GPU-heavy and is quite slow for big images. High number of
- * shadow-iterations might be fatal for the browser on big images.
- *
- * @author Anders Hallem Iversen
- * @param {WebGLRenderingContext} gl
- * @param {HTMLCanvasElement} canvas
- * @param {HTMLImageElement} loadedImage
- * @param {HTMLImageElement} loadedColorMap
- * @param {HillshadingOptions} options
- */
-export default async (
- gl,
- canvas,
- loadedImage,
- loadedColorMap,
- options = {}
-) => {
- const {
- // Hillshading options
- pixelScale = DEFAULT_PIXEL_SCALE,
- elevationScale = DEFAULT_ELEVATION_SCALE,
- shadows = false,
- sunDirection = DEFAULT_SUN_DIRECTION,
- shadowIterations = null,
-
- // ColorScale type
- scaleType = "linear",
- cutPointMin = 0.0,
- cutPointMax = 256.0,
- noColor = false,
-
- setBlackToAlpha = false,
- } = options;
-
- gl.getExtension("OES_texture_float");
- gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
-
- /**
- * @type {EQGLContext}
- */
- const eqGL = EQGL(gl, canvas);
-
- const width = loadedImage.width;
- const height = loadedImage.height;
-
- canvas.width = width;
- canvas.height = height;
-
- // The number of iterations for soft-shadows and ambient light
- let N = shadowIterations || calcN(width, height);
-
- const rawTexture = eqGL.texture({ image: loadedImage });
- const fboElevation = eqGL.framebuffer({ width: width, height: height });
-
- const elevationCmd = eqGL
- .new()
- .vert(positionVShader)
- .frag(elevationFShader)
- .attribute("position", [-1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1])
- .texture("tElevation", rawTexture)
- .uniformf("elevationScale", elevationScale)
- .uniformf("resolution", loadedImage.width, loadedImage.height)
- .vertexCount(6)
- .viewport(0, 0, loadedImage.width, loadedImage.height)
- .framebuffer(fboElevation)
- .build();
-
- elevationCmd();
-
- const fboNormal = eqGL.framebuffer({ width: width, height: height });
-
- const normalCmd = eqGL
- .new()
- .vert(positionVShader)
- .frag(normalsFShader)
- .attribute("position", [-1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1])
- .texture("tElevation", fboElevation)
- .uniformf("pixelScale", pixelScale)
- .uniformf("resolution", loadedImage.width, loadedImage.height)
- .vertexCount(6)
- .viewport(0, 0, loadedImage.width, loadedImage.height)
- .framebuffer(fboNormal)
- .build();
-
- normalCmd();
-
- const fboFinal = eqGL.framebuffer({ width: width, height: height });
-
- if (!shadows) {
- // Render the image without shadows - just add some direct lights
- const directCmd = eqGL
- .new()
- .vert(positionVShader)
- .frag(directLightningsFShader)
- .attribute("position", [-1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1])
- .texture("tNormal", fboNormal)
- .uniformf("sunDirection", sunDirection)
- .uniformf("resolution", loadedImage.width, loadedImage.height)
- .viewport(0, 0, loadedImage.width, loadedImage.height)
- .framebuffer(noColor ? null : fboFinal)
- .vertexCount(6)
- .build();
-
- directCmd();
- } else {
- // Enable shadows
- const shadowPP = PingPong(eqGL, {
- width: loadedImage.width,
- height: loadedImage.height,
- });
-
- const softShadowsCmd = eqGL
- .new()
- .vert(positionVShader)
- .frag(softShadowFShader)
- .attribute("position", [-1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1])
- .texture("tElevation", fboElevation)
- .texture("tNormal", fboNormal)
- .texture("tSrc", eqGL.variable("src"))
- .uniform("sunDirection", "3f", eqGL.variable("sunDirection"))
- .uniformf("pixelScale", pixelScale)
- .uniformf("resolution", loadedImage.width, loadedImage.height)
- .uniformf("n", N)
- .viewport(0, 0, loadedImage.width, loadedImage.height)
- .framebuffer(eqGL.variable("dest"))
- .vertexCount(6)
- .build();
-
- for (let i = 0; i < N; i++) {
- const sunDirection = vec3.normalize(
- [],
- vec3.add(
- [],
- vec3.scale([], vec3.normalize([], [1, 1, 1]), 149600000000),
- vec3.random([], 695508000 * 100)
- )
- );
-
- softShadowsCmd({
- sunDirection: sunDirection,
- src: shadowPP.ping(),
- // dest: i === N - 1 ? undefined : shadowPP.pong()
- dest: shadowPP.pong(),
- });
- shadowPP.swap();
- }
-
- // Enable ambient lighting
- const ambientPP = PingPong(eqGL, {
- width: loadedImage.width,
- height: loadedImage.height,
- });
-
- const ambientCmd = eqGL
- .new()
- .vert(positionVShader)
- .frag(ambientFShader)
- .attribute("position", [-1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1])
- .texture("tElevation", fboElevation)
- .texture("tNormal", fboNormal)
- .texture("tSrc", eqGL.variable("src"))
- .uniform("direction", "3f", eqGL.variable("direction"))
- .uniformf("pixelScale", 152.70299374405343)
- .uniformf("resolution", loadedImage.width, loadedImage.height)
- .uniformf("n", N)
- .framebuffer(eqGL.variable("dest"))
- .viewport(0, 0, loadedImage.width, loadedImage.height)
- .vertexCount(6)
- .build();
-
- for (let i = 0; i < N; i++) {
- ambientCmd({
- direction: vec3.random([], Math.random()),
- src: ambientPP.ping(),
- dest: ambientPP.pong(),
- });
- ambientPP.swap();
- }
-
- // Combine the shadows and the ambient lighting
- const finalCmd = eqGL
- .new()
- .vert(positionVShader)
- .frag(combinedFShader)
- .attribute("position", [-1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1])
- .texture("tSoftShadow", shadowPP.ping())
- .texture("tAmbient", ambientPP.ping())
- .uniformf("resolution", loadedImage.width, loadedImage.height)
- .viewport(0, 0, loadedImage.width, loadedImage.height)
- .framebuffer(noColor ? null : fboFinal)
- .vertexCount(6)
- .build();
-
- finalCmd();
- }
-
- if (!noColor) {
- // Apply the provided colormap
- const colorScaleCmd = eqGL
- .new()
- .vert(positionVShader)
- .frag(colorFShader)
- .attribute("position", [-1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1])
- .texture("u_image", fboFinal)
- .texture("u_raw_image", rawTexture)
- .texture("u_colormap", eqGL.texture({ image: loadedColorMap }))
- .uniformf("u_colormap_length", loadedColorMap.width)
- .uniformf("u_resolution", loadedImage.width, loadedImage.height)
- .uniformf("u_scale_type", scaleType === "log" ? 1.0 : 0.0) // 1.0 is logarithmic
- .uniformf("u_max_color_value", cutPointMax)
- .uniformf("u_min_color_value", cutPointMin)
- .uniformi("u_black_to_alpha", Boolean(setBlackToAlpha))
- .viewport(0, 0, loadedImage.width, loadedImage.height)
- .vertexCount(6)
- .build();
-
- colorScaleCmd();
- }
-
- eqGL.clean();
-};
-
-/**
- * PingPong is a structure for swapping between two framebuffers
- * @param {EQGLContext} eqGL
- * @param {Object} opts
- */
-function PingPong(eqGL, opts) {
- const fbos = [eqGL.framebuffer(opts), eqGL.framebuffer(opts)];
-
- let index = 0;
-
- function ping() {
- return fbos[index];
- }
-
- function pong() {
- return fbos[1 - index];
- }
-
- function swap() {
- index = 1 - index;
- }
-
- return {
- ping,
- pong,
- swap,
- };
-}
-
-/**
- * The purpose of this function is to make the soft-shadows and ambient-lightning iterations
- * not so costly. For small images N = 128 is fine, but for bigger images N = 10 is too much.
- *
- * This function is not throughly tested on different sizes and can not be considered perfect.
- * @param {Number} width
- * @param {Number} height
- * @returns {Number}
- */
-function calcN(width, height) {
- const resolution = width * height;
-
- if (resolution <= 90000) {
- // 300x300
- return 128;
- } else if (resolution <= 360000) {
- // 600x600
- return 84;
- } else if (resolution <= 490000) {
- // 700x700
- return 48;
- } else if (resolution <= 810000) {
- // 900x900
- return 18;
- } else if (resolution < 2293760) {
- // 1792x1280
- return 8;
- }
-
- return 1; // resolution >= 1792x1280
-}
diff --git a/src/lib/components/LeafletMap/webgl/commands/drawWithColormap.js b/src/lib/components/LeafletMap/webgl/commands/drawWithColormap.js
deleted file mode 100644
index 3180cf746..000000000
--- a/src/lib/components/LeafletMap/webgl/commands/drawWithColormap.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- *
- * Copyright (C) 2020 - Equinor ASA. */
-
-import EQGL from "../eqGL";
-
-// Shaders
-import positionVShader from "../../shaders/position.vs.glsl";
-import colorFShader from "../../shaders/color.fs.glsl";
-
-/**
- * @param {WebGLRenderingContext} gl
- */
-export default (gl, canvas, loadedImage, loadedColorMap, options = {}) => {
- const {
- scaleType = "linear",
- cutPointMin = 0.0,
- cutPointMax = 1000.0,
- setBlackToAlpha = false,
- } = options;
-
- gl.getExtension("OES_texture_float");
- //gl.getExtension('OES_texture_float_linear');
-
- gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
-
- const width = loadedImage.width;
- const height = loadedImage.height;
-
- canvas.width = width;
- canvas.height = height;
-
- const eqGL = EQGL(gl, canvas);
-
- const rawTexture = eqGL.texture({ image: loadedImage });
-
- const drawCmd = eqGL
- .new()
- .vert(positionVShader)
- .frag(colorFShader)
- .attribute("position", [-1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1])
- .texture("u_image", rawTexture)
- .texture("u_raw_image", rawTexture)
- .texture("u_colormap", eqGL.texture({ image: loadedColorMap }))
- .uniformf("u_colormap_length", loadedColorMap.width)
- .uniformf("u_resolution", loadedImage.width, loadedImage.height)
- .uniformf("u_scale_type", scaleType === "log" ? 1.0 : 0.0) // 1.0 is logarithmic
- .uniformf("u_max_color_value", cutPointMax)
- .uniformf("u_min_color_value", cutPointMin)
- .uniformi("u_black_to_alpha", Boolean(setBlackToAlpha))
- .viewport(0, 0, width, height)
- .vertexCount(6)
- .build();
-
- drawCmd();
-};
diff --git a/src/lib/components/LeafletMap/webgl/commands/drawWithHillShading.js b/src/lib/components/LeafletMap/webgl/commands/drawWithHillShading.js
deleted file mode 100644
index e8c36454d..000000000
--- a/src/lib/components/LeafletMap/webgl/commands/drawWithHillShading.js
+++ /dev/null
@@ -1,103 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- *
- * Copyright (C) 2020 - Equinor ASA. */
-
-import EQGL from "../eqGL";
-
-// Shaders
-import vertexShader from "../../shaders/hillshading/soft/softHillshading.vs.glsl";
-import fragmentShader from "../../shaders/hillshading/soft/softHillshading.fs.glsl";
-import positionVShader from "../../shaders/position.vs.glsl";
-import blackAlphaFShader from "../../shaders/blackalpha.fs.glsl";
-
-const DEFAULT_ELEVATION_SCALE = 0.03;
-const DEFAULT_LIGHT_DIRECTION = [1, 1, 1];
-
-/**
- * @param {WebGLRenderingContext} gl
- */
-export default (gl, canvas, loadedImage, loadedColorMap, config = {}) => {
- const {
- elevationScale = DEFAULT_ELEVATION_SCALE,
- lightDirection = DEFAULT_LIGHT_DIRECTION,
-
- setBlackToAlpha = false,
- } = config;
-
- gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
-
- const width = loadedImage.width;
- const height = loadedImage.height;
-
- canvas.width = width;
- canvas.height = height;
-
- const eqGL = EQGL(gl, canvas);
-
- // Add hillshading properties
- const vectorLength = Math.sqrt(
- lightDirection[0] ** 2 + lightDirection[1] ** 2 + lightDirection[2] ** 2
- );
-
- const rawTexture = eqGL.texture({ image: loadedImage });
- let inputTexture = rawTexture;
-
- if (setBlackToAlpha) {
- const fboBlackAlpha = eqGL.framebuffer({
- width: width,
- height: height,
- });
-
- const blackToAlphaCmd = eqGL
- .new()
- .vert(positionVShader)
- .frag(blackAlphaFShader)
- .attribute("position", [-1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1])
- .texture("u_image", inputTexture)
- .uniformf("u_resolution", loadedImage.width, loadedImage.height)
- .viewport(0, 0, width, height)
- .framebuffer(fboBlackAlpha)
- .vertexCount(6)
- .build();
-
- blackToAlphaCmd();
-
- inputTexture = fboBlackAlpha;
- }
-
- const elevationCmd = eqGL
- .new()
- .vert(vertexShader)
- .frag(fragmentShader)
- .attribute("a_texCoord", [0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1]) // The vertices of two triangles, creating a square
- .attribute("a_position", [
- 0,
- 0,
- width,
- 0,
- 0,
- height,
- 0,
- height,
- width,
- 0,
- width,
- height,
- ])
- .texture("u_image", inputTexture)
- .texture("u_colormap", eqGL.texture({ image: loadedColorMap }))
- .uniformf("u_colormap_length", loadedColorMap.width)
- .uniformf("u_resolution", width, height)
- .uniformf(
- "u_light_direction",
- ...lightDirection.map(dir => dir / vectorLength)
- )
- .uniformf("u_elevation_scale", elevationScale)
- .viewport(0, 0, width, height)
- .vertexCount(6)
- .build();
-
- elevationCmd();
-};
diff --git a/src/lib/components/LeafletMap/webgl/commands/drawWithTerrainRGB.js b/src/lib/components/LeafletMap/webgl/commands/drawWithTerrainRGB.js
new file mode 100644
index 000000000..85045a0db
--- /dev/null
+++ b/src/lib/components/LeafletMap/webgl/commands/drawWithTerrainRGB.js
@@ -0,0 +1,137 @@
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at https://mozilla.org/MPL/2.0/.
+//
+// Copyright (C) 2020 - Equinor ASA.
+
+import EQGL from "../eqGL";
+import vec3 from "../vec3";
+
+// Shaders
+import positionVShader from "../../shaders/position.vs.glsl";
+import terrainRGBFSShader from "../../shaders/terrainRGB.fs.glsl";
+
+// CONSTANTS
+const DEFAULT_ELEVATION_SCALE = -1.0;
+const DEFAULT_SUN_DIRECTION = vec3.normalize([], [1, 1, 1]);
+const DEFAULT_AMBIENT_LIGHT_INTENSITY = 0.5;
+const DEFAULT_DIFFUSE_LIGHT_INTENSITY = 0.5;
+
+/**
+ * @typedef {Object} Options
+ * @property {Number} minValue - Minimum elevation value.
+ * @property {Number} maxValue - Maximum elevation value.
+ * @property {Boolean} applyColorScale - Colorscale the data.
+ * @property {String} scaleType - "linear"/"log", apply the colorscale linearly or logarithmically.
+ * @property {Number} remapPointMin - [0,1], remap the minimum data point to a different point on the colorscale.
+ * @property {Number} remapPointMax - [0,1], remap the maximum data point to a different point on the colorscale.
+ * @property {Number} cutPointMin - [0,1], don't display points lower than this threshold.
+ * @property {Number} cutPointMax - [0,1], don't display points higher than this threshold.
+ * @property {Boolean} applyHillshading - Apply hillshading.
+ * @property {Number} elevationScale - Multiplier applied to the elevation value when computing the hillshading.
+ * @property {vec3} sunDirection - Direction the light is coming from.
+ * @property {Number} ambientLightIntensity - Brightness added to all pixels.
+ * @property {Number} diffuseLightIntensity - Brightness of surfaces hit by light.
+ */
+
+/**
+ * @description - This draws MapBox Terrain RGB data with a colorscale applied.
+ *
+ * @param {WebGLRenderingContext} gl
+ * @param {HTMLCanvasElement} canvas
+ * @param {HTMLImageElement} loadedImage
+ * @param {HTMLImageElement} loadedColorMap
+ * @param {Options} options
+ */
+export default async (
+ gl,
+ canvas,
+ loadedImage,
+ loadedColorMap,
+ options = {}
+) => {
+ const {
+ minValue = 0.0,
+ maxValue = 0.0,
+
+ // ColorScale type
+ applyColorScale = true,
+ scaleType = "linear",
+ remapPointMin = 0.0,
+ remapPointMax = 1.0,
+ cutPointMin = 0.0,
+ cutPointMax = 1.0,
+
+ // Hillshading options
+ applyHillshading = true,
+ elevationScale = DEFAULT_ELEVATION_SCALE,
+ sunDirection = DEFAULT_SUN_DIRECTION,
+ ambientLightIntensity = DEFAULT_AMBIENT_LIGHT_INTENSITY,
+ diffuseLightIntensity = DEFAULT_DIFFUSE_LIGHT_INTENSITY,
+ } = options;
+
+ const interpolationTypes = {
+ linear: 0,
+ log: 1,
+ };
+
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
+
+ /**
+ * @type {EQGLContext}
+ */
+ const eqGL = EQGL(gl, canvas);
+
+ const width = loadedImage.width;
+ const height = loadedImage.height;
+
+ canvas.width = width;
+ canvas.height = height;
+
+ const dataTexture = eqGL.texture({ image: loadedImage });
+ const colormapTexture = loadedColorMap
+ ? eqGL.texture({ image: loadedColorMap })
+ : null;
+
+ // prettier-ignore
+ const quad = [
+ -1, -1, //Bottom-Left
+ 1, -1, // Bottom-Right
+ 1, 1, // Top-Right
+
+ -1, -1, // Bottom-Left
+ 1, 1, // Top-Right
+ -1, 1, // Top-Left
+ ];
+
+ const terrainRGBCmd = eqGL
+ .new()
+ .vert(positionVShader)
+ .frag(terrainRGBFSShader)
+ .attribute("position", quad)
+ .vertexCount(6)
+
+ .texture("u_data_texture", dataTexture)
+ .uniformf("u_resolution", loadedImage.width, loadedImage.height)
+
+ .uniformi("u_apply_color_scale", Boolean(applyColorScale))
+ .uniformi("u_apply_hillshading", Boolean(applyHillshading))
+
+ .texture("u_colormap", colormapTexture)
+ .uniformi("u_interpolation_type", interpolationTypes[scaleType])
+ .uniformf("u_value_range", maxValue - minValue)
+ .uniformf("u_remap_colormap", remapPointMin, remapPointMax)
+ .uniformf("u_clamp_colormap", cutPointMin, cutPointMax)
+
+ .uniformf("u_elevation_scale", elevationScale)
+ .uniformf("u_sun_direction", sunDirection)
+ .uniformf("u_ambient_light_intensity", ambientLightIntensity)
+ .uniformf("u_diffuse_light_intensity", diffuseLightIntensity)
+
+ .viewport(0, 0, loadedImage.width, loadedImage.height)
+ .build();
+
+ terrainRGBCmd();
+
+ eqGL.clean();
+};
diff --git a/src/lib/components/LeafletMap/webgl/commands/index.js b/src/lib/components/LeafletMap/webgl/commands/index.js
index d82dbdb37..df229b35e 100644
--- a/src/lib/components/LeafletMap/webgl/commands/index.js
+++ b/src/lib/components/LeafletMap/webgl/commands/index.js
@@ -4,7 +4,4 @@
*
* Copyright (C) 2020 - Equinor ASA. */
-export { default as drawRawImage } from "./drawRawImage";
-export { default as drawWithColormap } from "./drawWithColormap";
-export { default as drawWithHillShading } from "./drawWithHillShading";
-export { default as drawWithAdvancedHillShading } from "./drawWithAdvancedHillShading";
+export { default as drawWithTerrainRGB } from "./drawWithTerrainRGB";
diff --git a/src/lib/components/LeafletMap/webgl/drawFunc.js b/src/lib/components/LeafletMap/webgl/drawFunc.js
index 4263ff474..c7630b83d 100644
--- a/src/lib/components/LeafletMap/webgl/drawFunc.js
+++ b/src/lib/components/LeafletMap/webgl/drawFunc.js
@@ -4,12 +4,7 @@
*
* Copyright (C) 2020 - Equinor ASA. */
-import {
- drawRawImage,
- drawWithColormap,
- drawWithHillShading,
- drawWithAdvancedHillShading,
-} from "./commands";
+import { drawWithTerrainRGB } from "./commands";
// Utils
import Utils from "../utils";
@@ -29,87 +24,18 @@ export default async (gl, canvas, image, colormap = null, config = {}) => {
// Select which draw command to draw
const shader = config.shader || {};
const colorScale = config.colorScale || {};
+ if (!shader.type || shader.type == "terrainRGB") {
+ const minmaxValues = {
+ minValue: config.minvalue,
+ maxValue: config.maxvalue,
+ };
- const cutOffPoints = calcCutOffPoints(
- config.minvalue,
- config.maxvalue,
- (config.colorScale || {}).cutPointMin,
- (config.colorScale || {}).cutPointMax
- );
-
- if (loadedColorMap) {
- switch (shader.type) {
- // Old hillshader
- case "soft-hillshading": {
- drawWithHillShading(gl, canvas, loadedImage, loadedColorMap, {
- ...colorScale,
- ...shader,
- });
- break;
- }
-
- case "hillshading": {
- drawWithAdvancedHillShading(
- gl,
- canvas,
- loadedImage,
- loadedColorMap,
- {
- ...colorScale,
- ...shader,
- ...cutOffPoints,
- }
- );
- break;
- }
-
- default: {
- // Draw the image with colormap
- drawWithColormap(gl, canvas, loadedImage, loadedColorMap, {
- ...colorScale,
- ...shader,
- ...cutOffPoints,
- });
- }
- }
- } else {
- // Draw the image raw - without colormap
- drawRawImage(gl, canvas, loadedImage, {
+ drawWithTerrainRGB(gl, canvas, loadedImage, loadedColorMap, {
+ ...minmaxValues,
...colorScale,
...shader,
- ...cutOffPoints,
});
+ } else {
+ console.warn("Unrecognized shader: ", shader.type);
}
};
-
-/**
- * Calculates cutOffPoints based on given a min/max values and min/max-cutoff-points between 0 and 255.
- * @example
- * calcCutOffPoints(0, 1000, 500, 1000) // { 127, 255 }
- */
-const calcCutOffPoints = (min, max, cutMin, cutMax) => {
- // If min and max is not provided, there will be no cutOff
- if (!min || !max) {
- return {
- cutPointMin: 0,
- cutPointMax: 256,
- };
- }
-
- if (cutMax > max) {
- cutMax = max;
- }
- if (cutMin < min) {
- cutMin = min;
- }
-
- const maxColorValue = Math.round(
- 255 - (Math.abs(cutMax - max) / (max - min)) * 255
- );
- const minColorValue = Math.round(((cutMin - min) / (max - min)) * 255);
-
- return {
- cutPointMin: minColorValue,
- cutPointMax: maxColorValue,
- };
-};