package com.suno.android.common_ui.components.aura import org.intellij.lang.annotations.Language // cobbled together from nikat's "3d simplex noise" on shadertoy.com // and metal code from suno-ai/adamantium's Simplex3DAura.metal @Language("AGSL") internal const val AURA_FRAGMENT_SHADER = """ uniform vec2 iResolution; // viewport resolution (in pixels) uniform float iTime; // shader playback time (in seconds) uniform float iFractalScale; uniform float iGrainScale; layout(color) uniform half4 iBackgroundColor; layout(color) uniform half4 iColorA; layout(color) uniform half4 iColorB; layout(color) uniform half4 iColorC; uniform half mixPointStart; uniform half mixPointBackground; uniform half mixPointBackgroundA; uniform half mixPointAB; uniform half mixPointBC; uniform half mixPointEnd; /* discontinuous pseudorandom uniformly distributed in [-0.5, +0.5]^3 */ // rng differs from iOS implementation because sin() rounds weird on Pixel GPUs // new rng is new hash33 function from https://www.shadertoy.com/view/4sc3z2 const vec3 MOD3 = vec3(.1031,.11369,.13787); vec3 random3(vec3 p3) { p3 = fract(p3 * MOD3); p3 += dot(p3, p3.yxz+19.19); return -.5 + fract(vec3((p3.x + p3.y)*p3.z, (p3.x+p3.z)*p3.y, (p3.y+p3.z)*p3.x)); } /* skew constants for 3d simplex functions */ const float F3 = 0.3333333; const float G3 = 0.1666667; /* 3d simplex noise */ float simplex3d(vec3 p) { /* 1. find current tetrahedron T and it's four vertices */ /* s, s+i1, s+i2, s+1.0 - absolute skewed (integer) coordinates of T vertices */ /* x, x1, x2, x3 - unskewed coordinates of p relative to each of T vertices*/ /* calculate s and x */ vec3 s = floor(p + dot(p, vec3(F3))); vec3 x = p - s + dot(s, vec3(G3)); /* calculate i1 and i2 */ vec3 e = step(vec3(0.0), x - x.yzx); vec3 i1 = e*(1.0 - e.zxy); vec3 i2 = 1.0 - e.zxy*(1.0 - e); /* x1, x2, x3 */ vec3 x1 = x - i1 + G3; vec3 x2 = x - i2 + 2.0*G3; vec3 x3 = x - 1.0 + 3.0*G3; /* 2. find four surflets and store them in d */ vec4 w, d; /* calculate surflet weights */ w.x = dot(x, x); w.y = dot(x1, x1); w.z = dot(x2, x2); w.w = dot(x3, x3); /* w fades from 0.6 at the center of the surflet to 0.0 at the margin */ w = max(0.6 - w, 0.0); /* calculate surflet components */ d.x = dot(random3(s), x); d.y = dot(random3(s + i1), x1); d.z = dot(random3(s + i2), x2); d.w = dot(random3(s + 1.0), x3); /* multiply d by w^4 */ w *= w; w *= w; d *= w; /* 3. return the sum of the four surflets */ return dot(d, vec4(52.0)); } float simplex3dCircle(float2 p, float r) { return length(p) - r; } /* const matrices for 3d rotation */ const mat3 rot1 = mat3(-0.37, 0.36, 0.85,-0.14,-0.93, 0.34,0.92, 0.01,0.4); const mat3 rot2 = mat3(-0.55,-0.39, 0.74, 0.33,-0.91,-0.24,0.77, 0.12,0.63); const mat3 rot3 = mat3(-0.71, 0.52,-0.47,-0.08,-0.72,-0.68,-0.7,-0.45,0.56); /* directional artifacts can be reduced by rotating each octave */ float simplex3d_fractal(vec3 m) { return 0.5333333*simplex3d(m*rot1) +0.2666667*simplex3d(2.0*m*rot2) +0.1333333*simplex3d(4.0*m*rot3) +0.0666667*simplex3d(8.0*m); } half4 main(in float2 fragCoord){ vec2 p = fragCoord.xy/max(iResolution.x, iResolution.y); vec3 p3 = vec3(p, iTime * 0.1); float value; value = simplex3d_fractal(p3*iFractalScale); value += .1; value = smoothstep(-0.2, 0.3, value); // Grain Noise float3 grain_point3D = vec3(p * iGrainScale, iTime * .01); float grain_value = simplex3d(grain_point3D * 32.0); // Speech Circle float2 circle_point_2D = p; circle_point_2D.x -= 0.5; circle_point_2D.y -= 0.5; float circle_value = simplex3dCircle(circle_point_2D, 1.0); circle_value = 1.0 - smoothstep(0.0, 0.1, circle_value); // Apply Grain value *= circle_value; value = max(0.1 * circle_value, value); grain_value += 2.0 * value; value *= grain_value; half4 blendedColor; if (value <= mixPointBackground) { float t = smoothstep(mixPointStart, mixPointBackground, value); blendedColor = mix(iBackgroundColor, iColorA, t); } else if (value <= mixPointAB) { float t = smoothstep(mixPointBackgroundA, mixPointAB, value); blendedColor = mix(iColorA, iColorB, t); } else { float t = smoothstep(mixPointBC, mixPointEnd, value); blendedColor = mix(iColorB, iColorC, t); } return blendedColor; } """