Skip to main content

CAST_WGSL

Constant CAST_WGSL 

Source
pub const CAST_WGSL: &str = r#"
struct Cast {
    model: mat4x4f,
    view_proj: mat4x4f,
    tint: vec4f,
    tinted: vec4f,
    liquid: vec4f,
    clip0: vec4f,
    clip1: vec4f,
}
@group(0) @binding(0) var<storage, read> casts: array<Cast>;
@group(0) @binding(1) var cast_fluid: texture_2d<f32>;
@group(0) @binding(2) var cast_ripple: texture_2d<f32>;
struct CastVertex {
    @location(0) position: vec4f,
    @location(1) normal: vec4f,
    @location(2) uv: vec4f,
    @location(3) look: vec4f,
}
struct CastOut {
    @builtin(position) position: vec4f,
    @location(0) @interpolate(flat) row: u32,
    @location(1) look: vec4f,
    @location(2) world: vec3f,
}
fn cast_height(uv: vec2f, caster: Cast) -> f32 {
    let fluid_size = vec2f(textureDimensions(cast_fluid));
    let ripple_size = vec2f(textureDimensions(cast_ripple));
    let fluid_xy = vec2i(clamp(uv * fluid_size, vec2f(0.0), fluid_size - vec2f(1.0)));
    let ripple_xy = vec2i(clamp(uv * ripple_size, vec2f(0.0), ripple_size - vec2f(1.0)));
    return textureLoad(cast_fluid, fluid_xy, 0).r * caster.liquid.y + textureLoad(cast_ripple, ripple_xy, 0).r * caster.liquid.z;
}
@vertex fn cast_vertex(v: CastVertex, @builtin(instance_index) row: u32) -> CastOut {
    let caster = casts[row];
    var p = v.position.xyz;
    if (caster.liquid.x > 0.5 && v.normal.z > 0.5) {
        p.z += cast_height(v.uv.xy, caster);
    }
    let world = caster.model * vec4f(p, 1.0);
    var out: CastOut;
    out.position = caster.view_proj * world;
    out.row = row;
    out.look = v.look;
    out.world = world.xyz;
    return out;
}
fn cast_clip(plane: vec4f, world: vec3f) -> bool {
    return any(plane.xyz != vec3f(0.0)) && dot(plane.xyz, world) > plane.w;
}
@fragment fn cast_fragment(input: CastOut) -> @location(0) vec4u {
    if (input.look.z < 0.0) { discard; }
    let caster = casts[input.row];
    if (cast_clip(caster.clip0, input.world) || cast_clip(caster.clip1, input.world)) { discard; }
    var tint = caster.tint.xyz;
    if (input.look.w > 0.5) {
        tint = mix(tint, caster.tinted.xyz, clamp(input.look.x, 0.0, 1.0));
    }
    return vec4u(pack4x8unorm(vec4f(tint, 1.0)), bitcast<u32>(input.position.z), 0u, 0u);
}
"#;