Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 206ef0f

Browse files
authored
[Impeller] Move gaussian routines into the shader library (#37037)
1 parent fc87b5c commit 206ef0f

File tree

5 files changed

+46
-28
lines changed

5 files changed

+46
-28
lines changed

ci/licenses_golden/licenses_flutter

+1
Original file line numberDiff line numberDiff line change
@@ -1107,6 +1107,7 @@ FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/blending.glsl
11071107
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/branching.glsl
11081108
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/color.glsl
11091109
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/constants.glsl
1110+
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/gaussian.glsl
11101111
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/texture.glsl
11111112
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/transform.glsl
11121113
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/types.glsl

impeller/compiler/shader_lib/impeller/constants.glsl

+3
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,7 @@ const float k1Over2Pi = 0.1591549430918;
1313
// sqrt(2 * pi)
1414
const float kSqrtTwoPi = 2.50662827463;
1515

16+
// sqrt(2) / 2 == 1 / sqrt(2)
17+
const float kHalfSqrtTwo = 0.70710678118;
18+
1619
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#ifndef GAUSSIAN_GLSL_
6+
#define GAUSSIAN_GLSL_
7+
8+
#include <impeller/constants.glsl>
9+
10+
float IPGaussian(float x, float sigma) {
11+
float variance = sigma * sigma;
12+
return exp(-0.5 * x * x / variance) / (kSqrtTwoPi * sigma);
13+
}
14+
15+
/// Abramowitz and Stegun erf approximation.
16+
float IPErf(float x) {
17+
float a = abs(x);
18+
// 0.278393*x + 0.230389*x^2 + 0.078108*x^4 + 1
19+
float b = (0.278393 + (0.230389 + 0.078108 * a * a) * a) * a + 1.0;
20+
return sign(x) * (1 - 1 / (b * b * b * b));
21+
}
22+
23+
vec2 IPVec2Erf(vec2 x) {
24+
return vec2(IPErf(x.x), IPErf(x.y));
25+
}
26+
27+
/// Indefinite integral of the Gaussian function (with constant range 0->1).
28+
float IPGaussianIntegral(float x, float sigma) {
29+
// ( 1 + erf( x * (sqrt(2) / (2 * sigma) ) ) / 2
30+
// Because this sigmoid is always > 1, we remap it (n * 1.07 - 0.07)
31+
// so that it always fades to zero before it reaches the blur radius.
32+
return 0.535 * IPErf(x * (kHalfSqrtTwo / sigma)) + 0.465;
33+
}
34+
35+
#endif

impeller/entity/shaders/border_mask_blur.frag

+5-22
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5+
#include <impeller/gaussian.glsl>
56
#include <impeller/texture.glsl>
67

78
// Constant time mask blur for image borders.
@@ -27,30 +28,12 @@ in float v_outer_blur_factor;
2728

2829
out vec4 frag_color;
2930

30-
// Abramowitz and Stegun erf approximation.
31-
float erf(float x) {
32-
float a = abs(x);
33-
// 0.278393*x + 0.230389*x^2 + 0.078108*x^4 + 1
34-
float b = (0.278393 + (0.230389 + 0.078108 * a * a) * a) * a + 1.0;
35-
return sign(x) * (1 - 1 / (b * b * b * b));
36-
}
37-
38-
const float kHalfSqrtTwo = 0.70710678118;
39-
40-
// Indefinite integral of the Gaussian function (with constant range 0->1).
41-
float GaussianIntegral(float x, float sigma) {
42-
// ( 1 + erf( x * (sqrt(2) / (2 * sigma) ) ) / 2
43-
// Because this sigmoid is always > 1, we remap it (n * 1.07 - 0.07)
44-
// so that it always fades to zero before it reaches the blur radius.
45-
return 0.535 * erf(x * (kHalfSqrtTwo / sigma)) + 0.465;
46-
}
47-
4831
float BoxBlurMask(vec2 uv) {
4932
// LTRB
50-
return GaussianIntegral(uv.x, v_sigma_uv.x) * //
51-
GaussianIntegral(uv.y, v_sigma_uv.y) * //
52-
GaussianIntegral(1 - uv.x, v_sigma_uv.x) * //
53-
GaussianIntegral(1 - uv.y, v_sigma_uv.y);
33+
return IPGaussianIntegral(uv.x, v_sigma_uv.x) * //
34+
IPGaussianIntegral(uv.y, v_sigma_uv.y) * //
35+
IPGaussianIntegral(1 - uv.x, v_sigma_uv.x) * //
36+
IPGaussianIntegral(1 - uv.y, v_sigma_uv.y);
5437
}
5538

5639
void main() {

impeller/entity/shaders/gaussian_blur.frag

+2-6
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
// level of log2(min_radius).
1515

1616
#include <impeller/constants.glsl>
17+
#include <impeller/gaussian.glsl>
1718
#include <impeller/texture.glsl>
1819

1920
uniform sampler2D texture_sampler;
@@ -46,18 +47,13 @@ in vec2 v_src_texture_coords;
4647

4748
out vec4 frag_color;
4849

49-
float Gaussian(float x) {
50-
float variance = frag_info.blur_sigma * frag_info.blur_sigma;
51-
return exp(-0.5 * x * x / variance) / (kSqrtTwoPi * frag_info.blur_sigma);
52-
}
53-
5450
void main() {
5551
vec4 total_color = vec4(0);
5652
float gaussian_integral = 0;
5753
vec2 blur_uv_offset = frag_info.blur_direction / frag_info.texture_size;
5854

5955
for (float i = -frag_info.blur_radius; i <= frag_info.blur_radius; i++) {
60-
float gaussian = Gaussian(i);
56+
float gaussian = IPGaussian(i, frag_info.blur_sigma);
6157
gaussian_integral += gaussian;
6258
total_color +=
6359
gaussian *

0 commit comments

Comments
 (0)