summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Yein Jo <yeinj@google.com> 2023-03-09 21:53:10 +0000
committer Yein Jo <yeinj@google.com> 2023-03-13 17:39:46 +0000
commit0458f10bffa630310934adf61c9eb92537b5b39f (patch)
tree37598f744dece33c51e04f19e16bcbb19128636c
parent73ec965c30a42287ce23ffe1f39f497a55eed957 (diff)
Add fractal noise support in TurbulenceNoiseShader
Bug: 271134655 Test: Manual, atest TurbulenceNoiseShaderTest Change-Id: I7e6cd67a7c8316200be9abbc4ef14b608c6ce882
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaderutil/ShaderUtilLibrary.kt35
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShader.kt47
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShaderTest.kt39
3 files changed, 99 insertions, 22 deletions
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaderutil/ShaderUtilLibrary.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaderutil/ShaderUtilLibrary.kt
index d78e0c153db8..280e7ed9ea2e 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaderutil/ShaderUtilLibrary.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaderutil/ShaderUtilLibrary.kt
@@ -53,6 +53,19 @@ class ShaderUtilLibrary {
cos(p.y * 0.01 + time * 0.005931)) * distort_amount_xy;
}
+ // Perceived luminosity (L′), not absolute luminosity.
+ half getLuminosity(vec3 c) {
+ return 0.3 * c.r + 0.59 * c.g + 0.11 * c.b;
+ }
+
+ // Creates a luminosity mask and clamp to the legal range.
+ vec3 maskLuminosity(vec3 dest, float lum) {
+ dest.rgb *= vec3(lum);
+ // Clip back into the legal range
+ dest = clamp(dest, vec3(0.), vec3(1.0));
+ return dest;
+ }
+
// Return range [-1, 1].
vec3 hash(vec3 p) {
p = fract(p * vec3(.3456, .1234, .9876));
@@ -62,14 +75,14 @@ class ShaderUtilLibrary {
}
// Skew factors (non-uniform).
- const float SKEW = 0.3333333; // 1/3
- const float UNSKEW = 0.1666667; // 1/6
+ const half SKEW = 0.3333333; // 1/3
+ const half UNSKEW = 0.1666667; // 1/6
// Return range roughly [-1,1].
// 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);
@@ -143,6 +156,22 @@ class ShaderUtilLibrary {
// Should multiply by the possible max contribution to adjust the range in [-1,1].
return dot(vec4(32.), nc);
}
+
+ // Random rotations.
+ // The way you create fractal noise is layering simplex noise with some rotation.
+ // To make random cloud looking noise, the rotations should not align. (Otherwise it
+ // creates patterned noise).
+ // Below rotations only rotate in one axis.
+ const mat3 rot1 = mat3(1.0, 0. ,0., 0., 0.15, -0.98, 0., 0.98, 0.15);
+ const mat3 rot2 = mat3(-0.95, 0. ,-0.3, 0., 1., 0., 0.3, 0., -0.95);
+ const mat3 rot3 = mat3(1.0, 0. ,0., 0., -0.44, -0.89, 0., 0.89, -0.44);
+
+ // Octave = 4
+ // Divide each coefficient by 3 to produce more grainy noise.
+ half simplex3d_fractal(vec3 mat) {
+ return 0.675 * simplex3d(mat * rot1) + 0.225 * simplex3d(2.0 * mat * rot2)
+ + 0.075 * simplex3d(4.0 * mat * rot3) + 0.025 * simplex3d(8.0 * mat);
+ }
"""
}
}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShader.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShader.kt
index 7456c4334f0f..0e2266734274 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShader.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShader.kt
@@ -19,8 +19,13 @@ import android.graphics.RuntimeShader
import com.android.systemui.surfaceeffects.shaderutil.ShaderUtilLibrary
import java.lang.Float.max
-/** Shader that renders turbulence simplex noise, with no octave. */
-class TurbulenceNoiseShader : RuntimeShader(TURBULENCE_NOISE_SHADER) {
+/**
+ * Shader that renders turbulence simplex noise, by default no octave.
+ *
+ * @param useFractal whether to use fractal noise (4 octaves).
+ */
+class TurbulenceNoiseShader(useFractal: Boolean = false) :
+ RuntimeShader(if (useFractal) FRACTAL_NOISE_SHADER else SIMPLEX_NOISE_SHADER) {
// language=AGSL
companion object {
private const val UNIFORMS =
@@ -35,21 +40,7 @@ class TurbulenceNoiseShader : RuntimeShader(TURBULENCE_NOISE_SHADER) {
layout(color) uniform vec4 in_backgroundColor;
"""
- private const val SHADER_LIB =
- """
- float getLuminosity(vec3 c) {
- return 0.3*c.r + 0.59*c.g + 0.11*c.b;
- }
-
- vec3 maskLuminosity(vec3 dest, float lum) {
- dest.rgb *= vec3(lum);
- // Clip back into the legal range
- dest = clamp(dest, vec3(0.), vec3(1.0));
- return dest;
- }
- """
-
- private const val MAIN_SHADER =
+ private const val SIMPLEX_SHADER =
"""
vec4 main(vec2 p) {
vec2 uv = p / in_size.xy;
@@ -71,8 +62,26 @@ class TurbulenceNoiseShader : RuntimeShader(TURBULENCE_NOISE_SHADER) {
}
"""
- private const val TURBULENCE_NOISE_SHADER =
- ShaderUtilLibrary.SHADER_LIB + UNIFORMS + SHADER_LIB + MAIN_SHADER
+ private const val FRACTAL_SHADER =
+ """
+ vec4 main(vec2 p) {
+ vec2 uv = p / in_size.xy;
+ uv.x *= in_aspectRatio;
+
+ vec3 noiseP = vec3(uv + in_noiseMove.xy, in_noiseMove.z) * in_gridNum;
+ float luma = simplex3d_fractal(noiseP) * in_opacity;
+ vec3 mask = maskLuminosity(in_color.rgb, luma);
+ vec3 color = in_backgroundColor.rgb + mask * 0.6;
+
+ // Skip dithering.
+ return vec4(color * in_color.a, in_color.a);
+ }
+ """
+
+ private const val SIMPLEX_NOISE_SHADER =
+ ShaderUtilLibrary.SHADER_LIB + UNIFORMS + SIMPLEX_SHADER
+ private const val FRACTAL_NOISE_SHADER =
+ ShaderUtilLibrary.SHADER_LIB + UNIFORMS + FRACTAL_SHADER
}
/** Sets the number of grid for generating noise. */
diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShaderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShaderTest.kt
new file mode 100644
index 000000000000..71bd51174452
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShaderTest.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.surfaceeffects.turbulencenoise
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class TurbulenceNoiseShaderTest : SysuiTestCase() {
+
+ private lateinit var turbulenceNoiseShader: TurbulenceNoiseShader
+
+ @Test
+ fun compliesSimplexNoise() {
+ turbulenceNoiseShader = TurbulenceNoiseShader()
+ }
+
+ @Test
+ fun compliesFractalNoise() {
+ turbulenceNoiseShader = TurbulenceNoiseShader(useFractal = true)
+ }
+}