1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.wallpaper.picker.customization.animation.shader 17 18 import android.graphics.RuntimeShader 19 import com.android.systemui.surfaceeffects.shaderutil.ShaderUtilLibrary 20 21 /** Shader that renders sparkles in [CompositeLoadingShader]. */ 22 // TODO (b/281878827): remove this and use loading animation in SystemUIShaderLib when available 23 class SparkleShader : RuntimeShader(SPARKLE_SHADER) { 24 // language=AGSL 25 companion object { 26 private const val UNIFORMS = 27 """ 28 uniform float in_gridNum; 29 uniform vec3 in_noiseMove; 30 uniform vec2 in_size; 31 uniform float in_aspectRatio; 32 uniform half in_time; 33 uniform half in_pixelDensity; 34 layout(color) uniform vec4 in_color; 35 """ 36 private const val MAIN_SHADER = 37 """vec4 main(vec2 p) { 38 vec2 uv = p / in_size.xy; 39 uv.x *= in_aspectRatio; 40 vec3 noiseP = vec3(uv + in_noiseMove.xy, in_noiseMove.z) * in_gridNum; 41 // Inverse luminosity per spec. 42 half luma = 1.0 - getLuminosity(vec3(simplex3d(noiseP))); 43 luma = max(/* intensity= */ 1.75 * luma - /* dim= */ 1.3, 0.); 44 float sparkle = sparkles(p - mod(p, in_pixelDensity * 0.8), in_time); 45 46 return vec4(maskLuminosity(in_color.rgb * sparkle, luma) * in_color.a, in_color.a); 47 } 48 """ 49 private const val SPARKLE_SHADER = UNIFORMS + ShaderUtilLibrary.SHADER_LIB + MAIN_SHADER 50 } 51 52 /** Sets noise move offset in x, y, and z direction. */ setNoiseMovenull53 fun setNoiseMove(x: Float, y: Float, z: Float) { 54 setFloatUniform("in_noiseMove", x, y, z) 55 } 56 57 /** Sets the number of grid for generating noise. */ setGridCountnull58 fun setGridCount(gridNumber: Float = 1.0f) { 59 setFloatUniform("in_gridNum", gridNumber) 60 } 61 62 /** Sets the size of the shader. */ setSizenull63 fun setSize(width: Float, height: Float) { 64 setFloatUniform("in_size", width, height) 65 setFloatUniform("in_aspectRatio", width / java.lang.Float.max(height, 0.001f)) 66 } 67 68 /** Sets the pixel density of the screen. */ setPixelDensitynull69 fun setPixelDensity(pixelDensity: Float) { 70 setFloatUniform("in_pixelDensity", pixelDensity) 71 } 72 setColornull73 fun setColor(color: Int) { 74 setColorUniform("in_color", color) 75 } 76 setTimenull77 fun setTime(time: Float) { 78 setFloatUniform("in_time", time) 79 } 80 } 81