highcharts
Version:
JavaScript charting framework
149 lines (120 loc) • 3.97 kB
JavaScript
/* *
*
* (c) 2010-2026 Highsoft AS
* Author: Torstein Hønsi
*
* A commercial license may be required depending on use.
* See www.highcharts.com/license
*
*
* */
'use strict';
/* *
*
* Shader Code
*
* */
export default `
struct VertexInput {
pos: vec3f
}
struct VertexOutput {
pos: vec4f,
originalPos: vec3f,
valExtremes: vec2f,
}
var<uniform> uExtremes: vec4f;
var<uniform> uValueExtremes: vec2f;
var<uniform> uIsInverted: u32;
fn vertexMain(input: VertexInput) -> VertexOutput {
var output: VertexOutput;
let pos = input.pos;
let xMin = uExtremes[0];
let xMax = uExtremes[1];
let yMin = uExtremes[2];
let yMax = uExtremes[3];
var posX: f32;
var posY: f32;
if (uIsInverted > 0u) {
posX = (1.0 - (pos.y - yMin) / (yMax - yMin)) * 2.0 - 1.0;
posY = (1.0 - (pos.x - xMin) / (xMax - xMin)) * 2.0 - 1.0;
} else {
posX = (pos.x - xMin) / (xMax - xMin) * 2.0 - 1.0;
posY = (pos.y - yMin) / (yMax - yMin) * 2.0 - 1.0;
}
output.valExtremes = uValueExtremes;
output.originalPos = pos.xyz;
output.pos = vec4f(posX, posY, 0, 1);
return output;
}
// ------------------------------------------------
struct FragmentInput {
originalPos: vec3f,
valExtremes: vec2f
}
var<storage> uColorStops: array<vec4<f32>>;
var<uniform> uColorStopsCount: u32;
var<uniform> uContourInterval: f32;
var<uniform> uContourOffset: f32;
var<uniform> uSmoothColoring: u32;
var<uniform> uContourLineWidth: f32;
var<uniform> uContourLineColor: vec3f;
fn getColor(value: f32) -> vec3<f32> {
let stopCount = uColorStopsCount;
if (stopCount == 0u) {
return vec3<f32>(1.0, 1.0, 1.0);
}
for (var i: u32 = 0u; i < stopCount - 1u; i = i + 1u) {
if (value < uColorStops[i + 1u].x) {
let t = (value - uColorStops[i].x) /
(uColorStops[i + 1u].x - uColorStops[i].x);
return mix(uColorStops[i].yzw, uColorStops[i + 1u].yzw, t);
}
}
return uColorStops[stopCount - 1u].yzw;
}
fn fragmentMain(input: FragmentInput) -> vec4f {
let val = input.originalPos.z;
// Contour lines
let lineWidth: f32 = uContourLineWidth;
let val_dx: f32 = dpdx(val);
let val_dy: f32 = dpdy(val);
let gradient: f32 = length(vec2f(val_dx, val_dy));
let epsilon: f32 = max(uContourInterval * 1.0e-6, 1.0e-12);
let adjustedLineWidth: f32 = lineWidth * gradient + epsilon;
let adjustedVal: f32 = val - uContourOffset;
let valDiv: f32 = adjustedVal / uContourInterval;
let valMod: f32 = adjustedVal - uContourInterval * floor(valDiv);
let lineMask: f32 = smoothstep(0.0, adjustedLineWidth, valMod) * (
1.0 - smoothstep(
uContourInterval - adjustedLineWidth,
uContourInterval,
valMod
)
);
// Background color
let minHeight: f32 = input.valExtremes.x;
let maxHeight: f32 = input.valExtremes.y;
var bgColor: vec3f;
if (uSmoothColoring > 0u) {
bgColor = getColor((val - minHeight) / (maxHeight - minHeight));
} else {
let adjustedVal: f32 = val - uContourOffset;
let averageValInBand: f32 = floor(
adjustedVal / uContourInterval
) * uContourInterval + uContourOffset + uContourInterval / 2.0;
bgColor = getColor(
(averageValInBand - minHeight) /
(maxHeight - minHeight)
);
}
// Mix
var pixelColor = bgColor;
if (lineWidth > 0.0) {
pixelColor = mix(uContourLineColor, pixelColor, lineMask);
}
return vec4(pixelColor, 1.0);
}
`;