pub const WGSL_VERSION: u32 = 3;
pub const WIND_DEFORMER_NAME: &str = "viewport_lib_wind";
pub const WIND_SWAY_STRIDE_BYTES: u32 = 4;
pub const WIND_MATERIAL_PARAMS_STRIDE_BYTES: u32 = 12;
pub const WIND_DEFORMER_BODY: &str = r#"
fn deform(v: DeformVertex, ctx: DeformContext) -> DeformVertex {
var out = v;
let slot = ctx.slot;
let stride = deform_slot_stride(slot);
if stride == 0u {
return out;
}
let mask = deform_read_f32(slot, v.vertex_index, 0u);
if mask <= 0.0 {
return out;
}
// Per-mesh material multipliers (strength, density, speed). Live in the
// per-mesh-instance slot data when the host has attached them; default
// to 1.0 otherwise.
var mat_strength: f32 = 1.0;
var mat_density: f32 = 1.0;
var mat_speed: f32 = 1.0;
// Instance 0 carries the per-mesh material params. `stride` here is in
// u32 words (3 = 12 bytes); when no params have been attached the slot
// reads as zeroed and defaults kick in above.
if deform_instance_slot_stride(slot) >= 3u {
mat_strength = deform_read_instance_f32(slot, 0u, 0u);
mat_density = deform_read_instance_f32(slot, 0u, 1u);
mat_speed = deform_read_instance_f32(slot, 0u, 2u);
}
let p0 = deform_header.slot_params[slot * 4u + 0u];
let p1 = deform_header.slot_params[slot * 4u + 1u];
let dir = vec3<f32>(p0.x, p0.y, p0.z);
let base = p0.w;
let gust = p1.x;
let freq = p1.y * mat_speed;
let density = p1.z * mat_density;
let time = p1.w;
let dlen_sq = dot(dir, dir);
if dlen_sq < 1e-8 {
return out;
}
let ndir = dir * inverseSqrt(dlen_sq);
let phase = time * freq + (v.position.x + v.position.z) * density;
let g = sin(phase) * gust;
out.position = v.position + ndir * ((base + g) * mask * mat_strength);
return out;
}
"#;
#[deprecated(note = "use WIND_DEFORMER_BODY")]
pub const SHARED_WIND_WGSL: &str = WIND_DEFORMER_BODY;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn body_defines_deform_function() {
assert!(WIND_DEFORMER_BODY.contains("fn deform("));
}
#[test]
fn body_reads_slot_data_and_params() {
assert!(WIND_DEFORMER_BODY.contains("deform_read_f32"));
assert!(WIND_DEFORMER_BODY.contains("deform_header.slot_params"));
}
#[test]
fn body_reads_per_mesh_material_multipliers() {
assert!(WIND_DEFORMER_BODY.contains("deform_read_instance_f32"));
assert!(WIND_DEFORMER_BODY.contains("mat_strength"));
assert!(WIND_DEFORMER_BODY.contains("mat_density"));
assert!(WIND_DEFORMER_BODY.contains("mat_speed"));
}
}