我有一个利用高度图生成平面顶点y位置的地形,我也使用光线投射在它上面绘制网格(树木,岩石等),并且效果很好。
我现在想要做的是绘制样条曲线,使每个点的y值与其绘制的地形相匹配。我不知道我是否可以使用光线投射(我猜不是?),或者是否有办法从高度图本身找到y位置。
如果有人有任何想法,我会打开!
如果有帮助,这是我的terrain和heightmap函数:
地形:
// TERRAIN
// load texture
var textureloader = new THREE.TextureLoader();
var terrainT = textureloader.load('assets/textures/terrain/Fabric.jpg');
terrainT.wrapS = terrainT.wrapT = THREE.RepeatWrapping;
terrainT.repeat.set(4, 4);
// create terrain from heightmap
var heightmaploader = new THREE.ImageLoader();
heightmaploader.load(
"assets/noisemaps/cloud.png",
function(img) {
// read the heightmap and get the vertex data
data = getHeightData(img);
var terrainG = new THREE.PlaneBufferGeometry(1000, 1000, worldWidth - 1, worldDepth - 1);
terrainG.rotateX(-Math.PI / 2);
var vertices = terrainG.attributes.position.array;
for (var i = 0, j = 0, l = vertices.length; i < l; i++, j += 3) {
vertices[j + 1] = data[i] * 5;
}
terrainG.computeFaceNormals();
terrainG.computeVertexNormals();
var material = new THREE.MeshLambertMaterial({
map: terrainT,
color: 0xffffff
});
terrain = new THREE.Mesh(terrainG, material);
terrain.receiveShadow = true;
terrain.position.y = -50;
scene.add(terrain);
plotAsset('boulder-photo-01.png', 35, 18, terrain);
plotAsset('boulder-outline-01.png', 25, 20, terrain);
plotAsset('birch-outline-01.png', 50, 50, terrain);
plotAsset('tree-photo-01.png', 55, 50, terrain);
plotAsset('grass-outline-01.png', 25, 20, terrain);
plotAsset('grass-outline-02.png', 25, 20, terrain);
}
);
高度图:
// HEIGHT DATA FROM HEIGHTMAP
function getHeightData(img) {
var canvas = document.createElement('canvas');
canvas.width = 2048 / 8;
canvas.height = 2048 / 8;
var context = canvas.getContext('2d');
var size = canvas.width * canvas.height,
data = new Float32Array(size);
context.drawImage(img, 0, 0);
for (var i = 0; i < size; i++) {
data[i] = 0
}
var imgd = context.getImageData(0, 0, canvas.width, canvas.height);
var pix = imgd.data;
var j = 0;
for (var i = 0, n = pix.length; i < n; i += (4)) {
var all = pix[i] + pix[i + 1] + pix[i + 2];
data[j++] = all / 40;
}
return data;
}