Add new parameter: contrast, white point, removed opacity. Update shader: bleed

This commit is contained in:
Kyant0 committed 2025-06-21 18:57:47 +08:00
1 parent 3909d3f72f
commit 2d21396023
13 files changed
+108 -55

No files matched your search

+9 -2
View File
@@ -16,11 +16,18 @@ You mustn't use the shaders in the project for commercial purposes, they are onl
| Inner refraction amount | ✔️ | ✔️ |
| Outer refraction height | ❌ | ❌ |
| Outer refraction amount | ❌ | ❌ |
| Eccentric factor | ✔️ | ✔️ |
| Dispersion height | 🚧 | ❌ |
| Bleed amount | ✔️ | ❌ |
| Bleed blur radius | ✔️ | ❌ |
| Bleed opacity | ✔️ | 🚧 |
| Blur radius | ✔️ | ❌ |
Other extensions:
- Contrast
- White point
- Chroma multiplier
- Eccentric factor
- Dispersion height (🚧)
## Comparisons
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -80,7 +80,7 @@ fun ButtonGroup(
)
}
IconButton(
{ state.configurationMode = ConfigurationMode.Color },
{ state.configurationMode = ConfigurationMode.Colors },
sizes = IconButtonSizes.medium,
colors = IconButtonColors.tonal()
) {
@@ -58,7 +58,7 @@ fun ConfigurationBottomSheet(
) {
Text(
when (state.configurationMode) {
ConfigurationMode.Color -> stringResource(R.string.colors)
ConfigurationMode.Colors -> stringResource(R.string.colors)
ConfigurationMode.Advanced -> stringResource(R.string.advanced_settings)
null -> ""
},
@@ -83,7 +83,7 @@ fun ConfigurationBottomSheet(
Snapshot.withoutReadObservation { state.configurationMode }
}
when (retainedConfigurationMode) {
ConfigurationMode.Color -> {
ConfigurationMode.Colors -> {
SliderChip(
state.blurRadius,
stringResource(R.string.blur_radius),
@@ -91,9 +91,15 @@ fun ConfigurationBottomSheet(
Modifier.fillMaxWidth()
)
SliderChip(
state.opacity,
stringResource(R.string.opacity),
{ Icon(painterResource(R.drawable.opacity_24px)) },
state.contrast,
stringResource(R.string.contrast),
{ Icon(painterResource(R.drawable.contrast_24px)) },
Modifier.fillMaxWidth()
)
SliderChip(
state.whitePoint,
stringResource(R.string.white_point),
{ Icon(painterResource(R.drawable.wb_sunny_24px)) },
Modifier.fillMaxWidth()
)
SliderChip(
@@ -1,6 +1,6 @@
package com.kyant.glass.playground
enum class ConfigurationMode {
Color,
Colors,
Advanced
}
@@ -21,7 +21,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.asComposeRenderEffect
import androidx.compose.ui.graphics.drawscope.translate
import androidx.compose.ui.graphics.graphicsLayer
@@ -157,6 +156,44 @@ fun Preview(state: PreviewState) {
clip = true
shape = RoundedCornerShape(state.cornerRadius.value)
}
.graphicsLayer { // white point & chroma boost
val contrast = state.contrast.value
val whitePoint = state.whitePoint.value
val chromaMultiplier = state.chromaMultiplier.value
if (contrast != 0f || whitePoint != 0f || chromaMultiplier != 1f) {
renderEffect = RenderEffect.createRuntimeShaderEffect(
RuntimeShader(
"""// This file belongs to Kyant. You must not use it without permission.
uniform shader image;
uniform float contrast;
uniform float whitePoint;
uniform float chromaMultiplier;
$colorShaderUtils
half4 main(float2 coord) {
half4 color = image.eval(coord);
color = saturateColor(color, chromaMultiplier);
float3 target = (whitePoint > 0.0) ? float3(1.0) : float3(0.0);
color.rgb = mix(color.rgb, target, abs(whitePoint));
color.rgb = (color.rgb - 0.5) * (1.0 + contrast) + 0.5;
return color;
}"""
).apply {
setFloatUniform("contrast", contrast)
setFloatUniform("whitePoint", whitePoint)
setFloatUniform("chromaMultiplier", chromaMultiplier)
},
"image"
).asComposeRenderEffect()
}
}
.graphicsLayer { // dispersion effect
renderEffect = RenderEffect.createRuntimeShaderEffect(
RuntimeShader(
@@ -261,29 +298,7 @@ fun Preview(state: PreviewState) {
"image"
).asComposeRenderEffect()
}
.graphicsLayer { // chroma boost
renderEffect = RenderEffect.createRuntimeShaderEffect(
RuntimeShader(
"""// This file belongs to Kyant. You must not use it without permission.
uniform shader image;
uniform float chromaMultiplier;
$colorShaderUtils
half4 main(float2 coord) {
half4 color = image.eval(coord);
color = saturateColor(color, chromaMultiplier);
return color;
}
"""
).apply {
setFloatUniform("chromaMultiplier", state.chromaMultiplier.value)
},
"image"
).asComposeRenderEffect()
}
.graphicsLayer { // refraction + bleed effect
.graphicsLayer { // refraction & bleed
val refractionRenderEffect = RenderEffect.createRuntimeShaderEffect(
RuntimeShader(
"""// This file belongs to Kyant. You must not use it without permission.
@@ -302,12 +317,13 @@ fun Preview(state: PreviewState) {
$refractionShaderUtils
half4 main(float2 coord) {
half4 refractedColor = refractionColor(coord, size, cornerRadius, eccentricFactor, refractionHeight, refractionAmount);
half4 color = refractionColor(coord, size, cornerRadius, eccentricFactor, refractionHeight, refractionAmount);
if (bleedOpacity <= 0.0) {
return refractedColor;
return color;
} else {
refractedColor *= 1.0 - bleedOpacity * luma(refractedColor);
return refractedColor;
float luma = luma(color);
color *= 1.0 - bleedOpacity * luma;
return color;
}
}"""
).apply {
@@ -332,26 +348,23 @@ fun Preview(state: PreviewState) {
uniform float cornerRadius;
uniform float eccentricFactor;
uniform float bleedAmount;
uniform float bleedBlurRadius;
uniform float bleedOpacity;
$colorShaderUtils
$refractionShaderUtils
half4 main(float2 coord) {
half4 bleedColor = refractionColor(coord, size, cornerRadius, eccentricFactor, cornerRadius * 3.5, bleedAmount);
return bleedColor;
half4 color = refractionColor(coord, size, cornerRadius, eccentricFactor, cornerRadius * 3.5, bleedAmount);
float luma = luma(color);
color.rgb = mix(color.rgb, half3(1.0), 0.5 * circleMap(1.0 - luma));
return color;
}"""
).apply {
setFloatUniform("size", size.width, size.height)
setFloatUniform("cornerRadius", state.cornerRadius.value.toPx())
setFloatUniform("eccentricFactor", state.eccentricFactor.value)
setFloatUniform("bleedAmount", state.bleedAmount.value.toPx())
setFloatUniform("bleedBlurRadius", state.bleedBlurRadius.value.toPx())
setFloatUniform("bleedOpacity", state.bleedOpacity.value)
},
"image"
)
@@ -397,10 +410,6 @@ fun Preview(state: PreviewState) {
translate(-rect.left, -rect.top) {
drawLayer(graphicsLayer)
}
drawRect(
Color.Black,
alpha = state.opacity.value
)
}
.onGloballyPositioned { layoutCoordinates ->
rect = layoutCoordinates.boundsInParent()
@@ -62,12 +62,19 @@ class PreviewState {
typeConverter = Dp.VectorConverter,
valueLabel = { "${it.value.fastRoundToInt()} dp" }
)
val opacity: LiquidGlassParamValue<Float> =
val contrast: LiquidGlassParamValue<Float> =
LiquidGlassParamValue(
initialValue = 0f,
valueRange = { 0f..0.2f },
valueRange = { -0.5f..0.5f },
typeConverter = Float.VectorConverter,
valueLabel = { "${(it * 100).fastRoundToInt()}%" }
valueLabel = { "%.2f".format(it) }
)
val whitePoint: LiquidGlassParamValue<Float> =
LiquidGlassParamValue(
initialValue = 0f,
valueRange = { -1f..1f },
typeConverter = Float.VectorConverter,
valueLabel = { "%.2f".format(it) }
)
val chromaMultiplier: LiquidGlassParamValue<Float> =
LiquidGlassParamValue(
@@ -167,7 +174,8 @@ class PreviewState {
launch { cornerRadius.reset() }
launch { blurRadius.reset() }
launch { opacity.reset() }
launch { contrast.reset() }
launch { whitePoint.reset() }
launch { chromaMultiplier.reset() }
launch { refractionHeight.reset() }
@@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal"
android:autoMirrored="true">
<path
android:fillColor="@android:color/white"
android:pathData="M480,880Q397,880 324,848.5Q251,817 197,763Q143,709 111.5,636Q80,563 80,480Q80,397 111.5,324Q143,251 197,197Q251,143 324,111.5Q397,80 480,80Q563,80 636,111.5Q709,143 763,197Q817,251 848.5,324Q880,397 880,480Q880,563 848.5,636Q817,709 763,763Q709,817 636,848.5Q563,880 480,880ZM520,797Q639,782 719.5,692.5Q800,603 800,480Q800,357 719.5,267.5Q639,178 520,163L520,797Z"/>
</vector>
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M440,160L440,40L520,40L520,160L440,160ZM440,920L440,800L520,800L520,920L440,920ZM800,520L800,440L920,440L920,520L800,520ZM40,520L40,440L160,440L160,520L40,520ZM748,268L692,212L762,140L820,198L748,268ZM198,820L140,762L212,692L268,748L198,820ZM762,820L692,748L748,692L820,762L762,820ZM212,268L140,198L198,140L268,212L212,268ZM480,720Q380,720 310,650Q240,580 240,480Q240,380 310,310Q380,240 480,240Q580,240 650,310Q720,380 720,480Q720,580 650,650Q580,720 480,720ZM480,640Q547,640 593.5,593.5Q640,547 640,480Q640,413 593.5,366.5Q547,320 480,320Q413,320 366.5,366.5Q320,413 320,480Q320,547 366.5,593.5Q413,640 480,640ZM480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Z"/>
</vector>
+2 -1
View File
@@ -10,6 +10,7 @@
<string name="chroma_multiplier">彩度增强系数</string>
<string name="close">关闭</string>
<string name="colors">颜色</string>
<string name="contrast">对比度</string>
<string name="corner_radius">圆角半径</string>
<string name="disable_unsafe_mode">禁用不安全值</string>
<string name="dispersion_height">色散高度</string>
@@ -17,11 +18,11 @@
<string name="enable_unsafe_mode">启用不安全值</string>
<string name="height">高度</string>
<string name="hide_controls">隐藏控件</string>
<string name="opacity">不透明度</string>
<string name="pick_an_image">选择图像</string>
<string name="refraction_height">折射高度</string>
<string name="refraction_amount">折射量</string>
<string name="reset">重置</string>
<string name="show_controls">显示控件</string>
<string name="width">宽度</string>
<string name="white_point">白点</string>
</resources>
+2 -1
View File
@@ -10,6 +10,7 @@
<string name="chroma_multiplier">Chroma multiplier</string>
<string name="close">Close</string>
<string name="colors">Colors</string>
<string name="contrast">Contrast</string>
<string name="corner_radius">Corner radius</string>
<string name="disable_unsafe_mode">Disable unsafe values</string>
<string name="dispersion_height">Dispersion height</string>
@@ -17,11 +18,11 @@
<string name="enable_unsafe_mode">Enable unsafe values</string>
<string name="height">Height</string>
<string name="hide_controls">Hide controls</string>
<string name="opacity">Opacity</string>
<string name="pick_an_image">Pick an image</string>
<string name="refraction_height">Refraction height</string>
<string name="refraction_amount">Refraction amount</string>
<string name="reset">Reset</string>
<string name="show_controls">Show controls</string>
<string name="width">Width</string>
<string name="white_point">White point</string>
</resources>