原理说明Cesium 原生剖切核心ClippingPlaneCollection给Cesium3DTileset.clippingPlanes赋值GPU 片元 discard 实现裁切Cesium。ClippingPlane(normal, distance)Hessian 平面方程法线 normal 指向的一侧保留另一侧裁切掉这个是最容易踩坑的点剖切盒 6 个正交剖切平面上下、左右、前后交集模拟 Revit 剖面框只保留盒子内部模型unionClippingRegions布尔模式false默认交集必须同时满足所有平面保留条件才显示 → 剖切盒true并集任意一个平面保留区域就显示注意剖切是依附在 tileset 上不同模型要单独设置 clippingPlanes全局 Globe 地形也支持剖切QQ20261104-104318完整代码 CesiumClipBox.vuetemplate div classcesium-page div refcesiumRef idcesiumContainer/div div classcontrol-panel div剖面控制/div button clickclipSinglePlane单向平面剖切/button button clickclipBox剖切盒(只框内可见)/button button clickclearClip清除剖切/button div stylemargin-top:6px label剖切距离滑动/label input typerange min-50 max50 step1 v-model.numberclipDist inputupdateClipDist / span{{clipDist}}/span /div /div /div /template script setup import { onMounted, onBeforeUnmount, ref } from vue import * as Cesium from cesium import cesium/Build/Cesium/Widgets/widgets.css const cesiumRef ref(null) let viewer null let tileset null let clipPlanesCollection null let boxCenter null const clipDist ref(0) window.CESIUM_BASE_URL /cesium/ onMounted(() { initCesium() }) onBeforeUnmount(() { if(tileset) tileset.clippingPlanes null if (viewer) viewer.destroy() }) function initCesium() { viewer new Cesium.Viewer(cesiumContainer, { animation: false, timeline: false, baseLayerPicker: false, geocoder: false, homeButton: false, sceneModePicker: false, navigationHelpButton: false, fullscreenButton: false, infoBox: false }) viewer.creditDisplay.container.style.display none viewer.scene.globe.depthTestAgainstTerrain true loadBIMTileset() } function loadBIMTileset() { tileset new Cesium.Cesium3DTileset({ url: /bim/tileset.json, // 替换为你的BIM/倾斜3DTiles skipLevelOfDetail: true }) viewer.scene.primitives.add(tileset) tileset.readyPromise.then(function (tiles) { viewer.zoomTo(tiles) // 取包围球中心作为剖切基准原点 boxCenter tiles.boundingSphere.center }) } /** * 1、单向剖切平面竖直剖面纵向切一刀看内部 */ function clipSinglePlane() { if(!tileset || !boxCenter) return // 法线X方向法线朝X正方向Xdistance的一侧保留 const normal new Cesium.Cartesian3(1,0,0) Cesium.Cartesian3.normalize(normal, normal) const plane new Cesium.ClippingPlane(normal, clipDist.value) clipPlanesCollection new Cesium.ClippingPlaneCollection({ planes: [plane], unionClippingRegions: false }) tileset.clippingPlanes clipPlanesCollection } /** * 2、剖切盒6个面类似Revit剖面框只保留盒子内部 */ function clipBox() { if(!tileset || !boxCenter) return const halfSize 25 // 盒子半边长米 // 六个剖切平面 const planes [ new Cesium.ClippingPlane(new Cesium.Cartesian3(1,0,0), halfSize), new Cesium.ClippingPlane(new Cesium.Cartesian3(-1,0,0), halfSize), new Cesium.ClippingPlane(new Cesium.Cartesian3(0,1,0), halfSize), new Cesium.ClippingPlane(new Cesium.Cartesian3(0,-1,0), halfSize), new Cesium.ClippingPlane(new Cesium.Cartesian3(0,0,1), halfSize), new Cesium.ClippingPlane(new Cesium.Cartesian3(0,0,-1), halfSize), ] clipPlanesCollection new Cesium.ClippingPlaneCollection({ planes: planes, modelMatrix: Cesium.Transforms.eastNorthUpToFixedFrame(boxCenter), unionClippingRegions: false // 交集模式六面围合的盒子内部才显示 }) tileset.clippingPlanes clipPlanesCollection } /** * 滑动条动态更新剖切平面距离 */ function updateClipDist(){ if(!clipPlanesCollection) return clipPlanesCollection.planes[0].distance clipDist.value } /** * 清除剖切 */ function clearClip(){ if(tileset){ tileset.clippingPlanes null } clipPlanesCollection null } /script style scoped .cesium-page { width: 100%; height: 100vh; position: relative; } #cesiumContainer { width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden; } .control-panel { position: absolute; top:12px; left:12px; z-index:999; background: rgba(0, 20, 40, 0.75); padding:10px; border-radius:6px; color:#fff; } .control-panel button { margin:4px; padding:4px 8px; cursor:pointer; } /style核心 API 详解ClippingPlanenew Cesium.ClippingPlane(normal, distance)normal归一化法向量法线指向哪一侧哪一侧保留渲染distance距离参数配合modelMatrix很关键BIM 模型建议以包围盒中心建立 ENU 局部坐标系避免全球坐标距离混乱CesiumunionClippingRegionsfalse交集剖切盒必须同时满足所有平面保留条件 → 长方体剖面框true并集任意一个平面保留区就显示多用于挖洞、排除多个区域modelMatrix剖切平面默认是世界坐标系BIM 模型用eastNorthUpToFixedFrame(center)转到局部 ENU这样盒子跟着建筑姿态走建筑旋转之后剖切盒不会错位BIM 项目必加这个参数。高频扩展方案项目常用剖切边框可视化原生不会显示剖切框线方案根据 6 个剖切平面参数动态绘制Polygon/Polyline线框同步跟随剖切参数更新就是大家常见带白色线框的剖面框效果。鼠标拾取定位剖切面点击 BIM 内部一点以点击点为中心自动生成剖切盒查看该房间内部搭配前面 BatchTable 拾取分户 ID一键分户剖切。斜向剖切非正交剖面不用 XYZ 轴向法线自定义 normal 向量实现斜切剖面管线、斜屋面查看用。剖切动画用setInterval/timeline 持续修改 plane.distance做平推剖切动画汇报大屏演示效果很好。新版本ClippingPolygon多边形剖切Cesium 新版本支持多边形裁切ClippingPolygonCollection支持任意闭合轮廓裁切适合按红线轮廓挖除倾斜摄影区别于平面剖切盒Cesium。踩坑清单❌ 剖切之后模型全消失 / 完全不裁切✅ 法线方向搞反调换 normal 方向即可distance 正负也要配合坐标系调试❌ 剖切盒和建筑错位歪掉✅ 缺少modelMatrix没有转到建筑局部 ENU 坐标系❌ 多个 BIM 模型只有一个被剖切✅ clippingPlanes 是挂在单个 tileset 上多 tileset 需要分别赋值❌ 剖切后瓦片闪烁、LOD 切换时剖面跳动✅ 尽量以模型包围盒中心作为剖切原点不要用很远的世界原点❌ glTF 模型剖切无效✅ glTF Model 同样支持model.clippingPlanes和 3DTiles 用法一致和前面系列联动建筑单体化 剖切选中分户 → 自动生成分户包围盒剖切隔离看一户内部轨迹漫游 剖切巡检小车漫游时动态剖切前方墙体实现穿墙透视巡检CustomShader 剖切剖切断面可以用 shader 给剖切面加上断面填充色模拟 CAD 剖面填充