Files
klz-cables.com/components/home/hero-webgl/Landscape.tsx
Marc Mintel 82bb7240d5
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 6s
Build & Deploy / 🧪 QA (push) Failing after 3m48s
Build & Deploy / 🏗️ Build (push) Has been skipped
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 4s
chore(workspace): add gitea repository url to all packages
2026-02-27 11:27:22 +01:00

62 lines
2.0 KiB
TypeScript

import React, { useMemo } from 'react';
import * as THREE from 'three';
import { createNoise2D } from 'simplex-noise';
import { getTerrainHeight } from './math';
export const Landscape: React.FC<{ seed: number }> = ({ seed }) => {
const geometry = useMemo(() => {
// Generate a very large plane with many segments
const size = 1200;
const segments = 128;
const geo = new THREE.PlaneGeometry(size, size, segments, segments);
geo.rotateX(-Math.PI / 2); // Lay flat on XZ plane
const pos = geo.attributes.position;
const vertex = new THREE.Vector3();
// Recreate same noise instance the Generator used
let rSeed = seed;
const rng = () => {
const x = Math.sin(rSeed++) * 10000;
return x - Math.floor(x);
};
const noise2D = createNoise2D(() => rng());
for (let i = 0; i < pos.count; i++) {
vertex.fromBufferAttribute(pos, i);
// Main height from the math utility so objects match exactly
const h = getTerrainHeight(noise2D, vertex.x, vertex.z);
// Curve down massively at edges to form a "planet" horizon
// If we are at dist R from center, we drop it down smoothly.
const dist = Math.sqrt(vertex.x * vertex.x + vertex.z * vertex.z);
const edgeRadius = 400;
let drop = 0;
if (dist > edgeRadius) {
// Drop quadratically beyond edgeRadius
const d = dist - edgeRadius;
drop = (d * d) * 0.05;
}
pos.setY(i, h - drop);
}
geo.computeVertexNormals();
return geo;
}, [seed]);
return (
<mesh geometry={geometry} receiveShadow>
<meshStandardMaterial
color="#081830" // Dark blueish surface
roughness={0.9}
metalness={0.1}
wireframe={false}
/>
</mesh>
);
};
export default Landscape;