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
62 lines
2.0 KiB
TypeScript
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;
|