ARTICLE DETAIL

资讯详情

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

CesiumJS 体素渲染 10 分钟跑通:三维体积数据可视化实战与避坑清单

CesiumJS 体素渲染 10 分钟跑通:三维体积数据可视化实战与避坑清单 CesiumJS 体素渲染 10 分钟跑通三维体积数据可视化实战与避坑清单【免费下载链接】cesiumAn open-source JavaScript library for world-class 3D globes and maps :earth_americas:项目地址: https://gitcode.com/GitHub_Trending/ce/cesium表面网格渲染只能给你一层壳。CT 断层里的病灶、岩心样本的密度分布、某高度的云场——这些内部传统方式都看不到。CesiumJS 的体素渲染就是为这类三维体积数据可视化问题准备的把空间切成小立方体数据原样保留渲染时由渲染器边走边采样、边走边合成把内部直接长在画面里。真实场景为什么表面网格不够用以医学成像为例。CT 扫描得到的是一摞二维断层医生的工作是脑内合成出三维体积再找病灶。用传统的先建网格做法会卡住必须挑一个密度阈值抽等值面阈值一变信息就丢一批只看得见外壳内部的密度梯度全没了想看不同组织就得重新抽一次面体素渲染反过来做体积数据原封不动渲染时把内部合成出来。地质勘探同理矿体形态、断层带、地下含盐量都是内部数据比医学图像更难用网格表达。最小体素场景怎么搭10 行代码跑起来仓库自带一套体素示例数据最快路径是直接走 3D Tiles 加载。以下代码改编自官方 Sandcastle 演示const viewer new Cesium.Viewer(cesiumContainer, { baseLayerPicker: false, // 关掉不用的控件首屏聚焦主体 geocoder: false, animation: false, timeline: false, }); // 用体素专用 provider 加载 tileset数据路径换成你自己的 const provider await Cesium.Cesium3DTilesVoxelProvider.fromUrl( data/VoxelBox3DTiles/tileset.json ); const voxelPrimitive viewer.scene.primitives.add( new Cesium.VoxelPrimitive({ provider }) ); // 一行把相机对准主体不用手算坐标 viewer.camera.flyToBoundingSphere(voxelPrimitive.boundingSphere, { duration: 0.0, });为什么这么写Cesium3DTilesVoxelProvider.fromUrl是体素扩展的专用入口把普通 3D Tiles 的 provider 喂给VoxelPrimitive是行不通的这是新手第一大坑dimensions、属性 schema、分块信息全部从tileset.json读取不需要手动声明VoxelPrimitive挂在scene.primitives上和别的图元一样分块、遍历、采样全由渲染器内部处理flyToBoundingSphere让相机直接对准主体的包围球省掉手动摆坐标这是官方演示的运行效果Cesium 场景里的体素盒注意它是密度场而不是实体壳转起来能看到内部颜色连续变化。体素数据组织方式与 3D Tiles 扩展配置一个体素瓦片本质是小立方体数组。拿仓库里的官方样例完整版见 Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json去掉噪音后长这样{ asset: { version: 1.1 }, extensionsUsed: [3DTILES_content_voxels], root: { boundingVolume: { box: [0,0,0, 6378137,0,0, 0,6378137,0, 0,0,6378137] }, content: { uri: tiles/{level}/{x}/{y}/{z}.gltf, extensions: { 3DTILES_content_voxels: { dimensions: [2, 4, 3], class: voxel } } } } }配置怎么读3DTILES_content_voxels是扩展标识告诉 3D Tiles 加载器这块内容是体素dimensions给出当前瓦片 x/y/z 三个轴上的格子数属性定义在schema段上面省略了示例里a字段是VEC4即每个体素携带一个四通道浮点数正是密度/颜色值uri用{level}/{x}/{y}/{z}占位配合完整配置里的implicitTilingsubdivisionScheme: OCTREE声明大体积被切成小瓦片逐级取用这是流式加载的基础boundingVolume.box的 12 个数是地心坐标下的包围盒数据不到赤道就得按实际改否则会被整体裁剪掉对应下面避坑清单第三条光线步进采样到底在做什么把屏幕上每个像素想成一根吸管从相机出发扎进体积里沿途每隔一段尝一口局部密度和颜色边尝边把结果掺进吸管里抽出来的那一刻你看到的颜色就是整根吸管掺完的果汁。渲染器把它拆成三步找入射点和出射点像素射线和形状盒、球、圆柱求交得出进出位置形状之外的部分直接不画步进采样从入点到出点按固定步长走每步读一次该点的密度步长大小由当前 LOD 决定累积合成每个采样点把密度转透明度混进射线累计不透明度接近不透明就提前结束这就是光线步进采样。体素没有表面几何你看到的表面其实是累积密度到一定浓度后的视觉结果这也是为什么透明映射写对了体素看起来才有质感。光线的起点就是 Cesium 场景里这个相机位置每条光线的方向由像素和视锥共同决定。体素渲染性能调优对照LOD 分级。VoxelPrimitive按屏幕空间误差决定是否细分瓦片相机距离策略代价近细分到高层级步长小、采样密高但细节值得中步长与层级取中间值均衡远只用粗层级甚至整块裁剪极低判断标准是误差在屏幕上占多少像素所以不用自己写距离阈值控制好瓦片的geometricError就行。空间索引跳空。体积里大片是空区域时岩样大部分是孔隙、气象网格大部分无降水先用八叉树标记空块遍历直接跳过。对应到 3D Tiles 就是implicitTiling里的八叉树声明子树没数据请求根本不发出去。内存与流式加载。单个 glTF 瓦片里的体素数组按块存放分块正确时浏览器只保留当前可见的几层圆盘缓存还能把回到视野的瓦片从磁盘读回省掉二次下载。项目性能测试指南里有对磁盘缓存机制的图示说明新手避坑清单现象、原因、处理现象图元加了屏幕却空无一物。原因用了普通 3D Tiles 的 provider或者tileset.json没声明3DTILES_content_voxels扩展。处理改用Cesium3DTilesVoxelProvider.fromUrl加载并检查extensionsRequired里有没有这个扩展。现象物体表面脏、转起来有接缝。原因瓦片之间没有留 padding采样踩在边界上取值跳变。处理provider 上声明paddingBefore/paddingAfter或先用voxelPrimitive.nearestSampling true观察采样行为定位问题。现象镜头一拉远物体整个消失。原因root 的boundingVolume盒子比真实数据范围小整棵瓦片树被视口裁剪掉。处理核对 box 与实际数据范围留出余量。现象首屏几秒卡顿内存冲高。原因所有层级、所有瓦片被一次性请求。处理用八叉树分块加按需加载并用事件盯住加载过程// 调试期用事件盯加载状态 voxelPrimitive.tileFailed.addEventListener((e) { console.warn(瓦片加载失败, e); });总结与延伸阅读一句话收束CesiumJS 体素场景 一份带3DTILES_content_voxels扩展的 3D Tiles 数据 专用 provider 入口 一个VoxelPrimitive采样、合成、LOD 全部交给渲染器。想继续往下挖从仓库里这四处入手packages/sandcastle/gallery/voxels/程序化体素演示含用 CustomShader 写透明度指数衰减的片段是自写密度映射的好模板packages/sandcastle/gallery/voxels-in-3d-tiles/3D Tiles 体素加载演示本文跑通代码即改编自它packages/engine/Source/Scene/VoxelPrimitive.js主源码JSDoc 里带事件、参数与 LOD 的完整说明Apps/SampleData/Cesium3DTiles/Voxel/盒、圆柱、球三套现成 tileset拿来就能跑【免费下载链接】cesiumAn open-source JavaScript library for world-class 3D globes and maps :earth_americas:项目地址: https://gitcode.com/GitHub_Trending/ce/cesium创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表