posh
posh copied to clipboard
Common subexpression not mapped to variable
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);
[...]