Update chromatic aberration shader

This commit is contained in:
Kyant0 committed 2025-10-10 14:10:49 +08:00
1 parent 1da660c416
commit c6f3a486d4
10 files changed
+41 -46

No files matched your search

@@ -97,7 +97,7 @@ uniform float4 cornerRadii;
uniform float refractionHeight; uniform float refractionHeight;
uniform float refractionAmount; uniform float refractionAmount;
uniform float depthEffect; uniform float depthEffect;
uniform float2 chromaticAberration; uniform float chromaticAberration;
$RoundedRectSDF $RoundedRectSDF
@@ -105,8 +105,10 @@ float circleMap(float x) {
return 1.0 - sqrt(1.0 - x * x); return 1.0 - sqrt(1.0 - x * x);
} }
float dispersionIntensity(float2 normal, int n) { float2 dispersionVec(float2 coord, float2 normal, int n) {
return 1.0 + dot(chromaticAberration, normal) * float(n) / 3.0; float intensity = 1.0 + chromaticAberration * float(n) / 3.0 * (coord.x * coord.y / (size.x * size.y * 0.25));
float2 dir = normal;
return intensity * dir;
} }
half4 main(float2 coord) { half4 main(float2 coord) {
@@ -127,37 +129,37 @@ half4 main(float2 coord) {
half4 color = half4(0.0); half4 color = half4(0.0);
color.a = 0.0; color.a = 0.0;
half4 redColor = content.eval(coord + d * dispersionIntensity(dir, 3) * dir); half4 red = content.eval(coord + d * dispersionVec(centeredCoord, dir, 3));
color.r += redColor.r / 3.5; color.r += red.r / 3.5;
color.a += redColor.a / 7.0; color.a += red.a / 7.0;
half4 orangeColor = content.eval(coord + d * dispersionIntensity(dir, 2) * dir); half4 orange = content.eval(coord + d * dispersionVec(centeredCoord, dir, 2));
color.r += orangeColor.r / 3.5; color.r += orange.r / 3.5;
color.g += orangeColor.g / 7.0; color.g += orange.g / 7.0;
color.a += orangeColor.a / 7.0; color.a += orange.a / 7.0;
half4 yellowColor = content.eval(coord + d * dispersionIntensity(dir, 1) * dir); half4 yellow = content.eval(coord + d * dispersionVec(centeredCoord, dir, 1));
color.r += yellowColor.r / 3.5; color.r += yellow.r / 3.5;
color.g += yellowColor.g / 3.5; color.g += yellow.g / 3.5;
color.a += yellowColor.a / 7.0; color.a += yellow.a / 7.0;
half4 greenColor = content.eval(coord + d * dispersionIntensity(dir, 0) * dir); half4 green = content.eval(coord + d * dispersionVec(centeredCoord, dir, 0));
color.g += greenColor.g / 3.5; color.g += green.g / 3.5;
color.a += greenColor.a / 7.0; color.a += green.a / 7.0;
half4 cyanColor = content.eval(coord + d * dispersionIntensity(dir, -1) * dir); half4 cyan = content.eval(coord + d * dispersionVec(centeredCoord, dir, -1));
color.g += cyanColor.g / 3.5; color.g += cyan.g / 3.5;
color.b += cyanColor.b / 3.0; color.b += cyan.b / 3.0;
color.a += cyanColor.a / 7.0; color.a += cyan.a / 7.0;
half4 blueColor = content.eval(coord + d * dispersionIntensity(dir, -2) * dir); half4 blue = content.eval(coord + d * dispersionVec(centeredCoord, dir, -2));
color.b += blueColor.b / 3.0; color.b += blue.b / 3.0;
color.a += blueColor.a / 7.0; color.a += blue.a / 7.0;
half4 purpleColor = content.eval(coord + d * dispersionIntensity(dir, -3) * dir); half4 purple = content.eval(coord + d * dispersionVec(centeredCoord, dir, -3));
color.r += purpleColor.r / 7.0; color.r += purple.r / 7.0;
color.b += purpleColor.b / 3.0; color.b += purple.b / 3.0;
color.a += purpleColor.a / 7.0; color.a += purple.a / 7.0;
return color; return color;
}""" }"""
@@ -4,7 +4,6 @@ import android.graphics.RenderEffect
import android.os.Build import android.os.Build
import androidx.annotation.FloatRange import androidx.annotation.FloatRange
import androidx.compose.foundation.shape.CornerBasedShape import androidx.compose.foundation.shape.CornerBasedShape
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.util.fastCoerceAtMost import androidx.compose.ui.util.fastCoerceAtMost
import com.kyant.backdrop.BackdropEffectScope import com.kyant.backdrop.BackdropEffectScope
@@ -14,8 +13,8 @@ import com.kyant.backdrop.RoundedRectRefractionWithDispersionShaderString
fun BackdropEffectScope.lens( fun BackdropEffectScope.lens(
@FloatRange(from = 0.0) refractionHeight: Float, @FloatRange(from = 0.0) refractionHeight: Float,
@FloatRange(from = 0.0) refractionAmount: Float, @FloatRange(from = 0.0) refractionAmount: Float,
chromaticAberration: Offset = Offset.Zero, depthEffect: Boolean = false,
depthEffect: Boolean = false chromaticAberration: Boolean = false
) { ) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) return
if (refractionHeight <= 0f || refractionAmount <= 0f) return if (refractionHeight <= 0f || refractionAmount <= 0f) return
@@ -24,7 +23,7 @@ fun BackdropEffectScope.lens(
val effect = val effect =
if (cornerRadii != null) { if (cornerRadii != null) {
val shader = val shader =
if (chromaticAberration == Offset.Zero) { if (!chromaticAberration) {
obtainRuntimeShader("Refraction", RoundedRectRefractionShaderString).apply { obtainRuntimeShader("Refraction", RoundedRectRefractionShaderString).apply {
setFloatUniform("size", size.width, size.height) setFloatUniform("size", size.width, size.height)
setFloatUniform("cornerRadii", cornerRadii) setFloatUniform("cornerRadii", cornerRadii)
@@ -42,7 +41,7 @@ fun BackdropEffectScope.lens(
setFloatUniform("refractionHeight", refractionHeight) setFloatUniform("refractionHeight", refractionHeight)
setFloatUniform("refractionAmount", -refractionAmount) setFloatUniform("refractionAmount", -refractionAmount)
setFloatUniform("depthEffect", if (depthEffect) 1f else 0f) setFloatUniform("depthEffect", if (depthEffect) 1f else 0f)
setFloatUniform("chromaticAberration", chromaticAberration.x, chromaticAberration.y) setFloatUniform("chromaticAberration", 1f)
} }
} }
RenderEffect.createRuntimeShaderEffect(shader, "content") RenderEffect.createRuntimeShaderEffect(shader, "content")
@@ -52,8 +51,6 @@ fun BackdropEffectScope.lens(
effect(effect) effect(effect)
} }
val DefaultChromaticAberration: Offset = Offset(1f / 2f, 1f / 6f)
private val BackdropEffectScope.cornerRadii: FloatArray? private val BackdropEffectScope.cornerRadii: FloatArray?
get() { get() {
val shape = shape as? CornerBasedShape ?: return null val shape = shape as? CornerBasedShape ?: return null
Binary file not shown.
@@ -42,7 +42,6 @@ import com.kyant.backdrop.backdrops.rememberLayerBackdrop
import com.kyant.backdrop.catalog.utils.DampedDragAnimation import com.kyant.backdrop.catalog.utils.DampedDragAnimation
import com.kyant.backdrop.catalog.utils.InteractiveHighlight import com.kyant.backdrop.catalog.utils.InteractiveHighlight
import com.kyant.backdrop.drawBackdrop import com.kyant.backdrop.drawBackdrop
import com.kyant.backdrop.effects.DefaultChromaticAberration
import com.kyant.backdrop.effects.blur import com.kyant.backdrop.effects.blur
import com.kyant.backdrop.effects.lens import com.kyant.backdrop.effects.lens
import com.kyant.backdrop.effects.vibrancy import com.kyant.backdrop.effects.vibrancy
@@ -245,9 +244,9 @@ fun LiquidBottomTabs(
effects = { effects = {
val progress = dampedDragAnimation.pressProgress val progress = dampedDragAnimation.pressProgress
lens( lens(
10f.dp.toPx() * progress,
12f.dp.toPx() * progress, 12f.dp.toPx() * progress,
12f.dp.toPx() * progress, chromaticAberration = true
chromaticAberration = DefaultChromaticAberration
) )
}, },
highlight = { highlight = {
@@ -37,7 +37,6 @@ import com.kyant.backdrop.backdrops.rememberCombinedBackdrop
import com.kyant.backdrop.backdrops.rememberLayerBackdrop import com.kyant.backdrop.backdrops.rememberLayerBackdrop
import com.kyant.backdrop.catalog.utils.DampedDragAnimation import com.kyant.backdrop.catalog.utils.DampedDragAnimation
import com.kyant.backdrop.drawBackdrop import com.kyant.backdrop.drawBackdrop
import com.kyant.backdrop.effects.DefaultChromaticAberration
import com.kyant.backdrop.effects.blur import com.kyant.backdrop.effects.blur
import com.kyant.backdrop.effects.lens import com.kyant.backdrop.effects.lens
import com.kyant.backdrop.highlight.Highlight import com.kyant.backdrop.highlight.Highlight
@@ -171,7 +170,7 @@ fun LiquidSlider(
lens( lens(
10f.dp.toPx() * progress, 10f.dp.toPx() * progress,
14f.dp.toPx() * progress, 14f.dp.toPx() * progress,
chromaticAberration = DefaultChromaticAberration chromaticAberration = true
) )
}, },
highlight = { highlight = {
@@ -36,7 +36,6 @@ import com.kyant.backdrop.backdrops.rememberCombinedBackdrop
import com.kyant.backdrop.backdrops.rememberLayerBackdrop import com.kyant.backdrop.backdrops.rememberLayerBackdrop
import com.kyant.backdrop.catalog.utils.DampedDragAnimation import com.kyant.backdrop.catalog.utils.DampedDragAnimation
import com.kyant.backdrop.drawBackdrop import com.kyant.backdrop.drawBackdrop
import com.kyant.backdrop.effects.DefaultChromaticAberration
import com.kyant.backdrop.effects.blur import com.kyant.backdrop.effects.blur
import com.kyant.backdrop.effects.lens import com.kyant.backdrop.effects.lens
import com.kyant.backdrop.highlight.Highlight import com.kyant.backdrop.highlight.Highlight
@@ -162,7 +161,7 @@ fun LiquidToggle(
lens( lens(
5f.dp.toPx() * progress, 5f.dp.toPx() * progress,
10f.dp.toPx() * progress, 10f.dp.toPx() * progress,
chromaticAberration = DefaultChromaticAberration chromaticAberration = true
) )
}, },
highlight = { highlight = {
@@ -54,7 +54,7 @@ fun GlassPlaygroundContent() {
var cornerRadiusFrac by remember { mutableFloatStateOf(0.5f) } var cornerRadiusFrac by remember { mutableFloatStateOf(0.5f) }
var blurRadiusDp by remember { mutableFloatStateOf(0f) } var blurRadiusDp by remember { mutableFloatStateOf(0f) }
var refractionHeightFrac by remember { mutableFloatStateOf(0.1f) } var refractionHeightFrac by remember { mutableFloatStateOf(0.2f) }
var refractionAmountFrac by remember { mutableFloatStateOf(0.2f) } var refractionAmountFrac by remember { mutableFloatStateOf(0.2f) }
var chromaticAberration by remember { mutableFloatStateOf(0f) } var chromaticAberration by remember { mutableFloatStateOf(0f) }
@@ -74,7 +74,7 @@ fun GlassPlaygroundContent() {
refractionHeight = refractionHeightFrac * minDimension * 0.5f, refractionHeight = refractionHeightFrac * minDimension * 0.5f,
refractionAmount = refractionAmountFrac * minDimension, refractionAmount = refractionAmountFrac * minDimension,
depthEffect = true, depthEffect = true,
chromaticAberration = Offset(chromaticAberration, chromaticAberration) chromaticAberration = chromaticAberration > 0f
) )
}, },
highlight = { Highlight.Plain }, highlight = { Highlight.Plain },
@@ -28,7 +28,6 @@ import com.kyant.backdrop.backdrops.rememberLayerBackdrop
import com.kyant.backdrop.catalog.BackdropDemoScaffold import com.kyant.backdrop.catalog.BackdropDemoScaffold
import com.kyant.backdrop.catalog.utils.LoremIpsum import com.kyant.backdrop.catalog.utils.LoremIpsum
import com.kyant.backdrop.drawBackdrop import com.kyant.backdrop.drawBackdrop
import com.kyant.backdrop.effects.DefaultChromaticAberration
import com.kyant.backdrop.effects.lens import com.kyant.backdrop.effects.lens
import com.kyant.backdrop.shadow.InnerShadow import com.kyant.backdrop.shadow.InnerShadow
import com.kyant.capsule.ContinuousCapsule import com.kyant.capsule.ContinuousCapsule
@@ -89,7 +88,7 @@ fun MagnifierContent() {
8f.dp.toPx(), 8f.dp.toPx(),
24f.dp.toPx(), 24f.dp.toPx(),
depthEffect = true, depthEffect = true,
chromaticAberration = DefaultChromaticAberration chromaticAberration = true
) )
}, },
innerShadow = { InnerShadow(radius = 16f.dp) }, innerShadow = { InnerShadow(radius = 16f.dp) },