12-呼吸的山地

54 阅读1分钟

呼吸的山地

  • 接入simplex-noise
    • https://www.npmjs.com/package/simplex-noise包地址
    • 具体使用查看上面的地址
    • 里面的使用的噪音算法
  • mesh.js
import { createNoise2D } from "simplex-noise";//导入包
import * as THREE from "three";
const geometry = new THREE.PlaneGeometry(1000, 1000, 10, 100);

const noise2D = createNoise2D();
// const positions = geometry.attributes.position;
// 顶点坐标随机
// for (let i = 0; i < positions.count; i++) {
//   positions.setZ(i, Math.random() * 50);
// }

export function updatePosition() {
  const positions = geometry.attributes.position;

  for (let i = 0; i < positions.count; i++) {
    const x = positions.getX(i);
    const y = positions.getY(i);

    const z = noise2D(x / 300, y / 300) * 50;
    //这里让山峰有起伏的感觉, 加入x轴是避免同上同下的问题
    const sinNum = Math.sin(Date.now() * 0.002 + x * 0.05) * 10;

    positions.setZ(i, z + sinNum);
  }
  positions.needsUpdate = true;//更新位置
}

// 自己写的会存在一个问题就是当分段过多的时候不平滑
// for (let i = 0; i < positions.count; i++) {
//   const x = positions.getX(i);
//   const y = positions.getY(i);

//   const z = noise2D(x / 100, y / 100) * 50;//陡峭的
//   const z = noise2D(x / 300, y / 300) * 50; //缓一点的
//   positions.setZ(i, z);
// }
updatePosition();

const material = new THREE.MeshBasicMaterial({
  color: new THREE.Color("orange"),
  wireframe: true,
});

const mesh = new THREE.Mesh(geometry, material);
mesh.rotateX(-Math.PI / 2); //旋转90°

export default mesh;
  • main.js
import * as THREE from "three";
// 导入轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import mesh, { updatePosition } from "./mesh";

const scene = new THREE.Scene();

scene.add(mesh);

const pointLight = new THREE.PointLight(0xffffff, 10000);
pointLight.position.set(80, 80, 80);
scene.add(pointLight);

const width = window.innerWidth;
const height = window.innerHeight;

const camera = new THREE.PerspectiveCamera(60, width / height, 1, 1000);
camera.position.set(400, 150, 100);
camera.lookAt(0, 0, 0);

const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);

function render() {
  updatePosition();//帧动画更细图案
  mesh.rotateZ(0.002);//加点旋转模拟摄像头动态拍摄感觉,也可以改变摄像头的位置试试
  renderer.render(scene, camera);
  requestAnimationFrame(render);
}

render();

document.body.append(renderer.domElement);

const controls = new OrbitControls(camera, renderer.domElement);
controls.addEventListener("change", () => {
  console.log(camera.position);
});
  • 效果图如下: image.png

image.png