Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions impeller/compiler/shader_lib/impeller/constants.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -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
35 changes: 35 additions & 0 deletions impeller/compiler/shader_lib/impeller/gaussian.glsl
Original file line number Diff line number Diff line change
@@ -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) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the meaning of the IP prefix?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's the C style namespacing of shader library functions.

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
27 changes: 5 additions & 22 deletions impeller/entity/shaders/border_mask_blur.frag
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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() {
Expand Down
8 changes: 2 additions & 6 deletions impeller/entity/shaders/gaussian_blur.frag
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 *
Expand Down