Merge "Add SparkleShader in the ShaderLib" into udc-qpr-dev
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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.shaders
|
||||
|
||||
import android.graphics.RuntimeShader
|
||||
|
||||
/** Simply renders a solid color. */
|
||||
class SolidColorShader(color: Int) : RuntimeShader(SHADER) {
|
||||
// language=AGSL
|
||||
private companion object {
|
||||
private const val SHADER =
|
||||
"""
|
||||
layout(color) uniform vec4 in_color;
|
||||
vec4 main(vec2 p) {
|
||||
return in_color;
|
||||
}
|
||||
"""
|
||||
}
|
||||
|
||||
init {
|
||||
setColorUniform("in_color", color)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* 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.shaders
|
||||
|
||||
import android.graphics.Color
|
||||
import android.graphics.RuntimeShader
|
||||
import android.graphics.Shader
|
||||
import com.android.systemui.surfaceeffects.shaderutil.ShaderUtilLibrary
|
||||
|
||||
/**
|
||||
* Renders sparkles based on the luma matte.
|
||||
*
|
||||
* For example, you can pass in simplex noise as the luma matte and have a cloud looking sparkles.
|
||||
*
|
||||
* You may want to utilize this shader by: (Preferred) 1. Create a RuntimeShaderEffect and set the
|
||||
* [RenderEffect] to the target [View].
|
||||
* 2. Create a custom [View], set the shader to the [Paint] and use [Canvas.drawPaint] in [onDraw].
|
||||
*/
|
||||
class SparkleShader : RuntimeShader(SPARKLE_SHADER) {
|
||||
// language=AGSL
|
||||
companion object {
|
||||
private const val UNIFORMS =
|
||||
"""
|
||||
// Used it for RenderEffect. For example:
|
||||
// myView.setRenderEffect(
|
||||
// RenderEffect.createRuntimeShaderEffect(SparkleShader(), "in_src")
|
||||
// )
|
||||
uniform shader in_src;
|
||||
uniform half in_time;
|
||||
uniform half in_pixelate;
|
||||
uniform shader in_lumaMatte;
|
||||
layout(color) uniform vec4 in_color;
|
||||
"""
|
||||
private const val MAIN_SHADER =
|
||||
"""vec4 main(vec2 p) {
|
||||
half3 src = in_src.eval(p).rgb;
|
||||
half luma = getLuminosity(in_lumaMatte.eval(p).rgb);
|
||||
half sparkle = sparkles(p - mod(p, in_pixelate), in_time);
|
||||
half3 mask = maskLuminosity(in_color.rgb * sparkle, luma);
|
||||
|
||||
return vec4(src * mask * in_color.a, in_color.a);
|
||||
}
|
||||
"""
|
||||
private const val SPARKLE_SHADER = UNIFORMS + ShaderUtilLibrary.SHADER_LIB + MAIN_SHADER
|
||||
|
||||
/** Highly recommended to use this value unless specified by design spec. */
|
||||
const val DEFAULT_SPARKLE_PIXELATE_AMOUNT = 0.8f
|
||||
}
|
||||
|
||||
init {
|
||||
// Initializes the src and luma matte to be white.
|
||||
setInputShader("in_src", SolidColorShader(Color.WHITE))
|
||||
setLumaMatteColor(Color.WHITE)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the time of the sparkle animation.
|
||||
*
|
||||
* This is used for animating sparkles. Note that this only makes the sparkles sparkle in place.
|
||||
* In order to move the sparkles in x, y directions, move the luma matte input instead.
|
||||
*/
|
||||
fun setTime(time: Float) {
|
||||
setFloatUniform("in_time", time)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets pixelated amount of the sparkle.
|
||||
*
|
||||
* This value *must* be based on [resources.displayMetrics.density]. Otherwise, this will result
|
||||
* in having different sparkle sizes on different screens.
|
||||
*
|
||||
* Expected to be used as follows:
|
||||
* <pre>
|
||||
* {@code
|
||||
* val pixelDensity = context.resources.displayMetrics.density
|
||||
* // Sparkles will be 0.8 of the pixel size.
|
||||
* val sparkleShader = SparkleShader().apply { setPixelateAmount(pixelDensity * 0.8f) }
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
fun setPixelateAmount(pixelateAmount: Float) {
|
||||
setFloatUniform("in_pixelate", pixelateAmount)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the luma matte for the sparkles. The luminosity determines the sparkle's visibility.
|
||||
* Useful for setting a complex mask (e.g. simplex noise, texture, etc.)
|
||||
*/
|
||||
fun setLumaMatte(lumaMatte: Shader) {
|
||||
setInputShader("in_lumaMatte", lumaMatte)
|
||||
}
|
||||
|
||||
/** Sets the luma matte for the sparkles. Useful for setting a solid color. */
|
||||
fun setLumaMatteColor(color: Int) {
|
||||
setInputShader("in_lumaMatte", SolidColorShader(color))
|
||||
}
|
||||
|
||||
/** Sets the color of the sparkles. Expect to have the alpha value encoded. */
|
||||
fun setColor(color: Int) {
|
||||
setColorUniform("in_color", color)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.shaders
|
||||
|
||||
import android.graphics.Color
|
||||
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 SolidColorShaderTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun compilesShader() {
|
||||
SolidColorShader(Color.RED)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.shaders
|
||||
|
||||
import android.graphics.Color
|
||||
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 SparkleShaderTest : SysuiTestCase() {
|
||||
|
||||
private lateinit var sparkleShader: SparkleShader
|
||||
|
||||
@Test
|
||||
fun compilesSparkleShader() {
|
||||
sparkleShader =
|
||||
SparkleShader().apply {
|
||||
setPixelateAmount(
|
||||
context.resources.displayMetrics.density *
|
||||
SparkleShader.DEFAULT_SPARKLE_PIXELATE_AMOUNT
|
||||
)
|
||||
setColor(Color.RED)
|
||||
setTime(0.01f)
|
||||
setLumaMatteColor(Color.WHITE)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user