bigger world + worldborder
TODO: fix teleport glitch when exiting car
This commit is contained in:
103
src/WorldBorder.tsx
Normal file
103
src/WorldBorder.tsx
Normal file
@@ -0,0 +1,103 @@
|
||||
import { useRef, useMemo } from 'react'
|
||||
import { useFrame, useThree } from '@react-three/fiber'
|
||||
import { ShaderMaterial, Vector3, DoubleSide } from 'three'
|
||||
|
||||
export function WorldBorder() {
|
||||
const materialRef = useRef<ShaderMaterial>(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 (
|
||||
<group>
|
||||
{/* North Wall (-Z) */}
|
||||
<mesh position={[0, wallHeight / 2, -halfSize]}>
|
||||
<planeGeometry args={[mapSize, wallHeight]} />
|
||||
<shaderMaterial
|
||||
ref={materialRef}
|
||||
vertexShader={vertexShader}
|
||||
fragmentShader={fragmentShader}
|
||||
uniforms={uniforms}
|
||||
transparent
|
||||
side={DoubleSide}
|
||||
/>
|
||||
</mesh>
|
||||
{/* South Wall (+Z) */}
|
||||
<mesh position={[0, wallHeight / 2, halfSize]}>
|
||||
<planeGeometry args={[mapSize, wallHeight]} />
|
||||
<shaderMaterial
|
||||
vertexShader={vertexShader}
|
||||
fragmentShader={fragmentShader}
|
||||
uniforms={uniforms}
|
||||
transparent
|
||||
side={DoubleSide}
|
||||
/>
|
||||
</mesh>
|
||||
{/* East Wall (+X) */}
|
||||
<mesh position={[halfSize, wallHeight / 2, 0]} rotation={[0, -Math.PI / 2, 0]}>
|
||||
<planeGeometry args={[mapSize, wallHeight]} />
|
||||
<shaderMaterial
|
||||
vertexShader={vertexShader}
|
||||
fragmentShader={fragmentShader}
|
||||
uniforms={uniforms}
|
||||
transparent
|
||||
side={DoubleSide}
|
||||
/>
|
||||
</mesh>
|
||||
{/* West Wall (-X) */}
|
||||
<mesh position={[-halfSize, wallHeight / 2, 0]} rotation={[0, Math.PI / 2, 0]}>
|
||||
<planeGeometry args={[mapSize, wallHeight]} />
|
||||
<shaderMaterial
|
||||
vertexShader={vertexShader}
|
||||
fragmentShader={fragmentShader}
|
||||
uniforms={uniforms}
|
||||
transparent
|
||||
side={DoubleSide}
|
||||
/>
|
||||
</mesh>
|
||||
</group>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user