ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

第18章:CesiumJS 从入门到精通 18:建筑师的工具:3D Tiles 变换裁剪与自定义着色器

第18章:CesiumJS 从入门到精通 18:建筑师的工具:3D Tiles 变换裁剪与自定义着色器 写在前面前序章节掌握 3D Tiles 基础加载、Cesium3DTileStyle属性着色仅能完成基础可视化工业 BIM、倾斜摄影数字孪生项目常需要剖切查看内部结构、自定义动态光影特效、大场景流畅加载、显存防崩溃管控。 本章讲解五大生产级核心能力ClippingPlaneCollection模型剖切、CustomShaderGPU 自定义着色器、debug 瓦片调试工具、skipLevelOfDetail跳级加速加载、maximumMemoryUsage内存管控配套多特性组合综合案例覆盖建筑剖面、动态热力、大场景性能优化业务需求。本章学习目标掌握ClippingPlane单 / 多平面剖切区分并集 / 交集裁剪模式实现滑块动态剖切交互理解CustomShader顶点 / 片元着色器、uniform 传参、GLSL 基础语法实现高度热力、脉冲发光特效熟练使用全套debugShow调试工具快速定位瓦片缺失、层级切换、加载异常问题掌握跳级加载策略区分 REPLACE/ADD 瓦片细化规则适配鸟瞰 / 室内漫游不同场景配置显存内存上限监听瓦片全生命周期事件实现内存监控解决大模型 OOM 崩溃问题一、ClippingPlaneCollection 模型剖切平面1.1 核心原理裁剪平面由法线向量距离值定义法线指向保留渲染一侧平面将三维空间分割两部分另一侧模型直接剔除不渲染多平面通过集合统一管理支持两种裁剪运算模式。ClippingPlane单剖切刀法线 distance 定义切割位置ClippingPlaneCollection剖切平面组统一控制切面轮廓、开关、运算逻辑unionClippingRegionstrue 并集任意平面裁掉即隐藏false 交集多平面重叠区域才隐藏1.2 基础配置参数const clipPlanes new Cesium.ClippingPlaneCollection({ planes: [ // 法线向下高度50米处水平切割 new Cesium.ClippingPlane(new Cesium.Cartesian3(0,0,-1), 50) ], unionClippingRegions: true, edgeColor: Cesium.Color.CYAN, // 切面描边颜色 edgeWidth: 2, // 切面线宽 enabled: true }); tileset.clippingPlanes clipPlanes;1.3 常用实战案例案例 1水平剖切切除建筑上部露出地基const clipPlanes new Cesium.ClippingPlaneCollection({ planes: [new Cesium.ClippingPlane(new Cesium.Cartesian3(0,0,-1), 50)], edgeColor: Cesium.Color.CYAN, edgeWidth:2 }); tileset.clippingPlanes clipPlanes;案例 2双平面对角剖切交集模式切角落const multiClip new Cesium.ClippingPlaneCollection({ planes: [ new Cesium.ClippingPlane(new Cesium.Cartesian3(1,0,0),0), new Cesium.ClippingPlane(new Cesium.Cartesian3(0,1,0),0) ], unionClippingRegions: false, // 交集模式 edgeColor: Cesium.Color.YELLOW }); tileset.clippingPlanes multiClip;案例 3滑块动态调节剖切高度input idclipSlider typerange min0 max200 value100const clipPlanes new Cesium.ClippingPlaneCollection({ planes: [new Cesium.ClippingPlane(new Cesium.Cartesian3(0,0,-1), 100)], edgeColor: Cesium.Color.RED }); tileset.clippingPlanes clipPlanes; document.getElementById(clipSlider).oninput e{ clipPlanes.get(0).distance parseFloat(e.target.value); viewer.scene.requestRender(); }1.4 两种裁剪模式对比参数unionClippingRegions:true 并集unionClippingRegions:false 交集逻辑任一平面剔除则隐藏仅多平面重叠区域剔除效果平面越多剔除范围越大平面越多剔除范围越小适用顶部、侧面多面同时剖切只切除建筑角落一小块二、CustomShader 自定义 GPU 着色器2.1 适用场景基础Cesium3DTileStyle仅支持简单静态着色无法实现高度渐变热力、脉冲呼吸发光、实时数据映射、菲涅尔边缘光CustomShader 直接编写 GLSL 片元 / 顶点着色代码在 GPU 并行运算实现高级视觉特效。2.2 基础结构说明uniformsJS 向 GLSL 传递全局变量颜色、时间、阈值vertexShaderText顶点着色修改模型几何顶点位置fragmentShaderText片元着色修改每个像素最终颜色最常用modeMODIFY_MATERIAL基于原始材质修改推荐/REPLACE_MATERIAL完全覆盖原有纹理2.3 内置核心变量变量作用fsInput.attributes.positionMC模型局部坐标 Z 值实现按高度着色fsInput.attributes.normalMC顶点法线制作边缘高光material.diffuse模型基础漫反射颜色material.emissive自发光不受太阳光影响2.4 实战 1建筑高度热力渐变着色const heatShader new Cesium.CustomShader({ uniforms:{ u_minH:{type:Cesium.UniformType.FLOAT,value:10}, u_maxH:{type:Cesium.UniformType.FLOAT,value:300} }, fragmentShaderText: void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material){ float h fsInput.attributes.positionMC.z; float t clamp((h-u_minH)/(u_maxH-u_minH),0.0,1.0); vec3 color mix(vec3(0,0,1),vec3(1,0,0),t); material.diffuse color; material.emissive color*0.2; } }); tileset.customShader heatShader;2.5 实战 2选中建筑金色脉冲呼吸效果const pulseShader new Cesium.CustomShader({ uniforms:{ u_time:{type:Cesium.UniformType.FLOAT,value:0}, u_selected:{type:Cesium.UniformType.BOOL,value:false} }, fragmentShaderText: void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material){ if(u_selected){ float pulse 0.6 0.4*sin(u_time*5.0); vec3 gold vec3(1,0.84,0); material.diffuse mix(material.diffuse,gold,pulse*0.5); material.emissive gold*pulse*0.6; } } }); tileset.customShader pulseShader; // 每帧更新时间驱动动画 viewer.scene.preRender.addEventListener((){ pulseShader.setUniform(u_time, performance.now()/1000); })2.6 mode 模式选择建议MODIFY_MATERIAL保留原始纹理、PBR 光照仅叠加特效性能开销低绝大多数场景首选REPLACE_MATERIAL完全丢弃原始贴图自定义纯色 / 线框 / X 光效果适合分析类场景三、debugShow 瓦片调试工具集3.1 六大调试开关快速定位渲染异常// 瓦片整体包围盒线框排查瓦片缺失 tileset.debugShowBoundingVolume true; // 瓦片内部几何包围盒 tileset.debugShowContentBoundingVolume true; // 标注瓦片几何误差判断层级精细度 tileset.debugShowGeometricError true; // 冻结当前瓦片停止加载新数据 tileset.debugFreezeFrame true; // 随机分色区分相邻瓦片看清瓦片边界 tileset.debugColorizeTiles true;3.2 问题排查速查表现象调试工具判断依据部分建筑消失debugShowBoundingVolume无包围盒 瓦片请求失败有盒无图形 几何损坏远处模型模糊粗糙debugShowGeometricError几何误差数值过大调高精细层级缩放时画面闪烁debugColorizeTiles瓦片层级切换边界突兀页面加载卡顿debugFreezeFrame冻结后统计当前渲染瓦片数量四、skipLevelOfDetail 跳级加载优化4.1 常规逐级加载缺陷默认瓦片加载严格 0→1→2→3 逐级加载远距离浏览时长期显示模糊低精度瓦片缩放拉近时大量请求中间层级瓦片带宽消耗高、画面刷新慢。 跳级加载跳过中间层级直接加载当前视距匹配精度瓦片大幅减少请求数量。4.2 使用前置条件仅瓦片细化策略为REPLACE时生效ADD 叠加细化瓦片不支持跳级加载检测代码tileset.readyPromise.then((){ const refine tileset.root.refine; if(refine Cesium.Cesium3DTileRefine.ADD){ console.warn(ADD细化跳级加载无效); } })4.3 完整配置参数const tileset await Cesium.Cesium3DTileset.fromUrl(tileset.json,{ skipLevelOfDetail:true, // 开启跳级 skipLevels:1, // 最多跳过1层保守策略 immediatelyLoadDesiredLevelOfDetail:false // 子瓦片加载时保留父瓦片防空白闪烁 })4.4 场景参数配置推荐场景skipLevelOfDetailskipLevelsimmediatelyLoadDesiredLevelOfDetail城市鸟瞰、大范围飞行true2false室内精细漫游、近距离浏览false--低带宽移动端true3true五、maximumMemoryUsage 显存内存管控与瓦片事件5.1 内存溢出问题3D Tiles 瓦片几何、纹理存储在 GPU 显存无上限管控会持续加载触发浏览器 OOM 崩溃通过maximumMemoryUsage设置显存硬阈值超出自动卸载远距离瓦片。5.2 设备适配内存配置// 移动端低配128MB maximumMemoryUsage:128 * 1024 * 1024 // 笔记本集成显卡256MB maximumMemoryUsage:256 * 1024 * 1024 // 台式独立显卡512~1024MB maximumMemoryUsage:1024 * 1024 * 10245.3 瓦片全生命周期监听事件// 单瓦片加载完成/失败 tileset.tileLoad.addEventListener(tile{ if(tile.contentFailed) console.warn(瓦片加载失败,tile._header.uri); }) // 瓦片进入视野可见 tileset.tileVisible.addEventListener(tile{}) // 当前视野全部瓦片加载完成 tileset.allTilesLoaded.addEventListener((){}) // 初始根瓦片加载完毕 tileset.initialTilesLoaded.addEventListener((){})5.4 简易显存监控工具setInterval((){ const memMB (tileset.totalMemoryUsageInBytes / 1024 / 1024).toFixed(1); const limitMB (tileset.maximumMemoryUsage / 1024 / 1024).toFixed(0); console.log(显存占用${memMB}MB上限${limitMB}MB使用率${(memMB/limitMB*100).toFixed(1)}%) },1000)六、综合实战建筑剖面可视化剖切 着色器 跳级整合本章全部能力实现可动态剖切、高度热力渐变、悬停脉冲发光、大场景流畅加载的建筑剖面 Demoasync function createBuildingView(viewer){ // 1.加载瓦片开启跳级、内存限制 const tileset await Cesium.Cesium3DTileset.fromIonAssetId(96188,{ skipLevelOfDetail:true, skipLevels:1, maximumMemoryUsage:512 * 1024 * 1024 }) viewer.scene.primitives.add(tileset); await tileset.readyPromise; // 2.水平剖切平面 const clipPlanes new Cesium.ClippingPlaneCollection({ planes:[new Cesium.ClippingPlane(new Cesium.Cartesian3(0,0,1),-20)], edgeColor:Cesium.Color.CYAN, edgeWidth:1.5 }) tileset.clippingPlanes clipPlanes; // 3.热力脉冲自定义着色器 const customShader new Cesium.CustomShader({ uniforms:{ u_time:{type:Cesium.UniformType.FLOAT,value:0}, u_hoverH:{type:Cesium.UniformType.FLOAT,value:-1}, u_min:{type:Cesium.UniformType.FLOAT,value:0}, u_max:{type:Cesium.UniformType.FLOAT,value:20} }, fragmentShaderText: void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material){ float h fsInput.attributes.positionMC.z; float t clamp((h-u_min)/(u_max-u_min),0.0,1.0); vec3 heat mix(vec3(0,0.8,1),vec3(1,0,0),t); material.diffuse heat; if(abs(h - u_hoverH) 0.5){ float pulse 0.50.5*sin(u_time*4); vec3 gold vec3(1,0.85,0.1); material.diffuse mix(heat,gold,pulse*0.7); material.emissive gold*pulse*0.5; } } }) tileset.customShader customShader; // 驱动动画时间 viewer.scene.preRender.addEventListener((){ customShader.setUniform(u_time, performance.now()/1000) }) // 鼠标悬停更新楼层高度 const handler new Cesium.ScreenSpaceEventHandler(viewer.canvas); handler.setInputAction(move{ const pos viewer.scene.pickPosition(move.endPosition); if(Cesium.defined(pos)){ const cart Cesium.Cartographic.fromCartesian(pos); customShader.setUniform(u_hoverH, cart.height); }else{ customShader.setUniform(u_hoverH, -1); } },Cesium.ScreenSpaceEventType.MOUSE_MOVE) viewer.camera.flyTo({destination:tileset.boundingSphere.center,orientation:{heading:Cesium.Math.toRadians(45),pitch:Cesium.Math.toRadians(-30),roll:0}}) return {tileset,clipPlanes,customShader} }七、性能调优清单加载优化大范围场景开启skipLevelOfDetail室内漫游关闭合理调高maximumScreenSpaceError减少瓦片加载数量内存管控按设备显存设置maximumMemoryUsage定期监控显存使用率超过 90% 降低上限剖切优化远距离浏览时动态关闭clippingPlanes.enabled减少 GPU 平面计算着色器优化简化 GLSL 分支判断降低 uniform 每帧更新频率非动画参数固定值不实时刷新渲染调试上线前关闭所有 debug 调试开关避免额外线框绘制消耗性能本篇总结ClippingPlaneCollection实现三维模型任意角度剖切支持单平面水平切楼、多平面组合剖切滑块交互动态调节切割高度区分并集 / 交集两种剔除模式切面可自定义描边。CustomShader自定义 GPU 着色器通过 GLSL 代码实现基础样式无法完成的高级特效uniform 完成 JS 与着色器数据互通高度热力、脉冲发光是数字孪生高频业务效果。全套debugShow调试工具可视化瓦片包围盒、几何误差、瓦片边界快速定位瓦片缺失、层级切换、加载卡顿等渲染问题。skipLevelOfDetail跳级加载跳过中间瓦片层级减少网络请求仅支持 REPLACE 细化瓦片鸟瞰飞行场景大幅提升加载速度。maximumMemoryUsage限制显存占用防止大 BIM / 倾斜摄影模型 OOM 崩溃瓦片生命周期事件实现加载监控、失败捕获、显存统计面板。多特性可组合叠加剖切 热力着色器 跳级加载实现完整建筑剖面分析系统是智慧城市、园区 BIM 项目标准解决方案。课后实操练习剖切实验分别实现水平切顶部、垂直切侧面、双平面对角剖切对比 unionClippingRegions 两种模式视觉差异。着色器开发编写高度渐变热力着色器增加时间 uniform 实现颜色缓慢流动呼吸动画。瓦片调试依次开启全部 debug 调试开关缩放观察瓦片层级切换、包围盒分布规律。内存监控实现控制台显存监控面板调低内存上限观察引擎自动卸载远距离瓦片行为。综合进阶整合剖切滑块、热力着色、悬停脉冲、跳级加载完成完整建筑剖面浏览 Demo。下一篇预告CesiumJS 从入门到精通 19光影魔术师光照模型与后期处理特效讲解全局太阳光、环境光遮蔽 AO、屏幕空间反射 SSR使用PostProcessStage实现泛光、景深、电影级调色后期特效打造真实写实三维渲染氛围。
返回列表