diff --git a/README.md b/README.md index 694c162..1bed525 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/app/release/app-release.apk b/app/release/app-release.apk index 11f763b..67d76bb 100644 Binary files a/app/release/app-release.apk and b/app/release/app-release.apk differ diff --git a/app/release/baselineProfiles/0/app-release.dm b/app/release/baselineProfiles/0/app-release.dm index 2176b02..14df4e7 100644 Binary files a/app/release/baselineProfiles/0/app-release.dm and b/app/release/baselineProfiles/0/app-release.dm differ diff --git a/app/release/baselineProfiles/1/app-release.dm b/app/release/baselineProfiles/1/app-release.dm index 617234c..0c62357 100644 Binary files a/app/release/baselineProfiles/1/app-release.dm and b/app/release/baselineProfiles/1/app-release.dm differ diff --git a/app/src/main/java/com/kyant/glass/playground/ButtonGroup.kt b/app/src/main/java/com/kyant/glass/playground/ButtonGroup.kt index 8aaa644..ca0a010 100644 --- a/app/src/main/java/com/kyant/glass/playground/ButtonGroup.kt +++ b/app/src/main/java/com/kyant/glass/playground/ButtonGroup.kt @@ -80,7 +80,7 @@ fun ButtonGroup( ) } IconButton( - { state.configurationMode = ConfigurationMode.Color }, + { state.configurationMode = ConfigurationMode.Colors }, sizes = IconButtonSizes.medium, colors = IconButtonColors.tonal() ) { diff --git a/app/src/main/java/com/kyant/glass/playground/ConfigurationBottomSheet.kt b/app/src/main/java/com/kyant/glass/playground/ConfigurationBottomSheet.kt index 9dae0c2..c6023af 100644 --- a/app/src/main/java/com/kyant/glass/playground/ConfigurationBottomSheet.kt +++ b/app/src/main/java/com/kyant/glass/playground/ConfigurationBottomSheet.kt @@ -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( diff --git a/app/src/main/java/com/kyant/glass/playground/ConfigurationMode.kt b/app/src/main/java/com/kyant/glass/playground/ConfigurationMode.kt index 35dc163..8551318 100644 --- a/app/src/main/java/com/kyant/glass/playground/ConfigurationMode.kt +++ b/app/src/main/java/com/kyant/glass/playground/ConfigurationMode.kt @@ -1,6 +1,6 @@ package com.kyant.glass.playground enum class ConfigurationMode { - Color, + Colors, Advanced } diff --git a/app/src/main/java/com/kyant/glass/playground/Preview.kt b/app/src/main/java/com/kyant/glass/playground/Preview.kt index 40f0df8..a24805d 100644 --- a/app/src/main/java/com/kyant/glass/playground/Preview.kt +++ b/app/src/main/java/com/kyant/glass/playground/Preview.kt @@ -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() diff --git a/app/src/main/java/com/kyant/glass/playground/PreviewState.kt b/app/src/main/java/com/kyant/glass/playground/PreviewState.kt index e7b39f3..e088daa 100644 --- a/app/src/main/java/com/kyant/glass/playground/PreviewState.kt +++ b/app/src/main/java/com/kyant/glass/playground/PreviewState.kt @@ -62,12 +62,19 @@ class PreviewState { typeConverter = Dp.VectorConverter, valueLabel = { "${it.value.fastRoundToInt()} dp" } ) - val opacity: LiquidGlassParamValue = + val contrast: LiquidGlassParamValue = 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 = + LiquidGlassParamValue( + initialValue = 0f, + valueRange = { -1f..1f }, + typeConverter = Float.VectorConverter, + valueLabel = { "%.2f".format(it) } ) val chromaMultiplier: LiquidGlassParamValue = 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() } diff --git a/app/src/main/res/drawable/contrast_24px.xml b/app/src/main/res/drawable/contrast_24px.xml new file mode 100644 index 0000000..c45d41b --- /dev/null +++ b/app/src/main/res/drawable/contrast_24px.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/drawable/wb_sunny_24px.xml b/app/src/main/res/drawable/wb_sunny_24px.xml new file mode 100644 index 0000000..b9fa9ea --- /dev/null +++ b/app/src/main/res/drawable/wb_sunny_24px.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index d5c4907..07c08e3 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -10,6 +10,7 @@ 彩度增强系数 关闭 颜色 + 对比度 圆角半径 禁用不安全值 色散高度 @@ -17,11 +18,11 @@ 启用不安全值 高度 隐藏控件 - 不透明度 选择图像 折射高度 折射量 重置 显示控件 宽度 + 白点 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d0b4a74..0eec73f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -10,6 +10,7 @@ Chroma multiplier Close Colors + Contrast Corner radius Disable unsafe values Dispersion height @@ -17,11 +18,11 @@ Enable unsafe values Height Hide controls - Opacity Pick an image Refraction height Refraction amount Reset Show controls Width + White point \ No newline at end of file