"use client"; import { Canvas, useFrame, useThree } from "@react-three/fiber"; import { useMemo, useRef } from "react"; import * as THREE from "three"; import { cn } from "@/lib/utils"; interface ShaderPlaneProps { vertexShader: string; fragmentShader: string; uniforms: Record; timeMultiplier: number; } const ShaderPlane = ({ vertexShader, fragmentShader, uniforms, timeMultiplier, }: ShaderPlaneProps) => { const meshRef = useRef(null); const { size } = useThree(); useFrame((state) => { if (meshRef.current) { const material = meshRef.current.material as THREE.ShaderMaterial; material.uniforms.u_time.value = state.clock.elapsedTime * timeMultiplier; material.uniforms.u_resolution.value.set(size.width, size.height, 1.0); } }); return ( ); }; interface ShaderBackgroundProps { vertexShader?: string; fragmentShader?: string; uniforms?: Record; className?: string; timeMultiplier?: number; baseColor?: THREE.ColorRepresentation; accent?: THREE.ColorRepresentation; glow?: THREE.ColorRepresentation; } const Shader12 = ({ vertexShader = ` varying vec2 vUv; void main() { vUv = uv; gl_Position = vec4(position, 1.0); } `, fragmentShader = ` precision highp float; varying vec2 vUv; uniform float u_time; uniform vec3 u_resolution; uniform vec3 u_baseColor; uniform vec3 u_accent; uniform vec3 u_glow; #define A(a) mat2(cos(a+vec4(0,11,33,0))) // rotate void mainImage(out vec4 C, vec2 U) { float t = u_time * 6.3; float d = 0.0; float i = d; float s; vec2 R = u_resolution.xy; vec2 m = -vec2(t / 30.0, 0.3); // kamera w spoczynku vec3 o = vec3(0.0, 2.0, -15.0); // kamera vec3 u = normalize(vec3((U - 0.5 * R) / R.y, 0.6)); // kierunek widzenia vec3 c, p, g; mat2 v = A(m.y); // pitch mat2 h = A(m.x); // yaw for (; i++ < 90.0;) { p = o + u * d; p.yz *= v; p.xz *= h; p.y -= pow(length(p.xz), 2.0) * 0.01; p.y += cos(length(round(p.xz)) - t / 5.5); g = abs(p - round(p)); s = max(g.x, max(p.y * -sign(m.y), g.z)) - 0.3; if (s < 0.001 || d > 90.0) break; d += s * 0.2; } vec3 baseColor = u_baseColor; vec3 accent = u_accent; vec3 glow = u_glow; c = mix(baseColor, accent, 2.5 / d); c += glow * 2.9 / (d * 2.0); float vignette = smoothstep(0.8, 0.1, length((U - 0.5 * R) / R.y)); c *= vignette; float noise = fract(sin(dot(U, vec2(12.9898,78.233))) * 43758.5453); c += noise * 0.02; c += 1.*s/d; C = vec4(c, 1.0); } void main() { vec4 fragColor; vec2 fragCoord = vUv * u_resolution.xy; mainImage(fragColor, fragCoord); gl_FragColor = fragColor; } `, uniforms = {}, className, timeMultiplier = 0.8, baseColor = "#020304", accent = "#9a61ff", glow = "#9a23ff", }: ShaderBackgroundProps) => { const baseUniform = useMemo(() => new THREE.Color(baseColor), [baseColor]); const accentUniform = useMemo(() => new THREE.Color(accent), [accent]); const glowUniform = useMemo(() => new THREE.Color(glow), [glow]); const shaderUniforms = useMemo>( () => ({ u_time: { value: 0 }, u_resolution: { value: new THREE.Vector3(1, 1, 1) }, ...(uniforms ?? {}), u_baseColor: { value: baseUniform }, u_accent: { value: accentUniform }, u_glow: { value: glowUniform }, }), [uniforms, baseUniform, accentUniform, glowUniform], ); return (
); }; export { Shader12 };