-
-
Save Rahkeen/9d1deda69e56f45fe5db22e179b48d5e to your computer and use it in GitHub Desktop.
Art of Code Rainy Window - Adapted for Android
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Language("AGSL") | |
val rainyWindow = """ | |
uniform float2 resolution; | |
uniform float time; | |
uniform shader composable; | |
const float twopi = 6.2831; | |
// smoothstep alias | |
float S(float a, float b, float t) { | |
return smoothstep(a, b, t); | |
} | |
// pseudo random value, takes a point and returns a float | |
float N21(float2 p) { | |
p = fract(p*float2(123.34, 345.45)); | |
p += dot(p, p+34.345); | |
return fract(p.x*p.y); | |
} | |
half4 main(float2 coord) { | |
// initializing things | |
float2 uv = coord.xy / resolution.y; | |
float2 uv0 = uv; | |
half3 color = half3(0.0); | |
float t = mod(time, 7200); | |
// gives us longer rectangles to work with | |
float2 aspect = float2(2, 1); | |
// invert y coordinates to follow along better | |
uv.y = 1.0 - uv.y; | |
// increase the range of values so that we can make a grid | |
uv *= 3.0 * aspect; | |
// globally moves coords down, this will conteract the oscillating of the | |
float yShift = t * 0.25; | |
uv.y += yShift; | |
// create the grid | |
float2 grid_pos = fract(uv) - 0.5; | |
float2 grid_id = floor(uv); | |
float n = N21(grid_id); // random value from 0..2pi | |
t += n * twopi; | |
// creating the horizontal movement | |
float w = uv0.y * 10; | |
float x = (n - 0.5) * 0.8; // random value from -0.4..0.4 | |
// function for the drop wiggling as it goes down | |
// if the drop is close to the edge of its cell, it will wiggle less. | |
x += (0.4 - abs(x)) * sin(3.0 * w) * pow(sin(w), 6.0) * 0.45; | |
// creating the vertical movement | |
// this moves the drop down | |
float y = -sin(t + sin(t + sin(t) * 0.5)) * 0.45; | |
// this helps make the drop shape by distorting the y | |
float dropShape = dot(grid_pos.x - x, grid_pos.x - x); | |
y -= dropShape; | |
// place the drop | |
float2 dropPos = (grid_pos-float2(x,y)) / aspect; | |
float drop = S(0.05, 0.03, length(dropPos)); | |
// place the trail of drops | |
float2 trailPos = (grid_pos-float2(x,yShift)) / aspect; | |
trailPos.y = (fract(trailPos.y * 8.0) - 0.5) / 8.0; | |
float trail = S(0.03, 0.01, length(trailPos)); | |
// makes sure that drops appear above main drop only | |
trail *= S(-0.05, 0.05, dropPos.y); | |
// fade out the drops | |
trail *= S(0.5, y, grid_pos.y); | |
color += trail; | |
color += drop; | |
// using out water drop mask as a texture on the original component | |
float2 offset = float2(drop*dropPos + trail*trailPos); | |
offset *= resolution; | |
// comment this out to see just the texture | |
color = composable.eval(coord+(offset*-5)).rgb; | |
// uncomment this show the grid lines | |
// if (grid_pos.x > 0.48 || grid_pos.y > 0.49) color = half3(1.0, 0.0, 0.0); | |
return half4(color, 1.0); | |
} | |
""".trimIndent() | |
@Preview | |
@Composable | |
fun RainyWindowPreview() { | |
// a simple timer that can drive the animation | |
var time by remember { mutableStateOf(0f) } | |
LaunchedEffect(Unit) { | |
do { | |
withFrameMillis { | |
time += 0.01f | |
} | |
} while (true) | |
} | |
// setup our shader to use | |
val shader = remember { RuntimeShader(rainyWindow) } | |
// replace this with a Box or use any image of your choice | |
Image( | |
modifier = Modifier | |
.graphicsLayer { | |
with(shader) { | |
setFloatUniform( | |
"resolution", | |
size.width, | |
size.height | |
) | |
setFloatUniform( | |
"time", | |
time | |
) | |
} | |
renderEffect = RenderEffect | |
.createRuntimeShaderEffect( | |
shader, | |
"composable" | |
) | |
.asComposeRenderEffect() | |
} | |
.fillMaxWidth() | |
.aspectRatio(1f), | |
painter = painterResource(id = R.drawable.bird), | |
contentScale = ContentScale.Crop, | |
contentDescription = "Bird" | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment