Skip to content

Instantly share code, notes, and snippets.

@Rohit-554
Created February 3, 2025 07:28
Show Gist options
  • Select an option

  • Save Rohit-554/e7d0c60602e260ff86825eab881da417 to your computer and use it in GitHub Desktop.

Select an option

Save Rohit-554/e7d0c60602e260ff86825eab881da417 to your computer and use it in GitHub Desktop.
private const val TUNNEL_SHADER_SRC = """
uniform float2 iResolution;
uniform float iTime;
uniform shader composable;
float2x2 rotate2D(float r) {
return float2x2(
cos(r), sin(r),
-sin(r), cos(r)
);
}
float3x3 rotate3D(float angle, float3 axis) {
float3 a = normalize(axis);
float s = sin(angle);
float c = cos(angle);
float r = 1.0 - c;
return float3x3(
a.x * a.x * r + c,
a.y * a.x * r + a.z * s,
a.z * a.x * r - a.y * s,
a.x * a.y * r - a.z * s,
a.y * a.y * r + c,
a.z * a.y * r + a.x * s,
a.x * a.z * r + a.y * s,
a.y * a.z * r - a.x * s,
a.z * a.z * r + c
);
}
half4 main(float2 FC) {
float4 o = float4(0.0);
float2 r = iResolution.xy;
float3 v = float3(1.0, 3.0, 7.0);
float3 p = float3(0.0);
float t = iTime;
float n = 0.0;
float e = 0.0;
float g = 0.0;
float k = t * 0.2;
for (int i = 0; i < 100; i++) {
p = float3((FC.xy - r * 0.5) / r.y * g, g) * rotate3D(k, cos(k + v));
p.z += t;
p = asin(sin(p)) - 3.0;
n = 0.0;
for (int j = 0; j < 9; j++) {
float2x2 rotation = rotate2D(g/8.0);
p.xz = float2(
rotation[0][0] * p.x + rotation[0][1] * p.z,
rotation[1][0] * p.x + rotation[1][1] * p.z
);
p = abs(p);
if (p.x < p.y) {
n += 1.0;
p = p.zxy;
} else {
p = p.zyx;
}
p += p - v;
}
e = max(p.x, p.z) / 1000.0 - 0.01;
g += e;
o.rgb += 0.1/exp(cos(v*g*0.1+n) + 3.0 + 10000.0*e);
}
return half4(o.rgb, 1.0);
}
"""
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
@Composable
fun TunnelShader() {
val shader = remember { RuntimeShader(TUNNEL_SHADER_SRC) }
var time by remember { mutableStateOf(0f) }
LaunchedEffect(Unit) {
while(true) {
time = (System.currentTimeMillis() % 100_000L) / 1_000f
delay(16) // ~60 FPS
}
}
Surface(
modifier = Modifier
.fillMaxSize()
.graphicsLayer {
clip = true
shader.setFloatUniform("iTime", time)
shader.setFloatUniform("iResolution", size.width, size.height)
renderEffect = android.graphics.RenderEffect
.createRuntimeShaderEffect(shader, "composable")
.asComposeRenderEffect()
},
color = MaterialTheme.colorScheme.background
) {
Box(modifier = Modifier.fillMaxSize())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment