【Three.js】如何实现楼栋分层渲染?
创始人
2025-05-29 18:40:56

分层思路

在 three.js 中,可以使用多个mesh来实现楼栋分层渲染。
感觉和 cesium.js 的分层渲染思路,没有什么区别啊…但还是要记录一下

1、楼层数确定

具体步骤如下:

  1. 将楼栋的每一层分别建模成一个mesh,并设置不同的高度和材质。

  2. 将每一层的mesh添加到一个数组中,按照从下往上的顺序排列。

  3. 使用THREE.Group来将每一层的mesh组合起来,形成一个楼栋。

  4. 将楼栋的整个Group添加到场景中。

  5. 使用THREE.Raycaster来检测用户的交互事件(例如点击),并判断用户所点击的位置是否在楼栋范围内。

  6. 根据用户点击的位置,计算出用户所点击的层数,并将该层的mesh设置为高亮显示状态。

示例代码:

// 因为楼层数是确定的,所以不用特地使用代码进行排序,直接在创建mesh的时候,按从下到上的顺序排序创建即可
// 创建每一层的mesh
var layer1 = new THREE.Mesh(geometry1, material1);
var layer2 = new THREE.Mesh(geometry2, material2);
var layer3 = new THREE.Mesh(geometry3, material3);
// 将每一层的mesh添加到数组中
var layers = [layer1, layer2, layer3];
// 将每一层的mesh组合成一个Group
var building = new THREE.Group();
for (var i = 0; i < layers.length; i++) {layers[i].position.y = i * layerHeight; // 设置每一层的高度building.add(layers[i]);
}
// 将整个楼栋的Group添加到场景中
scene.add(building);
// 监听鼠标点击事件
var raycaster = new THREE.Raycaster();
function onMouseClick(event) {// 计算用户点击的位置var mouse = new THREE.Vector2();mouse.x = (event.clientX / window.innerWidth) * 2 - 1;mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;// 将屏幕坐标转换为三维坐标raycaster.setFromCamera(mouse, camera);// 检测用户点击的位置是否在楼栋范围内var intersects = raycaster.intersectObject(building, true);if (intersects.length > 0) {// 计算用户所点击的层数var layerIndex = Math.floor(intersects[0].point.y / layerHeight);// 将该层的mesh设置为高亮显示状态layers[layerIndex].material.color.set(0xff0000);}
}
window.addEventListener('click', onMouseClick, false);

2、楼层数动态

具体步骤如下:

  1. 根据楼层数动态创建每一层的mesh,并设置不同的高度和材质。

  2. 将每一层的mesh添加到一个数组中,按照从下往上的顺序排列。

  3. 使用THREE.Group来将每一层的mesh组合起来,形成一个楼栋。

  4. 将楼栋的整个Group添加到场景中。

  5. 使用THREE.Raycaster来检测用户的交互事件(例如点击),并判断用户所点击的位置是否在楼栋范围内。

  6. 根据用户点击的位置,计算出用户所点击的层数,并将该层的mesh设置为高亮显示状态。

  7. 如果楼层数发生改变,需要重新创建每一层的mesh,更新楼栋的Group,并更新每一层的高度和材质。(Tips:这里不一定用得上)

下面是一个示例代码:

// 注意!!!!
// 因为是动态楼层,所以,numLayers楼层数 这里可以换成 allLayers总楼层数据-最好可以先排个序,按照从低到高
// 排序的方法就不放出来了,因为楼栋-楼层模型数据不一样,可能楼栋-楼层的命名规则不一样,排序方法也要求不同
// 动态创建每一层的mesh
var layers = [];
for (var i = 0; i < numLayers; i++) {var layer = new THREE.Mesh(geometry, material);layer.position.y = i * layerHeight; // 设置每一层的高度layers.push(layer);
}
// 将每一层的mesh组合成一个Group
var building = new THREE.Group();
for (var i = 0; i < layers.length; i++) {building.add(layers[i]);
}
// 将整个楼栋的Group添加到场景中
scene.add(building);
// 监听鼠标点击事件
var raycaster = new THREE.Raycaster();
function onMouseClick(event) {// 计算用户点击的位置var mouse = new THREE.Vector2();mouse.x = (event.clientX / window.innerWidth) * 2 - 1;mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;// 将屏幕坐标转换为三维坐标raycaster.setFromCamera(mouse, camera);// 检测用户点击的位置是否在楼栋范围内var intersects = raycaster.intersectObject(building, true);if (intersects.length > 0) {// 计算用户所点击的层数var layerIndex = Math.floor(intersects[0].point.y / layerHeight);// 将该层的mesh设置为高亮显示状态layers[layerIndex].material.color.set(0xff0000);}
}
window.addEventListener('click', onMouseClick, false);// 这一段代码不一定用得上
// 如果楼层数发生改变,重新创建每一层的mesh,并更新楼栋的Group、每一层的高度和材质
function updateBuilding(numLayers, layerHeight, geometry, material) {for (var i = 0; i < layers.length; i++) {building.remove(layers[i]);}layers = [];for (var i = 0; i < numLayers; i++) {var layer = new THREE.Mesh(geometry, material);layer.position.y = i * layerHeight;layers.push(layer);building.add(layer);}
}

相关内容

热门资讯

攻略游戏分享【WPK微扑克】外... 这篇文章讲的是游戏作弊的热点。希望对你有帮助。不要忘记书签这个网站。如何破解手机麻将游戏?。【WPK...
重磅!新好友比鸡有外挂吗真有(... 您好:新好友比鸡这款游戏可以开挂,确实是有挂的,很多玩家在这款游戏中打牌都会发现很多用户的牌特别好,...
我来告诉你开牛牛群房卡要怎么买... fkVJ6CsX曝光iPhone15标准版与iPhone15 Pro系列的屏幕配置还是有所区别,其中...
我来告诉你牛牛房卡从哪买牛牛房... 0于iPhone 15 Pro系列机型,还有不少的爆料。比方说为了给该系列机型减重,更换了机身的材质...
重大通报牛牛房卡多少钱如何开牛... 7MW除了屏幕和后置相机的变化之外,iPhone16Pro还将会支持手写笔的使用,所以后续用手写笔在...