#[set(everything)] const constants: { screen_size_inv: float2; current_mip_level: int; sample_scale: float; bloom_strength: float; }; #[set(everything)] const sampler_linear: sampler; #[set(everything)] const tex: tex2d; struct vert_in { pos: float2; } struct vert_out { pos: float4; tex: float2; } fun bloom_upsample_pass_vert(input: vert_in): vert_out { var output: vert_out; output.tex = input.pos.xy * 0.5 + 0.5; output.tex.y = 1.0 - output.tex.y; output.pos = float4(input.pos.xy, 0.0, 1.0); return output; } fun clamp_coord(coord: float2, texel_size: float2): float2 { var lo: float2 = texel_size * 1.5; var hi: float2 = float2(1.0, 1.0) - lo; return float2(clamp(coord.x, lo.x, hi.x), clamp(coord.y, lo.y, hi.y)); } fun upsample_dual_filter(tex_coord: float2, texel_size: float2): float3 { var delta: float2 = texel_size * constants.sample_scale; var result: float3; result = sample_lod(tex, sampler_linear, clamp_coord(tex_coord + float2(-delta.x * 2.0, 0.0), texel_size), 0.0).rgb; result += sample_lod(tex, sampler_linear, clamp_coord(tex_coord + float2(-delta.x, delta.y), texel_size), 0.0).rgb * 2.0; result += sample_lod(tex, sampler_linear, clamp_coord(tex_coord + float2(0.0, delta.y * 2.0), texel_size), 0.0).rgb; result += sample_lod(tex, sampler_linear, clamp_coord(tex_coord + delta, texel_size), 0.0).rgb * 2.0; result += sample_lod(tex, sampler_linear, clamp_coord(tex_coord + float2(delta.x * 2.0, 0.0), texel_size), 0.0).rgb; result += sample_lod(tex, sampler_linear, clamp_coord(tex_coord + float2(delta.x, -delta.y), texel_size), 0.0).rgb * 2.0; result += sample_lod(tex, sampler_linear, clamp_coord(tex_coord + float2(0.0, -delta.y * 2.0), texel_size), 0.0).rgb; result += sample_lod(tex, sampler_linear, clamp_coord(tex_coord - delta, texel_size), 0.0).rgb * 2.0; return result * (1.0 / 12.0); } fun bloom_upsample_pass_frag(input: vert_out): float4 { var color: float4; color.rgb = upsample_dual_filter(input.tex, constants.screen_size_inv); if (constants.current_mip_level == 0) { color.rgb = color.rgb * float3(constants.bloom_strength, constants.bloom_strength, constants.bloom_strength); } color.a = 1.0; return color; } #[pipe] struct pipe { vertex = bloom_upsample_pass_vert; fragment = bloom_upsample_pass_frag; }