threed-garden
Version:
ThreeD Garden: WebGL 3D Environment Interface for Next.JS React TypeScript Three.JS React-Three Physics, 2D Paper.JS; APIs: Apollo GraphQL, WordPress; CSS: Tailwind, Radix-UI; Libraries: FarmBot 3D; AI: OpenAI, DeepSeek
67 lines (54 loc) • 2.05 kB
JSX
import { useRouter } from 'next/router'
import useStore from '#/lib/threed/stores/store'
import { useRef, useState } from 'react'
import * as THREE from 'three'
import { useFrame, extend } from '@react-three/fiber'
import { shaderMaterial } from '@react-three/drei'
import vertex from 'raw-loader!glslify-loader!./glsl/shader.vert'
import fragment from 'raw-loader!glslify-loader!./glsl/shader.frag'
const ColorShiftMaterial = shaderMaterial(
{
time: 0,
color: new THREE.Color(0.07, 0.4, 0.0),
},
vertex,
fragment
)
// This is the 🔑 that HMR will renew if this file is edited
// It works for THREE.ShaderMaterial as well as for drei/shaderMaterial
ColorShiftMaterial.key = THREE.MathUtils.generateUUID()
extend({ ColorShiftMaterial })
const Shader = (props) => {
const { name, args, route } = props
const router = useRouter()
// This reference will give us direct access to the THREE.Mesh object
const meshRef = useRef(null)
// Set up state for the shaderHovered and active state
const [shaderHovered, setShaderHovered] = useState(false)
// Subscribe this component to the render-loop, rotate the mesh every frame
useFrame((state, delta) => {
if (meshRef.current) {
meshRef.current.rotation.x = meshRef.current.rotation.y -= 0.01
}
if (meshRef.current.material) {
meshRef.current.material.uniforms.time.value += Math.sin(delta / 2) * Math.cos(delta / 2)
}
})
// Return the view, these are regular Threejs elements expressed in JSX
return (
<>
<mesh
ref={meshRef}
onClick={() => router.push(route)}
onPointerOver={(e) => setShaderHovered(true)}
onPointerOut={(e) => setShaderHovered(false)}
scale={shaderHovered ? 1.1 : 1}>
<boxGeometry args={[3, 3, 3]} />
<colorShiftMaterial key={ColorShiftMaterial.key} time={3} />
</mesh>
<directionalLight position={[5, 5, 5]} />
<ambientLight />
</>
)
}
export default Shader