Skip to content

Instantly share code, notes, and snippets.

@aaaa-zhen
Created December 22, 2024 14:44
Show Gist options
  • Select an option

  • Save aaaa-zhen/e67921348c5b021a14bb0d3b06e23ea6 to your computer and use it in GitHub Desktop.

Select an option

Save aaaa-zhen/e67921348c5b021a14bb0d3b06e23ea6 to your computer and use it in GitHub Desktop.
Meatball
val MetaballShader = """
uniform float2 resolution;
uniform shader image;
uniform float time;
half4 main(vec2 fragCoord) {
float2 uv = fragCoord/resolution.xy;
float aspect = resolution.x/resolution.y;
float2 adjustedUV = float2(uv.x * aspect - aspect*0.5, uv.y - 0.5);
float movement = 0.15 * sin(time);
float d1 = length(adjustedUV - float2(movement, 0.0));
float d2 = length(adjustedUV + float2(movement, 0.0));
float metaball = 1.0/(d1*20.0) + 1.0/(d2*20.0);
metaball = metaball * 0.5;
float final = smoothstep(0.5, 0.5, metaball);
return half4(final, final, final, 1);
}
""".trimIndent()
@Preview
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
@Composable
fun Metaball() {
val shader = remember { RuntimeShader(MetaballShader) }
var time by remember { mutableStateOf(0f) }
LaunchedEffect(Unit) {
while(true) {
withFrameNanos { frameTime ->
time = (frameTime / 1_000_000_000f) // 转换纳秒到秒
}
}
}
Column(
modifier = Modifier
.fillMaxSize()
.background(Color.DarkGray)
.padding(16.dp)
) {
Box(
modifier = Modifier
.weight(1f)
.fillMaxWidth()
.onSizeChanged { size ->
shader.setFloatUniform(
"resolution",
size.width.toFloat(),
size.height.toFloat()
)
}
.graphicsLayer {
renderEffect = RenderEffect
.createRuntimeShaderEffect(
shader.apply {
setFloatUniform("time", time)
},
"image"
)
.asComposeRenderEffect()
}
.background(Color.White)
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment