呼吸的山地
- 接入
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);
});
- 效果图如下: