import { useRef, useMemo } from 'react' import { useFrame, useThree } from '@react-three/fiber' import { ShaderMaterial, Vector3, DoubleSide } from 'three' export function WorldBorder() { const materialRef = useRef(null) const { camera } = useThree() const uniforms = useMemo( () => ({ uPlayerPos: { value: new Vector3() }, uVisibleDistance: { value: 200.0 }, }), [] ) useFrame(() => { if (materialRef.current) { materialRef.current.uniforms.uPlayerPos.value.copy(camera.position) } }) const vertexShader = ` varying vec3 vWorldPos; void main() { vec4 worldPosition = modelMatrix * vec4(position, 1.0); vWorldPos = worldPosition.xyz; gl_Position = projectionMatrix * viewMatrix * worldPosition; } ` const fragmentShader = ` uniform vec3 uPlayerPos; uniform float uVisibleDistance; varying vec3 vWorldPos; void main() { // Calculate distance from player to this fragment float distToPlayer = distance(uPlayerPos, vWorldPos); // Fade based on distance float alpha = 1.0 - smoothstep(0.0, uVisibleDistance, distToPlayer); if (alpha <= 0.0) discard; gl_FragColor = vec4(1.0, 0.0, 0.0, alpha * 0.8); } ` const mapSize = 2500 const halfSize = mapSize / 2 const wallHeight = 100 return ( {/* North Wall (-Z) */} {/* South Wall (+Z) */} {/* East Wall (+X) */} {/* West Wall (-X) */} ) }