Skip to main content

CONTENT_WGSL

Constant CONTENT_WGSL 

Source
pub const CONTENT_WGSL: &str = r#"
override use_content: bool = true;
override use_content_cutout: bool = true;
@group(3) @binding(18) var content0: texture_2d<f32>;
@group(3) @binding(19) var content1: texture_2d<f32>;
@group(3) @binding(20) var content2: texture_2d<f32>;
@group(3) @binding(21) var content3: texture_2d<f32>;
@group(3) @binding(22) var content_sampler: sampler;
struct ContentCaustic {
    rect: vec4f,
    plane: vec4f,
    info: vec4f,
}
@group(3) @binding(27) var<uniform> content_caustic: ContentCaustic;
fn caustic_uv(world: vec3f) -> vec2f {
    let toward = content_caustic.plane.xyz;
    let along = (content_caustic.plane.w - world.y) / max(toward.y, 1e-4);
    let q = world.xz + toward.xz * along;
    return (q - content_caustic.rect.xy) / content_caustic.rect.zw;
}
fn caustic_gain(at: vec2f, dx: vec2f, dy: vec2f) -> vec3f {
    if (content_caustic.info.z < 0.5 || any(at < vec2f(0.0)) || any(at > vec2f(1.0))) {
        return vec3f(1.0);
    }
    let texel = content_texel(i32(content_caustic.info.x), at, dx, dy).rgb;
    return max(vec3f(1.0) + texel * content_caustic.info.y, vec3f(0.0));
}
fn content_size(slot: i32) -> vec2f {
    switch slot {
        case 0: { return vec2f(textureDimensions(content0)); }
        case 1: { return vec2f(textureDimensions(content1)); }
        case 2: { return vec2f(textureDimensions(content2)); }
        case 3: { return vec2f(textureDimensions(content3)); }
        default: { return vec2f(1.0); }
    }
}
fn content_texel(slot: i32, at: vec2f, dx: vec2f, dy: vec2f) -> vec4f {
    switch slot {
        case 0: { return textureSampleGrad(content0, content_sampler, at, dx, dy); }
        case 1: { return textureSampleGrad(content1, content_sampler, at, dx, dy); }
        case 2: { return textureSampleGrad(content2, content_sampler, at, dx, dy); }
        case 3: { return textureSampleGrad(content3, content_sampler, at, dx, dy); }
        default: { return vec4f(0.0); }
    }
}
fn content_alpha(slot: i32, at: vec2f) -> f32 {
    switch slot {
        case 0: { return textureSampleLevel(content0, content_sampler, at, 0.0).a; }
        case 1: { return textureSampleLevel(content1, content_sampler, at, 0.0).a; }
        case 2: { return textureSampleLevel(content2, content_sampler, at, 0.0).a; }
        case 3: { return textureSampleLevel(content3, content_sampler, at, 0.0).a; }
        default: { return 0.0; }
    }
}
fn content_cut(material_index: u32, uv: vec2f, transform: vec4f, crop: vec4f, cutoff: f32) -> bool {
    let slot = i32(round(map_materials[material_index].content.x));
    if (slot < 0) {
        return true;
    }
    let at = content_uv(uv, transform);
    if (!content_inside(at, crop)) {
        return true;
    }
    return content_alpha(slot, at) < cutoff;
}
fn content_apply(surface_in: Shaded, material_index: u32, uv: vec2f, uv_dx: vec2f, uv_dy: vec2f, transform: vec4f, crop: vec4f, tangent: vec3f, bitangent: vec3f, geometric: vec3f) -> Shaded {
    var surface = surface_in;
    if (!use_content) {
        return surface;
    }
    let layer = map_materials[material_index].content;
    let slot = i32(round(layer.x));
    if (slot < 0) {
        return surface;
    }
    let at = content_uv(uv, transform);
    if (!content_inside(at, crop)) {
        return surface;
    }
    let dx = uv_dx * transform.zw;
    let dy = uv_dy * transform.zw;
    let sharpen = map_materials[material_index].content_extra.y;
    let texel = content_texel(slot, at, dx * sharpen, dy * sharpen);
    let blend = u32(round(layer.y));
    var out = content_composite(surface, blend, texel, layer.z, map_materials[material_index].content_extra.x);
    if (layer.w != 0.0) {
        let step = max(1.5 / content_size(slot), max(abs(dx), abs(dy)));
        let ax = content_texel(slot, at + vec2f(step.x, 0.0), dx, dy).a - content_texel(slot, at - vec2f(step.x, 0.0), dx, dy).a;
        let ay = content_texel(slot, at + vec2f(0.0, step.y), dx, dy).a - content_texel(slot, at - vec2f(0.0, step.y), dx, dy).a;
        var n = content_emboss(out.normal, tangent, bitangent, vec2f(ax, ay), layer.w);
        if (dot(n, geometric) < 0.05) {
            n = normalize(n + geometric * 0.1);
        }
        out.normal = n;
    }
    return out;
}
"#;