Files
MapLibreParticleLab/shaders/color_relief.fragment.glsl

78 lines
1.9 KiB
GLSL

layout(std140) uniform ColorReliefDrawableUBO {
highp mat4 u_matrix;
};
layout(std140) uniform ColorReliefTilePropsUBO {
highp vec4 u_unpack;
highp vec2 u_dimension;
highp int u_color_ramp_size;
highp float pad_tile0;
};
layout(std140) uniform ColorReliefEvaluatedPropsUBO {
highp float u_opacity;
highp float pad_eval0;
highp float pad_eval1;
highp float pad_eval2;
};
uniform sampler2D u_image;
uniform sampler2D u_elevation_stops;
uniform sampler2D u_color_stops;
in vec2 v_pos;
float getElevation(vec2 coord) {
// Convert encoded elevation value to meters
vec4 data = texture(u_image, coord) * 255.0;
data.a = -1.0;
return dot(data, u_unpack);
}
float getElevationStop(int stop) {
// Elevation stops are plain float values, not terrain-RGB encoded
float x = (float(stop) + 0.5) / float(u_color_ramp_size);
return texture(u_elevation_stops, vec2(x, 0.5)).r;
}
vec4 getColorStop(int stop) {
float x = (float(stop) + 0.5) / float(u_color_ramp_size);
return texture(u_color_stops, vec2(x, 0.5));
}
void main() {
float el = getElevation(v_pos);
// Binary search for color stops
int r = (u_color_ramp_size - 1);
int l = 0;
while (r - l > 1) {
int m = (r + l) / 2;
float el_m = getElevationStop(m);
if (el < el_m) {
r = m;
} else {
l = m;
}
}
// Get elevation values for interpolation
float el_l = getElevationStop(l);
float el_r = getElevationStop(r);
// Get colors for interpolation
vec4 color_l = getColorStop(l);
vec4 color_r = getColorStop(r);
// Interpolate between the two colors
// Guard against division by zero when el_r == el_l
float denom = el_r - el_l;
float t = (abs(denom) < 0.0001) ? 0.0 : clamp((el - el_l) / denom, 0.0, 1.0);
fragColor = u_opacity * mix(color_l, color_r, t);
#ifdef OVERDRAW_INSPECTOR
fragColor = vec4(1.0);
#endif
}