UNPKG

highcharts

Version:
149 lines (120 loc) 3.97 kB
/* * * * (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 { @location(0) pos: vec3f } struct VertexOutput { @builtin(position) pos: vec4f, @location(0) originalPos: vec3f, @location(1) valExtremes: vec2f, } @group(0) @binding(0) var<uniform> uExtremes: vec4f; @group(0) @binding(1) var<uniform> uValueExtremes: vec2f; @group(0) @binding(9) var<uniform> uIsInverted: u32; @vertex 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 { @location(0) originalPos: vec3f, @location(1) valExtremes: vec2f } @group(0) @binding(2) var<storage> uColorStops: array<vec4<f32>>; @group(0) @binding(3) var<uniform> uColorStopsCount: u32; @group(0) @binding(4) var<uniform> uContourInterval: f32; @group(0) @binding(5) var<uniform> uContourOffset: f32; @group(0) @binding(6) var<uniform> uSmoothColoring: u32; @group(0) @binding(7) var<uniform> uContourLineWidth: f32; @group(0) @binding(8) 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; } @fragment fn fragmentMain(input: FragmentInput) -> @location(0) 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); } `;