ARTICLE DETAIL

资讯详情

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

如何在 3 步内跑通 CesiumJS 体素渲染

如何在 3 步内跑通 CesiumJS 体素渲染 如何在 3 步内跑通 CesiumJS 体素渲染【免费下载链接】cesiumAn open-source JavaScript library for world-class 3D globes and maps :earth_americas:项目地址: https://gitcode.com/GitHub_Trending/ce/cesium你有没有想过把一层云、一块岩体直接剖开看它内部长什么样而不只是看表面CesiumJS 体素渲染就是为这种需求准备的它不生成任何表面网格而是把一整块体积数据放进三维场景让你从任意角度看穿它。这个功能在当前版本仍标记为experimental接口可能还会调整但整条管线已经可用。体素Voxel一词拆开就是体积像素指把一段空间切成的三维小格子数组。最直观的类比是 Minecraft 世界每个格子存几个属性值引擎把它们拼成最终画面。这和网格mesh不同——网格只描述表面体素能回答内部有多浓这类问题正适合气象、医学、地质等 WebGL 体积数据可视化场景。这是一个真实的 Cesium 三维场景你后面加载的体素就会放进这样的场景里。一次看穿你要记住的只有一个 API用体素渲染只需要碰一个类VoxelPrimitive。你给它一个数据源provider即按需求提供瓦片数据的对象加载瓦片到合成画面的事都由引擎接手。三种形状与默认包围盒provider 必须声明体积是什么形状Cesium.VoxelShapeType支持BOX、ELLIPSOID、CYLINDER三个值。每种形状都有一对默认 min/max 边界由 VoxelShapeType 的getMinBounds/getMaxBounds提供数据没占满默认范围时才需要自己覆盖。椭球示例里就把minBounds.z设为 0、maxBounds.z设为 1000000把单位椭球拉伸到 1 千米高。跑通最小 demo三步搞定 512 个体素形状声明和默认包围盒到手了下面真正跑一遍最小示例。想动手的话先git clone https://gitcode.com/GitHub_Trending/ce/cesium官方示例 是程序化生成数据、不依赖任何外部文件写法可以直接照搬。把数据打包并写出 provider以 8×8×8 的立方体为例共 512 个体素每个体素是一个 4 通道的VEC43 个 RGB 1 个属性通道也就是 512 × 4 2048 个 float顺序填进一个Float32Array即可。provider.shape Cesium.VoxelShapeType.BOX; provider.dimensions new Cesium.Cartesian3(8, 8, 8); provider.names [color]; provider.types [Cesium.MetadataType.VEC4]; provider.availableLevels 1; provider.requestData () Promise.resolve(Cesium.VoxelContent.fromMetadataArray([data])); viewer.scene.primitives.add(new Cesium.VoxelPrimitive({ provider }));其中names/types相当于数据的字段声明着色器那边靠这些名字取值requestData会被引擎在需要某个瓦片时调用把数据用 VoxelContent.fromMetadataArray 包好返回就行。挂载 primitive 并让相机飞过去scene.primitives.add(new Cesium.VoxelPrimitive({ provider }))之后管线就开始转了接着flyToBoundingSphere(voxelPrimitive.boundingSphere)把相机对准体积中心。调试时再调一下viewer.extend(Cesium.viewerVoxelInspectorMixin)挂上体素检查器采样与渲染参数都能直接在界面上改。这时场景里会悬浮出一块半透明的彩色渐变立方体——你的第一份体素渲染就出来了。屏幕上每个像素到底怎么算的打开着色器看看。数据进来之后逐格步进、沿途合成体素渲染的核心是光线步进ray marching每个像素从相机发射一条射线射线沿方向逐格穿过体积在每格取属性、累加颜色与透明度直到穿出边界。思路同浏览器端光线追踪但没有 CPU 侧的追踪——这一切都发生在片元着色器里。自定义着色器决定长什么样官方示例传入了这样一段 GLSLvoid fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) { material.diffuse fsInput.metadata.color.rgb; float transparency 1.0 - fsInput.metadata.color.a; float thickness fsInput.voxel.travelDistance / 1000000.0; material.alpha 1.0 - pow(transparency, thickness); }指数衰减如何模拟光的散射第 4 行值得细看fsInput.voxel.travelDistance是射线在体积里已走过的路径长度pow(transparency, thickness)是一种指数衰减用来模拟光在介质中的散射。路径穿过得越厚结果越不透明——这正是体积区别于表面的观感来源。不传 customShader 也没关系buildVoxelCustomShader会按 provider 的元数据自动建一份默认版本裸写new Cesium.VoxelPrimitive({ provider })同样能出图。真实数据怎么接进 3D Tiles示例跑通后下一个问题自然是我自己的数据在服务端是一堆瓦片怎么喂进来答案是把它写成 3D Tiles 体素扩展3DTILES_content_voxels的格式。样例数据就在仓库里Apps/SampleData/Cesium3DTiles/Voxel/ 下有三套完整样例VoxelBox3DTiles、VoxelCylinder3DTiles、VoxelEllipsoid3DTiles。每份tileset.json都在extensions的3DTILES_content_voxels字段里声明了形状与数据布局拿它当模板改自己的数据即可。一行 fromUrl 拿到地址型 providervoxels-in-3d-tiles 示例 只写了一行Cesium3DTilesVoxelProvider.fromUrl(.../VoxelBox3DTiles/tileset.json)返回的 provider 直接丢进VoxelPrimitive。后续瓦片切分、层级管理都走和普通 3D Tiles 相同的管线你不用为体素单独造一套加载系统。性能调优三个容易踩的坑示例只有 512 个体素你的真实数据可能是 256×256×128这时下面几个开关决定画面卡不卡。让瓦片层级替你省算力多瓦片版本的示例把availableLevels设为 2每个瓦片 4×4×4 格paddingBefore/paddingAfter各再垫一圈 1 格边让瓦片接缝处的采样连续、不出现颜色断层。打开calculateStatistics: true后能统计已加载瓦片数与渲染调用次数方便你确认层级策略是否生效。这是浏览器网络面板瓦片请求全部命中磁盘缓存耗时只有几毫秒。看到锯齿先试 nearestSampling把voxelPrimitive.nearestSampling设为true采样从双线性切换成最近邻高对比属性的边缘会更锐利代价是可能出现轻微色带。数据是连续场如温度就保持默认双线性是离散类别如岩层就打开它。体素渲染仍处在实验阶段但路已经打通provider 喂数据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),仅供参考
返回列表