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

Commit c8db6625 authored by Yein Jo's avatar Yein Jo Committed by Android (Google) Code Review
Browse files

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

parents 9c03e79e 0458f10b
Loading
Loading
Loading
Loading
+32 −3
Original line number Original line Diff line number Diff line
@@ -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));
@@ -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);


@@ -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);
            }
            """
            """
    }
    }
}
}
+28 −19
Original line number Original line Diff line number Diff line
@@ -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 =
@@ -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;
@@ -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. */
+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)
    }
}