posh icon indicating copy to clipboard operation
posh copied to clipboard

Common subexpression not mapped to variable

Open leod opened this issue 1 year ago • 0 comments

I'll try to find a more minimal example later.

Fragment shader:

fn fragment_shader_sobel(
    sampler: sl::ColorSampler2d<sl::F32>,
    input: sl::FsInput<sl::Vec2>,
) -> sl::FullFsOutput<sl::Vec4> {
    let uv = input.interp;
    let center_alpha = sampler.sample(uv);

    let size = sampler.size(0u32).as_vec2();
    let tex_offset = 1.0 / size;

    let n = [
        sl::ivec2(-1, -1),
        sl::ivec2(0, -1),
        sl::ivec2(1, -1),
        sl::ivec2(-1, 0),
        sl::ivec2(0, 0),
        sl::ivec2(1, 0),
        sl::ivec2(-1, 1),
        sl::ivec2(0, 1),
        sl::ivec2(1, 1),
    ]
    .map(|offset| {
        let sample_uv = uv + offset.as_vec2() * tex_offset;

        let is_no_wraparound = sample_uv
            .cmpge(sl::Vec2::ZERO)
            .all()
            .and(sample_uv.cmple(sl::Vec2::ONE).all());

        is_no_wraparound
            .then(sampler.sample(sample_uv))
            .otherwise(0.0)
    });

    let sobel_edge_h = n[2] + (2.0 * n[5]) + n[8] - (n[0] + (2.0 * n[3]) + n[6]);
    let sobel_edge_v = n[0] + (2.0 * n[1]) + n[2] - (n[6] + (2.0 * n[7]) + n[8]);
    let sobel = ((sobel_edge_h * sobel_edge_h) + (sobel_edge_v * sobel_edge_v)).sqrt();

    let sobel = sobel.gt(0.0).then(1.0).otherwise_discard(input);

    let max_alpha = n.into_iter().fold(center_alpha, sl::F32::max);
    let max_depth = max_alpha * 2.0 - 1.0;
    let max_depth = max_depth
        .lt(ZLayer::TileBackground.to_depth() + 0.05)
        .then_discard(input)
        .otherwise(max_depth);

    let color = max_depth
        .ge(ZLayer::Object(ObjectLayer::Enemy, 0, 0).to_depth())
        .and(max_depth.lt(ZLayer::Object(ObjectLayer::Me, 0, 0).to_depth()))
        .then(srgb_to_linear(glam::uvec3(255, 50, 50)) * 5.0)
        .else_then(
            max_depth
                .ge(ZLayer::Object(ObjectLayer::Me, 0, 0).to_depth())
                .and(max_depth.le(ZLayer::ObjectMax.to_depth())),
            srgb_to_linear(glam::uvec3(255, 255, 0)) * 5.0,
        )
        .otherwise(sl::Vec3::ONE * 5.0);

    sl::FullFsOutput {
        fragment: (sobel * color).extend(1.0),
        fragment_depth: Some(max_alpha),
    }
}

The generated GLSL contains the expression for max_alpha twice, which is a bug.

[...]
    float var_23 = ((max(max(max(max(max(max(max(max(max(texture(uniforms, vertex_output).x, var_8), var_15), var_2), var_10), var_22), var_4), var_12), var_17), var_6) * 2.0) - 1.0);
    float var_25;
    if ((var_23 < 0.068)) {
        discard;
    } else {
        var_25 = var_23;
    }
    vec3 var_27;
    if (((var_25 >= 0.33666664) && (var_25 < 0.5133333))) {
        var_27 = vec3(5.0, 0.15948014, 0.15948014);
    } else {
        vec3 var_26;
        if (((var_25 >= 0.5133333) && (var_25 <= 0.69))) {
            var_26 = vec3(5.0, 5.0, 0.0);
        } else {
            var_26 = (vec3(1.0, 1.0, 1.0) * 5.0);
        }
        var_27 = var_26;
    }
    vec3 var_28 = (var_20 * var_27);
    fragment_output = vec4(var_28.x, var_28.y, var_28.z, 1.0);
    gl_FragDepth = max(max(max(max(max(max(max(max(max(texture(uniforms, vertex_output).x, var_8), var_15), var_2), var_10), var_22), var_4), var_12), var_17), var_6);
[...]

leod avatar Dec 09 '24 22:12 leod