|
6 | 6 | #define GAUSSIAN_GLSL_ |
7 | 7 |
|
8 | 8 | #include <impeller/constants.glsl> |
| 9 | +#include <impeller/types.glsl> |
9 | 10 |
|
10 | 11 | /// Gaussian distribution function. |
11 | | -float IPGaussian(float x, float sigma) { |
12 | | - float variance = sigma * sigma; |
13 | | - return exp(-0.5 * x * x / variance) / (kSqrtTwoPi * sigma); |
| 12 | +float16_t IPGaussian(float16_t x, float16_t sigma) { |
| 13 | + float16_t variance = sigma * sigma; |
| 14 | + return exp(-0.5hf * x * x / variance) / (float16_t(kSqrtTwoPi) * sigma); |
14 | 15 | } |
15 | 16 |
|
16 | 17 | /// Abramowitz and Stegun erf approximation. |
17 | | -float IPErf(float x) { |
18 | | - float a = abs(x); |
| 18 | +float16_t IPErf(float16_t x) { |
| 19 | + float16_t a = abs(x); |
19 | 20 | // 0.278393*x + 0.230389*x^2 + 0.078108*x^4 + 1 |
20 | | - float b = (0.278393 + (0.230389 + 0.078108 * a * a) * a) * a + 1.0; |
21 | | - return sign(x) * (1 - 1 / (b * b * b * b)); |
| 21 | + float16_t b = |
| 22 | + (0.278393hf + (0.230389hf + 0.078108hf * a * a) * a) * a + 1.0hf; |
| 23 | + return sign(x) * (1.0hf - 1.0hf / (b * b * b * b)); |
22 | 24 | } |
23 | 25 |
|
24 | 26 | /// Vec2 variation for the Abramowitz and Stegun erf approximation. |
25 | | -vec2 IPVec2Erf(vec2 x) { |
26 | | - vec2 a = abs(x); |
| 27 | +f16vec2 IPVec2Erf(f16vec2 x) { |
| 28 | + f16vec2 a = abs(x); |
27 | 29 | // 0.278393*x + 0.230389*x^2 + 0.078108*x^4 + 1 |
28 | | - vec2 b = (0.278393 + (0.230389 + 0.078108 * a * a) * a) * a + 1.0; |
29 | | - return sign(x) * (1 - 1 / (b * b * b * b)); |
| 30 | + f16vec2 b = (0.278393hf + (0.230389hf + 0.078108hf * a * a) * a) * a + 1.0hf; |
| 31 | + return sign(x) * (1.0hf - 1.0hf / (b * b * b * b)); |
30 | 32 | } |
31 | 33 |
|
32 | 34 | /// The indefinite integral of the Gaussian function. |
33 | 35 | /// Uses a very close approximation of Erf. |
34 | | -float IPGaussianIntegral(float x, float sigma) { |
| 36 | +float16_t IPGaussianIntegral(float16_t x, float16_t sigma) { |
35 | 37 | // ( 1 + erf( x * (sqrt(2) / (2 * sigma) ) ) / 2 |
36 | | - return (1 + IPErf(x * (kHalfSqrtTwo / sigma))) * 0.5; |
| 38 | + return (1.0hf + IPErf(x * (float16_t(kHalfSqrtTwo) / sigma))) * 0.5hf; |
37 | 39 | } |
38 | 40 |
|
39 | 41 | /// Vec2 variation for the indefinite integral of the Gaussian function. |
40 | 42 | /// Uses a very close approximation of Erf. |
41 | | -vec2 IPVec2GaussianIntegral(vec2 x, float sigma) { |
| 43 | +f16vec2 IPVec2GaussianIntegral(f16vec2 x, float16_t sigma) { |
42 | 44 | // ( 1 + erf( x * (sqrt(2) / (2 * sigma) ) ) / 2 |
43 | | - return (1 + IPVec2Erf(x * (kHalfSqrtTwo / sigma))) * 0.5; |
| 45 | + return (1.0hf + IPVec2Erf(x * (float16_t(kHalfSqrtTwo) / sigma))) * 0.5hf; |
44 | 46 | } |
45 | 47 |
|
46 | 48 | /// Simpler (but less accurate) approximation of the Gaussian integral. |
47 | | -vec2 IPVec2FastGaussianIntegral(vec2 x, float sigma) { |
48 | | - return 1 / (1 + exp(-kSqrtThree / sigma * x)); |
| 49 | +f16vec2 IPVec2FastGaussianIntegral(f16vec2 x, float16_t sigma) { |
| 50 | + return 1.0hf / (1.0hf + exp(float16_t(-kSqrtThree) / sigma * x)); |
49 | 51 | } |
50 | 52 |
|
51 | 53 | /// Simple logistic sigmoid with a domain of [-1, 1] and range of [0, 1]. |
52 | | -float IPSigmoid(float x) { |
53 | | - return 1.03731472073 / (1 + exp(-4 * x)) - 0.0186573603638; |
| 54 | +float16_t IPSigmoid(float16_t x) { |
| 55 | + return 1.03731472073hf / (1.0hf + exp(-4.0hf * x)) - 0.0186573603638hf; |
54 | 56 | } |
55 | 57 |
|
56 | 58 | #endif |
0 commit comments