Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 704cb9df authored by Yein Jo's avatar Yein Jo Committed by Automerger Merge Worker
Browse files

Merge "Add fractal noise support in TurbulenceNoiseShader" into udc-dev am: c8db6625

parents cbd4d677 c8db6625
Loading
Loading
Loading
Loading
+32 −3
Original line number Diff line number Diff line
@@ -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);
            }
            """
    }
}
+28 −19
Original line number Diff line number Diff line
@@ -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. */
+39 −0
Original line number 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)
    }
}