sistema-de-chamados/src/components/background-paper-shaders.tsx
2025-10-07 02:26:09 -03:00

125 lines
3.1 KiB
TypeScript

"use client"
import { useRef, useMemo } from "react"
import { useFrame } from "@react-three/fiber"
import * as THREE from "three"
// Custom shader material for advanced effects
const vertexShader = `
uniform float time;
uniform float intensity;
varying vec2 vUv;
varying vec3 vPosition;
void main() {
vUv = uv;
vPosition = position;
vec3 pos = position;
pos.y += sin(pos.x * 10.0 + time) * 0.1 * intensity;
pos.x += cos(pos.y * 8.0 + time * 1.5) * 0.05 * intensity;
gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
}
`
const fragmentShader = `
uniform float time;
uniform float intensity;
uniform vec3 color1;
uniform vec3 color2;
varying vec2 vUv;
varying vec3 vPosition;
void main() {
vec2 uv = vUv;
// Create animated noise pattern
float noise = sin(uv.x * 20.0 + time) * cos(uv.y * 15.0 + time * 0.8);
noise += sin(uv.x * 35.0 - time * 2.0) * cos(uv.y * 25.0 + time * 1.2) * 0.5;
// Mix colors based on noise and position
vec3 color = mix(color1, color2, noise * 0.5 + 0.5);
color = mix(color, vec3(1.0), pow(abs(noise), 2.0) * intensity);
// Add glow effect
float glow = 1.0 - length(uv - 0.5) * 2.0;
glow = pow(glow, 2.0);
gl_FragColor = vec4(color * glow, glow * 0.8);
}
`
export function ShaderPlane({
position,
color1 = "#ff5722",
color2 = "#ffffff",
}: {
position: [number, number, number]
color1?: string
color2?: string
}) {
const mesh = useRef<THREE.Mesh>(null)
const uniforms = useMemo(
() => ({
time: { value: 0 },
intensity: { value: 1.0 },
color1: { value: new THREE.Color(color1) },
color2: { value: new THREE.Color(color2) },
}),
[color1, color2],
)
useFrame((state) => {
if (mesh.current) {
uniforms.time.value = state.clock.elapsedTime
uniforms.intensity.value = 1.0 + Math.sin(state.clock.elapsedTime * 2) * 0.3
}
})
return (
<mesh ref={mesh} position={position}>
<planeGeometry args={[2, 2, 32, 32]} />
<shaderMaterial
uniforms={uniforms}
vertexShader={vertexShader}
fragmentShader={fragmentShader}
transparent
side={THREE.DoubleSide}
/>
</mesh>
)
}
export function EnergyRing({
radius = 1,
position = [0, 0, 0],
}: {
radius?: number
position?: [number, number, number]
}) {
const mesh = useRef<THREE.Mesh>(null)
useFrame((state) => {
if (mesh.current) {
mesh.current.rotation.z = state.clock.elapsedTime
const material = mesh.current.material
if (Array.isArray(material)) {
material.forEach((mat) => {
if ("opacity" in mat) {
mat.opacity = 0.5 + Math.sin(state.clock.elapsedTime * 3) * 0.3
}
})
} else if (material && "opacity" in material) {
material.opacity = 0.5 + Math.sin(state.clock.elapsedTime * 3) * 0.3
}
}
})
return (
<mesh ref={mesh} position={position}>
<ringGeometry args={[radius * 0.8, radius, 32]} />
<meshBasicMaterial color="#ff5722" transparent opacity={0.6} side={THREE.DoubleSide} />
</mesh>
)
}