struct Uniforms {
view_proj: mat4x4<f32>,
fog_color: vec4<f32>,
eye_pos: vec4<f32>,
fog_params: vec4<f32>,
hillshade_highlight: vec4<f32>,
hillshade_shadow: vec4<f32>,
hillshade_accent: vec4<f32>,
hillshade_light: vec4<f32>,
};
struct GridScalarUniforms {
origin_counts: vec4<f32>, // (lat, lon, rows, cols)
grid_params: vec4<f32>, // (cell_width, cell_height, rotation, opacity)
scene_origin: vec4<f32>, // (x, y, z, projection_kind)
value_params: vec4<f32>, // (min, max, nan_value, has_nan)
base_altitude: vec4<f32>, // (base_altitude, 0, 0, 0)
};
struct VertexInput {
@location(0) position: vec3<f32>,
@location(1) uv: vec2<f32>,
};
struct VertexOutput {
@builtin(position) clip_position: vec4<f32>,
@location(0) uv: vec2<f32>,
@location(1) world_pos: vec3<f32>,
};
@group(0) @binding(0)
var<uniform> u: Uniforms;
@group(1) @binding(0)
var<uniform> overlay: GridScalarUniforms;
@group(1) @binding(1)
var scalar_texture: texture_2d<f32>;
@group(1) @binding(2)
var ramp_texture: texture_2d<f32>;
@group(1) @binding(3)
var ramp_sampler: sampler;
fn normalized_value(value: f32) -> f32 {
let range = overlay.value_params.y - overlay.value_params.x;
if abs(range) < 1e-6 {
return 0.5;
}
return clamp((value - overlay.value_params.x) / range, 0.0, 1.0);
}
@vertex
fn vs_main(in: VertexInput) -> VertexOutput {
var out: VertexOutput;
out.clip_position = u.view_proj * vec4<f32>(in.position, 1.0);
out.uv = in.uv;
out.world_pos = in.position;
return out;
}
@fragment
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
let dims = textureDimensions(scalar_texture);
let cols = max(i32(dims.x), 1);
let rows = max(i32(dims.y), 1);
let col = clamp(i32(floor(in.uv.x * f32(cols))), 0, cols - 1);
let row = clamp(i32(floor(in.uv.y * f32(rows))), 0, rows - 1);
let value = textureLoad(scalar_texture, vec2<i32>(col, row), 0).x;
if value != value {
discard;
}
if overlay.value_params.w > 0.5 && abs(value - overlay.value_params.z) < 1e-6 {
discard;
}
let t = normalized_value(value);
let ramp = textureSample(ramp_texture, ramp_sampler, vec2<f32>(t, 0.5));
return vec4<f32>(ramp.rgb, ramp.a * overlay.grid_params.w);
}