Sync simplex artifact fix
Weathereffects copied over simplex3d that has some recent regression
where it shows skewed grid artifacts. 2D flow noise is also fixed, even
though the artifacts bug has yet to be raised. It is observed (by me)
that it shows the same artifacts on some platforms. To mitigate this
issue that happens due to floating point precision, 2D flow noise hash
function is also converted to integer based.
Bug: 315533269
Test: visually inspect
Flag: NA
Change-Id: Iff8b488a6979fa57acb81685d505f4d0a0955072
diff --git a/weathereffects/assets/shaders/simplex2d.agsl b/weathereffects/assets/shaders/simplex2d.agsl
index 0ec3316..de7e271 100644
--- a/weathereffects/assets/shaders/simplex2d.agsl
+++ b/weathereffects/assets/shaders/simplex2d.agsl
@@ -30,6 +30,23 @@
return vec2(cos(theta), sin(theta));
}
+int imod(int a, int b) {
+ return a - (b * (a / b));
+}
+
+// 2D hash without bit-wise operations
+vec2 hash(vec2 p) {
+ int a = int(p.x + p.y) * 15823;
+ int b = a * 65536; // a << 16
+
+ a = imod((10 - imod((a + b), 10)), 10); // a ^ b = (base - (a + b) % base) % base
+ a = (a * (a * a * 38833 + 683873) + 19734581);
+ a /= 65536; // a >> 16
+
+ float af = float(a);
+ return vec2(cos(af), sin(af));
+}
+
// Returns kernel summation from the given simplex vertices (v0, v1, v2), and their corresponding
// gradients (g0, g1, g2).
float kernel_summation(vec2 v0, vec2 v1, vec2 v2, vec2 g0, vec2 g1, vec2 g2) {
diff --git a/weathereffects/assets/shaders/simplex3d.agsl b/weathereffects/assets/shaders/simplex3d.agsl
index 7c696f9..7a178c4 100644
--- a/weathereffects/assets/shaders/simplex3d.agsl
+++ b/weathereffects/assets/shaders/simplex3d.agsl
@@ -17,13 +17,35 @@
// Copied from frameworks/base/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/
// shaderutil/ShaderUtilLibrary.kt
-// Return range [-1, 1].
-vec3 hash(vec3 p) {
- p = fract(p * vec3(.3456, .1234, .9876));
- p += dot(p, p.yxz + 43.21);
- p = (p.xxy + p.yxx) * p.zyx;
- return (fract(sin(p) * 4567.1234567) - .5) * 2.;
+// Integer mod.
+int imod(int a, int b) {
+ return a - (b * (a / b));
}
+
+ivec3 imod(ivec3 a, int b) {
+ return ivec3(imod(a.x, b), imod(a.y, b), imod(a.z, b));
+}
+
+// Integer based hash function with the return range of [-1, 1].
+vec3 hash(vec3 p) {
+ ivec3 v = ivec3(p);
+ v = v * 1671731 + 10139267;
+
+ v.x += v.y * v.z;
+ v.y += v.z * v.x;
+ v.z += v.x * v.y;
+
+ ivec3 v2 = v / 65536; // v >> 16
+ v = imod((10 - imod((v + v2), 10)), 10); // v ^ v2
+
+ v.x += v.y * v.z;
+ v.y += v.z * v.x;
+ v.z += v.x * v.y;
+
+ // Use sin and cos to map the range to [-1, 1].
+ return vec3(sin(float(v.x)), cos(float(v.y)), sin(float(v.z)));
+}
+
// Skew factors (non-uniform).
const float SKEW = 0.3333333; // 1/3
const float UNSKEW = 0.1666667; // 1/6
@@ -32,7 +54,7 @@
// It's because the hash function (that returns a random gradient vector) returns
// different magnitude of vectors. Noise doesn't have to be in the precise range thus
// skipped normalize.
-float simplex3d(vec3 p) {
+half simplex3d(vec3 p) {
// Skew the input coordinate, so that we get squashed cubical grid
vec3 s = floor(p + (p.x + p.y + p.z) * SKEW);