<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>19_使用高度映射创建地形</title>
<link href="../css/index.css" rel="stylesheet" />
<script src="../libs/three.js"></script>
<script src="../libs/OrbitControls.js"></script>
</head>
<body>
<script>
var scene = new THREE.Scene();
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0x000000, 1.0);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000);
camera.position.set(1200, 500, 1200);
camera.lookAt(scene.position);
var light = new THREE.DirectionalLight(0xffffff);
scene.add(light);
light.position.set(1200, 1200, 1200);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.maxPolarAngle = Math.PI * 0.5;
// 创建地形
var depth = 512;
var width = 512;
var spacingX = 3;
var spacingZ = 3;
var heightOffset = 2;
// canvas
var canvas = document.createElement('canvas');
canvas.width = 512;
canvas.height = 512;
var ctx = canvas.getContext('2d');
// img
var img = new Image();
img.src = "../assets/other/grandcanyon.png";
img.onload = function () {
// draw on canvas
debugger;
ctx.drawImage(img, 0, 0);
var pixel = ctx.getImageData(0, 0, width, depth);
var geom = new THREE.Geometry();
var output = [];
for (var x = 0; x < depth; x++) {
for (var z = 0; z < width; z++) {
// get pixel
// since we're grayscale, we only need one element
var yValue = pixel.data[z * 4 + (depth * x * 4)] / heightOffset;
var vertex = new THREE.Vector3(x * spacingX, yValue, z * spacingZ);
geom.vertices.push(vertex);
}
}
// we create a rectangle between four vertices, and we do
// that as two triangles.
for (var z = 0; z < depth - 1; z++) {
for (var x = 0; x < width - 1; x++) {
// we need to point to the position in the array
// a - - b
// | x |
// c - - d
var a = x + z * width;
var b = (x + 1) + (z * width);
var c = x + ((z + 1) * width);
var d = (x + 1) + ((z + 1) * width);
var face1 = new THREE.Face3(a, b, d);
var face2 = new THREE.Face3(d, c, a);
geom.faces.push(face1);
geom.faces.push(face2);
}
}
geom.computeVertexNormals(true);
geom.computeFaceNormals();
geom.computeBoundingBox();
var zMax = geom.boundingBox.max.z;
var xMax = geom.boundingBox.max.x;
var mesh = new THREE.Mesh(geom, new THREE.MeshLambertMaterial({
vertexColors: THREE.FaceColors,
color: 0x666666
}));
mesh.translateX(-xMax / 2);
mesh.translateZ(-zMax / 2);
scene.add(mesh);
mesh.name = 'valley';
};
var render = function () {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
render();
</script>
</body>
</html>
19、使用高度映射创建地形
创建日期:2024-07-08
更新日期:2025-01-12
简介
一个来自三线小城市的程序员开发经验总结。