export declare const vertexShaderSource = "void main() {\n vUv = uv;\n\n // SCROLLING LOGIC\n // Separate multipliers for wave, color, and flow offsets\n float waveOffset = -u_y_offset * u_y_offset_wave_multiplier;\n float colorOffset = -u_y_offset * u_y_offset_color_multiplier;\n float flowOffset = -u_y_offset * u_y_offset_flow_multiplier;\n\n // 1. DISPLACEMENT (WAVES)\n // We add waveOffset to Y to scroll the wave pattern\n v_displacement_amount = cnoise( vec3(\n u_wave_frequency_x * position.x + u_time,\n u_wave_frequency_y * (position.y + waveOffset) + u_time,\n u_time\n ));\n\n // 2. FLOW FIELD\n // Apply flow offset to scroll the flow field mask\n vec2 baseUv = vUv;\n baseUv.y += flowOffset / u_plane_height; // Scale to match wave speed\n vec2 flowUv = baseUv;\n\n if (u_flow_enabled > 0.5) {\n if (u_flow_ease > 0.0 || u_flow_distortion_a > 0.0) {\n vec2 ppp = -1.0 + 2.0 * baseUv;\n ppp += 0.1 * cos((1.5 * u_flow_scale) * ppp.yx + 1.1 * u_time + vec2(0.1, 1.1));\n ppp += 0.1 * cos((2.3 * u_flow_scale) * ppp.yx + 1.3 * u_time + vec2(3.2, 3.4));\n ppp += 0.1 * cos((2.2 * u_flow_scale) * ppp.yx + 1.7 * u_time + vec2(1.8, 5.2));\n ppp += u_flow_distortion_a * cos((u_flow_distortion_b * u_flow_scale) * ppp.yx + 1.4 * u_time + vec2(6.3, 3.9));\n\n float r = length(ppp);\n flowUv = mix(baseUv, vec2(baseUv.x * (1.0 - u_flow_ease) + r * u_flow_ease, baseUv.y), u_flow_ease);\n }\n }\n\n // Pass the standard flow UV to fragment shader (for texture)\n vFlowUv = flowUv;\n\n // 3. COLOR MIXING\n // We take the computed flow UVs and apply the color offset\n // Scale by plane height to match wave offset speed (world space vs UV space)\n vec3 color = u_colors[0].color;\n // ...\n vec2 adjustedUv = flowUv;\n adjustedUv.y += colorOffset / u_plane_height; // Scroll the color mixing pattern\n\n vec2 noise_cord = adjustedUv * u_color_pressure;\n const float minNoise = .0;\n const float maxNoise = .9;\n\n for (int i = 1; i < 6; i++) {\n if (i < u_colors_count) {\n if (u_colors[i].is_active > 0.5) {\n float noiseFlow = (1. + float(i)) / 30.;\n float noiseSpeed = (1. + float(i)) * 0.11;\n float noiseSeed = 13. + float(i) * 7.;\n\n float noise = snoise(\n vec3(\n noise_cord.x * u_color_pressure.x + u_time * noiseFlow * 2.,\n noise_cord.y * u_color_pressure.y,\n u_time * noiseSpeed\n ) + noiseSeed\n ) - (.1 * float(i)) + (.5 * u_color_blending);\n\n noise = clamp(noise, minNoise, maxNoise + float(i) * 0.02);\n color = mix(color, u_colors[i].color, smoothstep(0.0, u_color_blending, noise));\n }\n }\n }\n\n v_color = color;\n\n // 4. FRESNEL (rim glow)\n // (Calculated in fragment shader using displacement slope approximation)\n\n // 5. VERTEX POSITION\n vec3 newPosition = position + normal * v_displacement_amount * u_wave_amplitude;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(newPosition, 1.0);\n v_new_position = gl_Position;\n}\n"; export declare const fragmentShaderSource = "float random(vec2 p) {\n return fract(sin(dot(p, vec2(12.9898,78.233))) * 43758.5453);\n}\n\nfloat fbm(vec3 x) {\n float value = 0.0;\n float amplitude = 0.5;\n float frequency = 1.0;\n for (int i = 0; i < 4; i++) {\n value += amplitude * snoise(x * frequency);\n frequency *= 2.0;\n amplitude *= 0.5;\n }\n return value;\n}\n\n// Branchless HSL to RGB for iridescence\nvec3 hsl2rgb(float h, float s, float l) {\n vec3 rgb = clamp(abs(mod(h * 6.0 + vec3(0.0, 4.0, 2.0), 6.0) - 3.0) - 1.0, 0.0, 1.0);\n return l + s * (rgb - 0.5) * (1.0 - abs(2.0 * l - 1.0));\n}\n\nvoid main() {\n vec2 finalUv = vFlowUv;\n \n vec3 baseColor;\n\n if (u_enable_procedural_texture > 0.5) {\n vec2 ppp = -1.0 + 2.0 * finalUv;\n ppp += 0.1 * cos((1.5 * u_flow_scale) * ppp.yx + 1.1 * u_time + vec2(0.1, 1.1));\n ppp += 0.1 * cos((2.3 * u_flow_scale) * ppp.yx + 1.3 * u_time + vec2(3.2, 3.4));\n ppp += 0.1 * cos((2.2 * u_flow_scale) * ppp.yx + 1.7 * u_time + vec2(1.8, 5.2));\n ppp += u_flow_distortion_a * cos((u_flow_distortion_b * u_flow_scale) * ppp.yx + 1.4 * u_time + vec2(6.3, 3.9));\n float r = length(ppp);\n \n float vx = (finalUv.x * u_texture_ease) + (r * (1.0 - u_texture_ease));\n float vy = (finalUv.y * u_texture_ease) + (0.0 * (1.0 - u_texture_ease));\n vec2 texUv = vec2(vx, vy);\n\n float parallaxFactor = 0.25;\n texUv.y -= (u_y_offset * u_y_offset_color_multiplier / u_plane_height) * parallaxFactor;\n texUv *= 1.5;\n\n vec4 texSample = texture2D(u_procedural_texture, texUv);\n baseColor = texSample.rgb;\n } else {\n baseColor = v_color;\n }\n\n vec3 color = baseColor;\n\n // === DOMAIN WARPING (simplified: 3 fbm calls instead of 5) ===\n if (u_domain_warp_enabled > 0.5) {\n vec3 p = vec3(finalUv * u_domain_warp_scale, u_time * 0.15);\n vec2 q = vec2(fbm(p), fbm(p + vec3(5.2, 1.3, 0.0)));\n float f = fbm(p + vec3(4.0 * q, 0.0));\n vec3 warpColor = color * (1.0 + f * 0.8 * u_domain_warp_intensity);\n float pattern = clamp(f * f * f + 0.6 * f * f + 0.5 * f, 0.0, 1.0);\n color = mix(color, warpColor * (0.6 + pattern * 0.8), u_domain_warp_intensity * 0.7);\n }\n\n // Post-processing\n color += v_displacement_amount * u_highlights;\n float shadowFactor = 1.0 - v_displacement_amount;\n color -= shadowFactor * shadowFactor * u_shadows;\n color = saturation(color, 1.0 + u_saturation);\n color = color * u_brightness;\n\n // === IRIDESCENCE ===\n if (u_iridescence_enabled > 0.5) {\n float hue = fract(v_displacement_amount * 0.5 + 0.5 + u_time * u_iridescence_speed * 0.05);\n vec3 iriColor = hsl2rgb(hue, 0.8, 0.6);\n color = mix(color, iriColor, u_iridescence_intensity * abs(v_displacement_amount) * 0.6);\n }\n\n // === FRESNEL (Rim glow) ===\n if (u_fresnel_enabled > 0.5) {\n float slope = 1.0 - abs(v_displacement_amount);\n float fresnel = pow(max(slope, 0.0), u_fresnel_power);\n color += u_fresnel_color * fresnel * u_fresnel_intensity;\n }\n\n // === VIGNETTE ===\n if (u_vignette_intensity > 0.0) {\n float dist = length(vUv - vec2(0.5));\n float vig = smoothstep(u_vignette_radius, u_vignette_radius * 0.3, dist);\n color *= mix(1.0, vig, u_vignette_intensity);\n }\n\n // === FAKE BLOOM ===\n if (u_bloom_intensity > 0.0) {\n float luma = dot(color, vec3(0.2126, 0.7152, 0.0722));\n float bloomMask = smoothstep(u_bloom_threshold, 1.0, luma);\n color += color * bloomMask * u_bloom_intensity;\n }\n\n // === CHROMATIC ABERRATION ===\n if (u_chromatic_aberration > 0.0) {\n float caAmount = u_chromatic_aberration * 0.008;\n float dist = length(vUv - vec2(0.5));\n float rShift = v_displacement_amount + caAmount * dist;\n float bShift = v_displacement_amount - caAmount * dist;\n color.r *= 1.0 + rShift * caAmount * 10.0;\n color.b *= 1.0 - bShift * caAmount * 10.0;\n }\n\n // Grain (use cheap hash noise instead of expensive fbm when static)\n float grain = 0.0;\n if (u_grain_intensity > 0.0) {\n vec2 noiseCoords = gl_FragCoord.xy / u_grain_scale;\n if (u_grain_speed != 0.0) {\n grain = fbm(vec3(noiseCoords, u_time * u_grain_speed));\n } else {\n // Static grain: use cheap hash instead of fbm\n grain = random(noiseCoords) - 0.5;\n }\n\n grain = grain * 0.5 + 0.5;\n grain -= 0.5;\n grain = (grain > u_grain_sparsity) ? grain : 0.0;\n grain *= u_grain_intensity;\n }\n\n color += vec3(grain);\n\n gl_FragColor = vec4(color, 1.0);\n}\n"; export declare function buildVertUniforms(): string; export declare function buildFragUniforms(): string; export declare function buildNoise(): string; export declare function buildColorFunctions(): string;