blob: 501acb3df78cbfa995e889da819e5f7375282063 [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// 1D (directional) gaussian blur.
//
// Paths for future optimization:
// * Remove the uv bounds multiplier in SampleColor by adding optional
// support for SamplerAddressMode::ClampToBorder in the texture sampler.
// * Sample from higher mipmap levels when the blur radius is high enough.
uniform sampler2D texture_sampler;
uniform sampler2D alpha_mask_sampler;
in vec2 v_texture_coords;
in vec2 v_src_texture_coords;
in vec2 v_texture_size;
in vec2 v_blur_direction;
in float v_blur_sigma;
in float v_blur_radius;
in float v_src_factor;
in float v_inner_blur_factor;
in float v_outer_blur_factor;
out vec4 frag_color;
const float kSqrtTwoPi = 2.50662827463;
float Gaussian(float x) {
float variance = v_blur_sigma * v_blur_sigma;
return exp(-0.5 * x * x / variance) / (kSqrtTwoPi * v_blur_sigma);
}
// Emulate SamplerAddressMode::ClampToBorder.
vec4 SampleWithBorder(sampler2D tex, vec2 uv) {
float within_bounds = float(uv.x >= 0 && uv.y >= 0 && uv.x < 1 && uv.y < 1);
return texture(tex, uv) * within_bounds;
}
void main() {
vec4 total_color = vec4(0);
float gaussian_integral = 0;
vec2 blur_uv_offset = v_blur_direction / v_texture_size;
for (float i = -v_blur_radius; i <= v_blur_radius; i++) {
float gaussian = Gaussian(i);
gaussian_integral += gaussian;
total_color +=
gaussian * SampleWithBorder(texture_sampler,
v_texture_coords + blur_uv_offset * i);
}
vec4 blur_color = total_color / gaussian_integral;
vec4 src_color = SampleWithBorder(alpha_mask_sampler, v_src_texture_coords);
float blur_factor = v_inner_blur_factor * float(src_color.a > 0) +
v_outer_blur_factor * float(src_color.a == 0);
frag_color = blur_color * blur_factor + src_color * v_src_factor;
}