尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

在CesiumJS中渲染体素:3D Tiles体积数据可视化实践指南

在CesiumJS中渲染体素:3D Tiles体积数据可视化实践指南 在CesiumJS中渲染体素3D Tiles体积数据可视化实践指南【免费下载链接】cesiumAn open-source JavaScript library for world-class 3D globes and maps :earth_americas:项目地址: https://gitcode.com/GitHub_Trending/ce/cesium做医学影像或地质建模的人常遇到同一个麻烦CT扫描、地震波场这类数据是完整的三维体积可普通三维模型只能表达表面。想让用户在浏览器里像旋转CT机那样透视数据内部就得用体素渲染——直接把整个数据体积当作渲染对象。CesiumJS 的体素渲染能力就长在它的3D Tiles体系里官方定义了3DTILES_content_voxels扩展场景侧提供VoxelPrimitive图元体素数据可以像普通瓦片集一样按八叉树分层、按视点距离流式加载而不是把几百兆体积一次性塞进内存。小方糖比喻体素是什么把一段空间想象成一盒小方糖每块糖占一个固定格子格子的位置确定后只需要记下这块糖是什么颜色、多不透明整个体积就描述完了。这些格子就是体素Voxel它是体素网格的最小单元而表面网格模型里的三角面片只描述外壳体素则把内部结构原样保留。这个设计带来两个好处一是数据是规则的三维数组读写和索引都很直白二是天然适合用空间索引和细节层级管理规模。CesiumJS 用 VoxelShapeType.js 里的枚举定义了三种外形BOX、CYLINDER、ELLIPSOID控制体素网格如何映射到三维空间地球表面的数据用椭球体最贴切。光线步进采样颜色是怎么算出来的渲染时GPU会为屏幕上的像素发射一条射线。射线进入体素区域后不是一步到终点而是一小段一小段地前进每到一步就用当前坐标去查体素属性密度、温度、RGB色等把这一步采到的颜色按不透明度叠到累计颜色上然后继续往前直到射出区域。这个逐点采样混合的过程就是体积渲染的核心也叫光线步进ray marching。步长是关键权衡太大薄结构会被跳过去出现条纹太小采样次数暴涨帧率扛不住。CesiumJS 把这个循环放在 GPU 片段着色器里执行VoxelFS.glsl 是体素片元的主逻辑体素数据本身以 megatexture 形式驻留在显存中供随机采样空区域则靠瓦片树的八叉树结构整块跳过不做无谓采样。体素数据长什么样体素瓦片集本质是一个 3D Tiles 1.1 的tileset.json体素内容通过扩展声明。仓库测试数据 VoxelBox3DTiles 里的真实文件精简后如下{ asset: { version: 1.1 }, root: { geometricError: 0.0, refine: REPLACE, content: { uri: tiles/{level}/{x}/{y}/{z}.gltf, extensions: { 3DTILES_content_voxels: { dimensions: [2, 2, 2], class: voxel } } }, implicitTiling: { subdivisionScheme: OCTREE, subtreeLevels: 3, availableLevels: 1, subtrees: { uri: subtrees/{level}/{x}/{y}/{z}.json } } }, extensionsUsed: [3DTILES_content_voxels] }dimensions给出瓦片内体素的三维尺寸class指明属性来自哪个元数据类属性定义在schemaUri指向的 schema 里implicitTiling的OCTREE方案决定瓦片如何逐级细分。多个属性——密度、温度、速度向量——就是 schema 里多个属性类渲染时按通道取值。从零跑起来拿到仓库后最小可运行的加载流程如下它从本地样例瓦片集创建体素提供者并加入场景import * as Cesium from cesium; const viewer new Cesium.Viewer(cesiumContainer); const provider await Cesium.Cesium3DTilesVoxelProvider.fromUrl( Assets/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json, ); const primitive viewer.scene.primitives.add( new Cesium.VoxelPrimitive({ provider }), ); viewer.camera.flyToBoundingSphere(primitive.boundingSphere, { duration: 0.0, });样例瓦片集放在Apps/SampleData/Cesium3DTiles/Voxel/下VoxelBox3DTiles、VoxelCylinder3DTiles、VoxelEllipsoid3DTiles三种形状各有一个。不想自己造数据的也可以打开 Sandcastle 体素示例那里用自定义着色器模拟了体积散射——fsInput.voxel.travelDistance记录射线在体积中走过的距离配合指数衰减就能近似出光线在介质里被吞掉的效果着色器写法可参考 CustomShaderGuide。两个真实场景的叙事医疗阅片要回答的问题是一张512×512×300的CT体积怎么让非专业用户看清肿瘤周围的结构而不打开重型桌面软件。做法是把数据切成体素瓦片集用自定义着色器把密度映射成颜色渐变内部高密度区域自然透出。效果是医生在浏览器里就能平移、旋转、调整阈值切片交互延迟和普通三维场景没有区别。气象数据的痛点则是动态云场、温度场随时间变化单帧体积已经够大。做法是把时间做成属性通道或按帧换瓦片内容渲染时用步进采样的透明度累积呈现云团厚度——薄的地方透、厚的地方实正好符合人眼对云的真实观感。效果是一团会呼吸的云直接浮在 CesiumJS 的地球上。避坑与调优现象、原因与解法帧率随瓦片变大断崖下跌通常是采样步长和瓦片尺寸不匹配。解法是启用多级细节availableLevels大于1时让远处瓦片用粗网格近处才加载细粒度瓦片这正是 LOD 思路在体素上的落地。边缘出现锯齿状条纹原因是步长超过了体素分辨率射线跳过了细节。解法是把最大步长限制在体素尺寸量级并对采样加双线性插值。首屏加载慢一般是把整块体积一次性发到了浏览器。解法是依赖implicitTiling的八叉树做流式加载——先用低精度子树占位视点靠近再逐层请求细节瓦片纹理侧选用压缩格式显存压力也能降下来。收尾体素渲染的价值是让体积第一次在浏览器里成为一等公民CT 的断面、地下的矿体、上空的云场都成了可以随手旋转、随时切片的数据而不是只能看渲染图的静态文件。随着 WebGPU 在主流浏览器铺开Compute Shader 驱动的大规模步进采样会进一步降低单帧开销实时体积光照和更大数据集的支持也只是时间问题。对开发者而言现在入手 CesiumJS 的3D Tiles体素管线等于提前站在了这条线的起点上。【免费下载链接】cesiumAn open-source JavaScript library for world-class 3D globes and maps :earth_americas:项目地址: https://gitcode.com/GitHub_Trending/ce/cesium创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表