问题描述
我正在使用 MapBox RGB 图块来获取高程数据并更新 Three.js 中的平面缓冲区几何。然后我计划使用他们的卫星纹理来完成 3D 地形瓷砖网格生成。之后我将创建一个动态加载网格系统。
现在我的问题是我得到的图像像素数据比顶点多。这意味着我无法将像素数据映射到高度的顶点 Z 值。我做了一个快速插入并检查我是否可以得到一个固定的高度和宽度段,但它不起作用。
对于上下文,图像图块的分辨率为 512x512。像素数据长度为520849
,缓冲区几何的Float32Array长度为519168
以下是我的粗略代码,用于创建要通过 REST API 发送 ThreeJSON 的数据集。
import * as THREE from "three";
import fs from "fs";
import Canvas from "canvas";
import path from "path";
const __dirname = path.resolve(path.dirname(""));
async function getPixels(imagePath) {
try {
const data = await fs.promises.readFile(
__dirname + imagePath,function (err,data) {
if (err) throw err;
const img = new Canvas.Image(); // Create a new Image
img.src = data;
// Initialize a new Canvas with the same dimensions
// as the image,and get a 2D drawing context for it.
const canvas = new Canvas(img.width,img.height);
const ctx = canvas.getContext("2d");
ctx.drawImage(img,img.width / 4,img.height / 4);
const imgData = context.getimageData(0,img.width,img.height);
return imgData;
}
);
return data;
} catch (err) {
console.error(err);
}
}
function rgbToHeight(r,g,b) {
return -10000 + (r * 256 * 256 + g * 256 + b) * 0.1;
}
export const tiletoMesh = async (rgbTilePath,textureTilePath) => {
try {
const pixels = await getPixels(rgbTilePath);
const planesize = parseInt(Math.sqrt(pixels.length / 4));
const geometry = new THREE.default.PlaneGeometry(
planesize,planesize,415,415
// planesize - 1,// planesize - 1
);
for (let i = 0; i < pixels.length; i += 4) {
const r = pixels[i + 0];
const g = pixels[i + 1];
const b = pixels[i + 2];
const height = rgbToHeight(r,b);
if (!geometry.vertices[i / 4]) {
console.error(`No vertices at index ${i / 4} found.`);
break;
}
geometry.vertices[i / 4].z = height;
}
geometry.verticesNeedUpdate = true;
const texture = new THREE.TextureLoader().load(textureTilePath);
const material = new THREE.MeshBasicMaterial({
map: texture,side: DoubleSide,wireframe: true,});
const mesh = new THREE.Mesh(geometry,material);
return mesh;
} catch (err) {
console.error(err);
}
};
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)