• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Source: Android Open Source Project
2// https://cs.android.com/android/_/android/platform/frameworks/base/+/main:graphics/java/android/graphics/drawable/RippleShader.java
3
4uniform vec2 in_origin;
5uniform vec2 in_touch;
6uniform float in_progress;
7uniform float in_maxRadius;
8uniform vec2 in_resolutionScale;
9uniform vec2 in_noiseScale;
10uniform float in_hasMask;
11uniform float in_noisePhase;
12uniform float in_turbulencePhase;
13uniform vec2 in_tCircle1;
14uniform vec2 in_tCircle2;
15uniform vec2 in_tCircle3;
16uniform vec2 in_tRotation1;
17uniform vec2 in_tRotation2;
18uniform vec2 in_tRotation3;
19layout(color) uniform vec4 in_color;
20layout(color) uniform vec4 in_sparkleColor;
21uniform shader in_shader;
22
23float triangleNoise(vec2 n) {
24  n  = fract(n * vec2(5.3987, 5.4421));
25  n += dot(n.yx, n.xy + vec2(21.5351, 14.3137));
26  float xy = n.x * n.y;
27  return fract(xy * 95.4307) + fract(xy * 75.04961) - 1.0;
28}
29const float PI = 3.1415926535897932384626;
30float threshold(float v, float l, float h) {
31    return step(l, v) * (1.0 - step(h, v));
32}
33float sparkles(vec2 uv, float t) {
34  float n = triangleNoise(uv);
35  float s = 0.0;
36  for (float i = 0; i < 4; i += 1) {
37    float l = i * 0.1;
38    float h = l + 0.05;
39    float o = sin(PI * (t + 0.35 * i));
40    s += threshold(n + o, l, h);
41  }
42  return saturate(s) * in_sparkleColor.a;
43}
44float softCircle(vec2 uv, vec2 xy, float radius, float blur) {
45  float blurHalf = blur * 0.5;
46  float d = distance(uv, xy);
47  return 1. - smoothstep(1. - blurHalf, 1. + blurHalf, d / radius);
48}
49float softRing(vec2 uv, vec2 xy, float radius, float progress, float blur) {
50  float thickness = 0.05 * radius;
51  float currentRadius = radius * progress;
52  float circle_outer = softCircle(uv, xy, currentRadius + thickness, blur);
53  float circle_inner = softCircle(uv, xy, max(currentRadius - thickness, 0.),
54    blur);
55  return saturate(circle_outer - circle_inner);
56}
57float subProgress(float start, float end, float progress) {
58    float sub = clamp(progress, start, end);
59    return (sub - start) / (end - start);
60}
61mat2 rotate2d(vec2 rad){
62  return mat2(rad.x, -rad.y, rad.y, rad.x);
63}
64float circle_grid(vec2 resolution, vec2 coord, float time, vec2 center,
65    vec2 rotation, float cell_diameter) {
66  coord = rotate2d(rotation) * (center - coord) + center;
67  coord = mod(coord, cell_diameter) / resolution;
68  float normal_radius = cell_diameter / resolution.y * 0.5;
69  float radius = 0.65 * normal_radius;
70  return softCircle(coord, vec2(normal_radius), radius, radius * 50.0);
71}
72float turbulence(vec2 uv, float t) {
73  const vec2 scale = vec2(0.8);
74  uv = uv * scale;
75  float g1 = circle_grid(scale, uv, t, in_tCircle1, in_tRotation1, 0.17);
76  float g2 = circle_grid(scale, uv, t, in_tCircle2, in_tRotation2, 0.2);
77  float g3 = circle_grid(scale, uv, t, in_tCircle3, in_tRotation3, 0.275);
78  float v = (g1 * g1 + g2 - g3) * 0.5;
79  return saturate(0.45 + 0.8 * v);
80}
81
82vec4 main(vec2 p) {
83    float fadeIn = subProgress(0., 0.13, in_progress);
84    float scaleIn = subProgress(0., 1.0, in_progress);
85    float fadeOutNoise = subProgress(0.4, 0.5, in_progress);
86    float fadeOutRipple = subProgress(0.4, 1., in_progress);
87    vec2 center = mix(in_touch, in_origin, saturate(in_progress * 2.0));
88    float ring = softRing(p, center, in_maxRadius, scaleIn, 1.);
89    float alpha = min(fadeIn, 1. - fadeOutNoise);
90    vec2 uv = p * in_resolutionScale;
91    vec2 densityUv = uv - mod(uv, in_noiseScale);
92    float turbulence = turbulence(uv, in_turbulencePhase);
93    float sparkleAlpha = sparkles(densityUv, in_noisePhase) * ring * alpha * turbulence;
94    float fade = min(fadeIn, 1. - fadeOutRipple);
95    float waveAlpha = softCircle(p, center, in_maxRadius * scaleIn, 1.) * fade * in_color.a;
96    vec4 waveColor = vec4(in_color.rgb * waveAlpha, waveAlpha);
97    vec4 sparkleColor = vec4(in_sparkleColor.rgb * in_sparkleColor.a, in_sparkleColor.a);
98    float mask = in_hasMask == 1. ? in_shader.eval(p).a > 0. ? 1. : 0. : 1.;
99    return mix(waveColor, sparkleColor, sparkleAlpha) * mask;
100}
101