Skip to content

Instantly share code, notes, and snippets.

@ardakazanci
Created August 4, 2026 15:12
Show Gist options
  • Select an option

  • Save ardakazanci/e378c47a3c90e00f25da1adfc8ba01eb to your computer and use it in GitHub Desktop.

Select an option

Save ardakazanci/e378c47a3c90e00f25da1adfc8ba01eb to your computer and use it in GitHub Desktop.
Cinematic neon court shader for Android RuntimeShader, featuring parallax depth, animated portals, plasma lighting, scanlines, and chromatic aberration.
uniform float2 resolution;
uniform float time;
uniform float sideIndex;
uniform float ballY;
uniform float linked;
uniform float2 cameraOffset;
uniform float cameraZoom;
uniform float aberration;
uniform float ballLocalX;
uniform float depthIntensity;
float gridLine(float value, float density, float width) {
float cell = abs(fract(value * density) - 0.5);
return 1.0 - smoothstep(width, width + 0.045, cell);
}
half4 main(float2 fragCoord) {
float2 rawUv = fragCoord / resolution;
float zoomDelta = cameraZoom - 1.0;
float2 farUv =
(rawUv - 0.5 - cameraOffset * 0.18) /
(1.0 + zoomDelta * 0.18) + 0.5;
float2 midUv =
(rawUv - 0.5 - cameraOffset * 0.52) /
(1.0 + zoomDelta * 0.52) + 0.5;
float2 uv =
(rawUv - 0.5 - cameraOffset * 0.86) /
(1.0 + zoomDelta * 0.86) + 0.5;
float2 centered =
(midUv * resolution * 2.0 - resolution) /
min(resolution.x, resolution.y);
float2 screenCentered =
(fragCoord * 2.0 - resolution) /
min(resolution.x, resolution.y);
half3 cyan = half3(0.02, 0.88, 1.0);
half3 pink = half3(1.0, 0.08, 0.62);
half3 accent = mix(
cyan,
pink,
half(sideIndex)
);
half3 secondary = mix(
half3(0.54, 1.0, 0.18),
half3(1.0, 0.56, 0.08),
half(sideIndex)
);
float plasma =
0.5 + 0.5 * sin(
farUv.y * 11.0 +
sin(farUv.x * 5.0 - time * 0.65) * 1.25 +
time * 1.2
);
float farGridX = gridLine(
farUv.x,
7.0,
0.012
);
float farCurve = farUv.x - 0.5;
float farGridY = gridLine(
farUv.y +
farCurve * farCurve * 0.02 +
time * 0.007,
10.0,
0.011
);
float farGrid =
max(farGridX, farGridY) *
0.032 *
depthIntensity;
float gridX = gridLine(
midUv.x,
11.0,
0.017
);
float gridY = gridLine(
midUv.y +
centered.x * centered.x * 0.038 +
time * 0.018,
17.0,
0.016
);
float grid =
max(gridX, gridY) *
(0.045 + linked * 0.035);
float fromPortal =
sideIndex < 0.5
? 1.0 - uv.x
: uv.x;
float portal =
1.0 - smoothstep(
0.0,
0.34,
fromPortal
);
float portalWave =
0.5 + 0.5 * sin(
uv.y * 52.0 -
time * 8.0 +
ballY * 12.0
);
portal *=
0.42 +
portalWave * 0.58;
float beamDistance =
abs(uv.y - ballY);
float beam =
(1.0 - smoothstep(
0.0,
0.22,
beamDistance
)) *
portal *
linked;
float2 focusVector =
uv - float2(
ballLocalX,
ballY
);
float focusDistance =
dot(
focusVector,
focusVector
);
float focalLight =
(1.0 - smoothstep(
0.002,
0.09,
focusDistance
)) *
depthIntensity;
float horizon =
(1.0 - smoothstep(
0.0,
0.24,
abs(midUv.y - 0.52)
)) *
depthIntensity;
float scan =
step(
0.62,
fract(
fragCoord.y * 0.31 +
time * 1.8
)
);
float vignetteDistance =
dot(
screenCentered * float2(0.68, 0.46),
screenCentered * float2(0.68, 0.46)
);
float vignette =
1.0 - smoothstep(
0.2,
1.2,
vignetteDistance
);
half3 color =
half3(0.003, 0.006, 0.018);
color +=
accent *
half(
plasma * 0.085 +
grid
);
color +=
secondary *
half(
farGrid +
portal * 0.15 +
beam * 0.18
);
color +=
accent *
half(
horizon * 0.022 +
focalLight * 0.055
);
color +=
accent *
half(scan * 0.012);
float redSplit = gridLine(
uv.x + aberration * 0.0035,
11.0,
0.012
);
float blueSplit = gridLine(
uv.x - aberration * 0.0035,
11.0,
0.012
);
color.r += half(
redSplit *
aberration *
0.045
);
color.b += half(
blueSplit *
aberration *
0.055
);
color *= half(
0.36 +
vignette * 0.84
);
return half4(color, 1.0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment