mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[Impeller] Move gaussian routines into the shader library (flutter/engine#37037)
This commit is contained in:
parent
702a9365bd
commit
2145adbc5a
@ -1107,6 +1107,7 @@ FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/blending.glsl
|
||||
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/branching.glsl
|
||||
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/color.glsl
|
||||
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/constants.glsl
|
||||
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/gaussian.glsl
|
||||
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/texture.glsl
|
||||
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/transform.glsl
|
||||
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/types.glsl
|
||||
|
||||
@ -13,4 +13,7 @@ const float k1Over2Pi = 0.1591549430918;
|
||||
// sqrt(2 * pi)
|
||||
const float kSqrtTwoPi = 2.50662827463;
|
||||
|
||||
// sqrt(2) / 2 == 1 / sqrt(2)
|
||||
const float kHalfSqrtTwo = 0.70710678118;
|
||||
|
||||
#endif
|
||||
|
||||
@ -0,0 +1,35 @@
|
||||
// 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.
|
||||
|
||||
#ifndef GAUSSIAN_GLSL_
|
||||
#define GAUSSIAN_GLSL_
|
||||
|
||||
#include <impeller/constants.glsl>
|
||||
|
||||
float IPGaussian(float x, float sigma) {
|
||||
float variance = sigma * sigma;
|
||||
return exp(-0.5 * x * x / variance) / (kSqrtTwoPi * sigma);
|
||||
}
|
||||
|
||||
/// Abramowitz and Stegun erf approximation.
|
||||
float IPErf(float x) {
|
||||
float a = abs(x);
|
||||
// 0.278393*x + 0.230389*x^2 + 0.078108*x^4 + 1
|
||||
float b = (0.278393 + (0.230389 + 0.078108 * a * a) * a) * a + 1.0;
|
||||
return sign(x) * (1 - 1 / (b * b * b * b));
|
||||
}
|
||||
|
||||
vec2 IPVec2Erf(vec2 x) {
|
||||
return vec2(IPErf(x.x), IPErf(x.y));
|
||||
}
|
||||
|
||||
/// Indefinite integral of the Gaussian function (with constant range 0->1).
|
||||
float IPGaussianIntegral(float x, float sigma) {
|
||||
// ( 1 + erf( x * (sqrt(2) / (2 * sigma) ) ) / 2
|
||||
// Because this sigmoid is always > 1, we remap it (n * 1.07 - 0.07)
|
||||
// so that it always fades to zero before it reaches the blur radius.
|
||||
return 0.535 * IPErf(x * (kHalfSqrtTwo / sigma)) + 0.465;
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -2,6 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <impeller/gaussian.glsl>
|
||||
#include <impeller/texture.glsl>
|
||||
|
||||
// Constant time mask blur for image borders.
|
||||
@ -27,30 +28,12 @@ in float v_outer_blur_factor;
|
||||
|
||||
out vec4 frag_color;
|
||||
|
||||
// Abramowitz and Stegun erf approximation.
|
||||
float erf(float x) {
|
||||
float a = abs(x);
|
||||
// 0.278393*x + 0.230389*x^2 + 0.078108*x^4 + 1
|
||||
float b = (0.278393 + (0.230389 + 0.078108 * a * a) * a) * a + 1.0;
|
||||
return sign(x) * (1 - 1 / (b * b * b * b));
|
||||
}
|
||||
|
||||
const float kHalfSqrtTwo = 0.70710678118;
|
||||
|
||||
// Indefinite integral of the Gaussian function (with constant range 0->1).
|
||||
float GaussianIntegral(float x, float sigma) {
|
||||
// ( 1 + erf( x * (sqrt(2) / (2 * sigma) ) ) / 2
|
||||
// Because this sigmoid is always > 1, we remap it (n * 1.07 - 0.07)
|
||||
// so that it always fades to zero before it reaches the blur radius.
|
||||
return 0.535 * erf(x * (kHalfSqrtTwo / sigma)) + 0.465;
|
||||
}
|
||||
|
||||
float BoxBlurMask(vec2 uv) {
|
||||
// LTRB
|
||||
return GaussianIntegral(uv.x, v_sigma_uv.x) * //
|
||||
GaussianIntegral(uv.y, v_sigma_uv.y) * //
|
||||
GaussianIntegral(1 - uv.x, v_sigma_uv.x) * //
|
||||
GaussianIntegral(1 - uv.y, v_sigma_uv.y);
|
||||
return IPGaussianIntegral(uv.x, v_sigma_uv.x) * //
|
||||
IPGaussianIntegral(uv.y, v_sigma_uv.y) * //
|
||||
IPGaussianIntegral(1 - uv.x, v_sigma_uv.x) * //
|
||||
IPGaussianIntegral(1 - uv.y, v_sigma_uv.y);
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
// level of log2(min_radius).
|
||||
|
||||
#include <impeller/constants.glsl>
|
||||
#include <impeller/gaussian.glsl>
|
||||
#include <impeller/texture.glsl>
|
||||
|
||||
uniform sampler2D texture_sampler;
|
||||
@ -46,18 +47,13 @@ in vec2 v_src_texture_coords;
|
||||
|
||||
out vec4 frag_color;
|
||||
|
||||
float Gaussian(float x) {
|
||||
float variance = frag_info.blur_sigma * frag_info.blur_sigma;
|
||||
return exp(-0.5 * x * x / variance) / (kSqrtTwoPi * frag_info.blur_sigma);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 total_color = vec4(0);
|
||||
float gaussian_integral = 0;
|
||||
vec2 blur_uv_offset = frag_info.blur_direction / frag_info.texture_size;
|
||||
|
||||
for (float i = -frag_info.blur_radius; i <= frag_info.blur_radius; i++) {
|
||||
float gaussian = Gaussian(i);
|
||||
float gaussian = IPGaussian(i, frag_info.blur_sigma);
|
||||
gaussian_integral += gaussian;
|
||||
total_color +=
|
||||
gaussian *
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user