rustial-renderer-wgpu 0.0.1

Pure WGPU renderer for the rustial 2.5D map engine
Documentation
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);
}