Merge "Add fractal noise support in TurbulenceNoiseShader" into udc-dev
This commit is contained in:
@@ -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);
|
||||
}
|
||||
"""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user