Loading packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaderutil/ShaderUtilLibrary.kt +32 −3 Original line number Original line Diff line number Diff line Loading @@ -53,6 +53,19 @@ class ShaderUtilLibrary { cos(p.y * 0.01 + time * 0.005931)) * distort_amount_xy; 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]. // Return range [-1, 1]. vec3 hash(vec3 p) { vec3 hash(vec3 p) { p = fract(p * vec3(.3456, .1234, .9876)); p = fract(p * vec3(.3456, .1234, .9876)); Loading @@ -62,14 +75,14 @@ class ShaderUtilLibrary { } } // Skew factors (non-uniform). // Skew factors (non-uniform). const float SKEW = 0.3333333; // 1/3 const half SKEW = 0.3333333; // 1/3 const float UNSKEW = 0.1666667; // 1/6 const half UNSKEW = 0.1666667; // 1/6 // Return range roughly [-1,1]. // Return range roughly [-1,1]. // It's because the hash function (that returns a random gradient vector) returns // 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 // different magnitude of vectors. Noise doesn't have to be in the precise range thus // skipped normalize. // skipped normalize. float simplex3d(vec3 p) { half simplex3d(vec3 p) { // Skew the input coordinate, so that we get squashed cubical grid // Skew the input coordinate, so that we get squashed cubical grid vec3 s = floor(p + (p.x + p.y + p.z) * SKEW); vec3 s = floor(p + (p.x + p.y + p.z) * SKEW); Loading Loading @@ -143,6 +156,22 @@ class ShaderUtilLibrary { // Should multiply by the possible max contribution to adjust the range in [-1,1]. // Should multiply by the possible max contribution to adjust the range in [-1,1]. return dot(vec4(32.), nc); 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); } """ """ } } } } packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShader.kt +28 −19 Original line number Original line Diff line number Diff line Loading @@ -19,8 +19,13 @@ import android.graphics.RuntimeShader import com.android.systemui.surfaceeffects.shaderutil.ShaderUtilLibrary import com.android.systemui.surfaceeffects.shaderutil.ShaderUtilLibrary import java.lang.Float.max 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 // language=AGSL companion object { companion object { private const val UNIFORMS = private const val UNIFORMS = Loading @@ -35,21 +40,7 @@ class TurbulenceNoiseShader : RuntimeShader(TURBULENCE_NOISE_SHADER) { layout(color) uniform vec4 in_backgroundColor; layout(color) uniform vec4 in_backgroundColor; """ """ private const val SHADER_LIB = private const val SIMPLEX_SHADER = """ 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 = """ """ vec4 main(vec2 p) { vec4 main(vec2 p) { vec2 uv = p / in_size.xy; vec2 uv = p / in_size.xy; Loading @@ -71,8 +62,26 @@ class TurbulenceNoiseShader : RuntimeShader(TURBULENCE_NOISE_SHADER) { } } """ """ private const val TURBULENCE_NOISE_SHADER = private const val FRACTAL_SHADER = ShaderUtilLibrary.SHADER_LIB + UNIFORMS + SHADER_LIB + MAIN_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. */ /** Sets the number of grid for generating noise. */ Loading packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShaderTest.kt 0 → 100644 +39 −0 Original line number Original line Diff line number Diff line /* * 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) } } Loading
packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaderutil/ShaderUtilLibrary.kt +32 −3 Original line number Original line Diff line number Diff line Loading @@ -53,6 +53,19 @@ class ShaderUtilLibrary { cos(p.y * 0.01 + time * 0.005931)) * distort_amount_xy; 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]. // Return range [-1, 1]. vec3 hash(vec3 p) { vec3 hash(vec3 p) { p = fract(p * vec3(.3456, .1234, .9876)); p = fract(p * vec3(.3456, .1234, .9876)); Loading @@ -62,14 +75,14 @@ class ShaderUtilLibrary { } } // Skew factors (non-uniform). // Skew factors (non-uniform). const float SKEW = 0.3333333; // 1/3 const half SKEW = 0.3333333; // 1/3 const float UNSKEW = 0.1666667; // 1/6 const half UNSKEW = 0.1666667; // 1/6 // Return range roughly [-1,1]. // Return range roughly [-1,1]. // It's because the hash function (that returns a random gradient vector) returns // 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 // different magnitude of vectors. Noise doesn't have to be in the precise range thus // skipped normalize. // skipped normalize. float simplex3d(vec3 p) { half simplex3d(vec3 p) { // Skew the input coordinate, so that we get squashed cubical grid // Skew the input coordinate, so that we get squashed cubical grid vec3 s = floor(p + (p.x + p.y + p.z) * SKEW); vec3 s = floor(p + (p.x + p.y + p.z) * SKEW); Loading Loading @@ -143,6 +156,22 @@ class ShaderUtilLibrary { // Should multiply by the possible max contribution to adjust the range in [-1,1]. // Should multiply by the possible max contribution to adjust the range in [-1,1]. return dot(vec4(32.), nc); 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); } """ """ } } } }
packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShader.kt +28 −19 Original line number Original line Diff line number Diff line Loading @@ -19,8 +19,13 @@ import android.graphics.RuntimeShader import com.android.systemui.surfaceeffects.shaderutil.ShaderUtilLibrary import com.android.systemui.surfaceeffects.shaderutil.ShaderUtilLibrary import java.lang.Float.max 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 // language=AGSL companion object { companion object { private const val UNIFORMS = private const val UNIFORMS = Loading @@ -35,21 +40,7 @@ class TurbulenceNoiseShader : RuntimeShader(TURBULENCE_NOISE_SHADER) { layout(color) uniform vec4 in_backgroundColor; layout(color) uniform vec4 in_backgroundColor; """ """ private const val SHADER_LIB = private const val SIMPLEX_SHADER = """ 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 = """ """ vec4 main(vec2 p) { vec4 main(vec2 p) { vec2 uv = p / in_size.xy; vec2 uv = p / in_size.xy; Loading @@ -71,8 +62,26 @@ class TurbulenceNoiseShader : RuntimeShader(TURBULENCE_NOISE_SHADER) { } } """ """ private const val TURBULENCE_NOISE_SHADER = private const val FRACTAL_SHADER = ShaderUtilLibrary.SHADER_LIB + UNIFORMS + SHADER_LIB + MAIN_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. */ /** Sets the number of grid for generating noise. */ Loading
packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShaderTest.kt 0 → 100644 +39 −0 Original line number Original line Diff line number Diff line /* * 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) } }