Javascript 如何使用three.js中的heightmap在地形顶部绘制随机网格?
因此,正如标题所述,我想知道如何在y位置绘制随机生成的网格,该网格与three.js中地形对应的y位置相匹配。我浏览了文档,觉得使用光线投射器可能会有用,但我只能看到将检测用作鼠标事件的示例,而不是在渲染之前,所以我不确定如何实现它 这是我迄今为止关于地形、高度贴图和网格打印的代码。从技术上讲,这一切都是可行的,但正如您所看到的,y位置现在只是处于零位。任何见解都将不胜感激,我对three.js还很陌生 地形:Javascript 如何使用three.js中的heightmap在地形顶部绘制随机网格?,javascript,three.js,Javascript,Three.js,因此,正如标题所述,我想知道如何在y位置绘制随机生成的网格,该网格与three.js中地形对应的y位置相匹配。我浏览了文档,觉得使用光线投射器可能会有用,但我只能看到将检测用作鼠标事件的示例,而不是在渲染之前,所以我不确定如何实现它 这是我迄今为止关于地形、高度贴图和网格打印的代码。从技术上讲,这一切都是可行的,但正如您所看到的,y位置现在只是处于零位。任何见解都将不胜感激,我对three.js还很陌生 地形: var heightmaploader = new THREE.Im
var heightmaploader = new THREE.ImageLoader();
heightmaploader.load(
"assets/noisemaps/cloud.png",
function(img) {
data = getHeightData(img);
var terrainG = new THREE.PlaneBufferGeometry(700, 700, 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,
//side: THREE.DoubleSide,
color: 0xffffff,
transparent: false,
});
terrain = new THREE.Mesh(terrainG, material);
terrain.receiveShadow = true;
terrain.castShadow = true;
terrain.position.y = 0;
scene.add(terrain);
plotAsset('boulder-photo-01.png', 30, 18, data);
plotAsset('boulder-outline-01.png', 20, 20, data);
plotAsset('birch-outline-01.png', 10, 50, data);
plotAsset('tree-photo-01.png', 20, 50, data);
plotAsset('grass-outline-01.png', 10, 20, data);
plotAsset('grass-outline-02.png', 10, 20, data);
}
);
var heightmaploader=new THREE.ImageLoader();
heightmaploader.load(
“assets/noisemap/cloud.png”,
功能(img){
数据=获取高度数据(img);
var terrainG=新的三层平面缓冲几何体(700700,worldWidth-1,worldDepth-1);
terrainG.rotateX(-Math.PI/2);
var顶点=terrainG.attributes.position.array;
对于(变量i=0,j=0,l=vertices.length;i
地块资产:
function plotAsset(texturefile, amount, size, array) {
console.log(array);
var loader = new THREE.TextureLoader();
loader.load(
"assets/textures/objects/" + texturefile,
function(texturefile) {
var geometry = new THREE.PlaneGeometry(size, size, 10, 1);
var material = new THREE.MeshBasicMaterial({
color: 0xFFFFFF,
map: texturefile,
side: THREE.DoubleSide,
transparent: true,
depthWrite: false,
depthTest: false,
alphaTest: 0.5,
});
var uniforms = { texture: { value: texturefile } };
var vertexShader = document.getElementById( 'vertexShaderDepth' ).textContent;
var fragmentShader = document.getElementById( 'fragmentShaderDepth' ).textContent;
// add bunch o' stuff
for (var i = 0; i < amount; i++) {
var scale = Math.random() * (1 - 0.8 + 1) + 0.8;
var object = new THREE.Mesh(geometry, material);
var x = Math.random() * 400 - 400 / 2;
var z = Math.random() * 400 - 400 / 2;
object.rotation.y = 180 * Math.PI / 180;
//object.position.y = size * scale / 2;
object.position.x = x;
object.position.z = z;
object.position.y = 0;
object.castShadow = true;
object.scale.x = scale; // random scale
object.scale.y = scale;
object.scale.z = scale;
scene.add(object);
object.customDepthMaterial = new THREE.ShaderMaterial( {
uniforms: uniforms,
vertexShader: vertexShader,
fragmentShader: fragmentShader,
side: THREE.DoubleSide
} );
}
}
);
}
函数绘图资源(纹理文件、数量、大小、数组){
console.log(数组);
var loader=new THREE.TextureLoader();
装载机(
“资源/纹理/对象/”+纹理文件,
函数(纹理文件){
var几何=新的三个平面几何(尺寸,尺寸,10,1);
var材料=新的三网格基本材料({
颜色:0xFFFFFF,
贴图:纹理文件,
三面,双面,
透明:是的,
depthWrite:false,
深度测试:假,
字母测试:0.5,
});
var={texture:{value:texturefile}};
var vertexShader=document.getElementById('vertexShaderDepth').textContent;
var fragmentShader=document.getElementById('fragmentShaderDepth').textContent;
//添加一堆o'东西
对于(变量i=0;i
高度数据:
function getHeightData(img) {
var canvas = document.createElement('canvas');
canvas.width = 2048 / 8;
canvas.height = 2048 / 8;
var context = canvas.getContext('2d');
var size = 2048 / 8 * 2048 / 8,
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, 2048 / 8, 2048 / 8);
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;
}
函数getHeightData(img){
var canvas=document.createElement('canvas');
画布宽度=2048/8;
画布高度=2048/8;
var context=canvas.getContext('2d');
变量大小=2048/8*2048/8,
数据=新阵列(大小);
drawImage(img,0,0);
对于(变量i=0;i
是的,使用THREE.Raycaster()
效果很好。
光线投射器具有.set(原点、方向)
方法。这里唯一需要做的就是将原点设置为高于高度贴图的最高点
var n = new THREE.Mesh(...); // the object we want to aling along y-axis
var collider = new THREE.Raycaster();
var shiftY = new THREE.Vector3();
var colliderDir = new THREE.Vector3(0, -1, 0); // down along y-axis to the mesh of height map
shiftY.set(n.position.x, 100, n.position.z); // set the point of the origin
collider.set(shiftY, colliderDir); //set the ray of the raycaster
colliderIntersects = collider.intersectObject(plane); // plane is the mesh of height map
if (colliderIntersects.length > 0){
n.position.y = colliderIntersects[0].point.y; // set the position of the object
}
范例