SuperAPI AI 工具集

cesiumjs-custom-shader

智能体与模型

查看项目

更新于 10-16 11:51

技能介绍

用途

CesiumJS CustomShader 用于向 Model、Cesium3DTileset、VoxelPrimitive 的渲染管线注入用户编写的 GLSL 代码。它把 glTF 属性、feature ID 以及 EXT_structural_metadata 暴露给逐顶点和逐片元代码,并通过内置的 czm_modelVertexOutput 和 czm_modelMaterial 结构体返回结果。本技能专注于编写 shader 主体。

相关但不在本技能范围内:Fabric Material、ImageBasedLighting、PostProcessStage(见 cesiumjs-materials-shaders);通过 Cesium3DTileStyle 声明式逐要素着色及 VoxelPrimitive 配置(见 cesiumjs-3d-tiles);Model.fromGltfAsync、动画、ModelFeature.getProperty()(见 cesiumjs-models-particles)。在 glTF 中编写 EXT_structural_metadata / EXT_mesh_features 属于工具链问题,不是运行时范畴。

版本基线:CesiumJS 1.144,所有导入使用 ES module 风格。

主要能力

  • 着色器函数签名:void vertexMain(VertexInput vsInput, inout czm_modelVertexOutput vsOutput) 与 void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material)。参数名是契约的一部分,重命名会破坏着色器。
  • Uniforms:通过 { type, value } 声明,type 取 UniformType,JS 值类型必须匹配(如 VEC3 → Cartesian3)。支持 TextureUniform(url 或 typedArray + width + height,二者只能其一),仅支持 SAMPLER_2D,SAMPLER_CUBE 会在构造时抛错。运行时可调用 shader.setUniform() 更新。
  • Varyings:声明后自动生成 vertex 的 out 与 fragment 的 in。支持 FLOAT、VEC2–VEC4、MAT2–MAT4,无 INT/BOOL/SAMPLER 变体。
  • 模式与光照:CustomShaderMode 有 MODIFY_MATERIAL(默认,在材质阶段后、光照前运行)与 REPLACE_MATERIAL(完全跳过材质阶段)。LightingModel 有 UNLIT(跳过光照,flat-shaded)与 PBR(物理基础渲染,可用时带 IBL);省略则保留模型默认光照。
  • 半透明:CustomShaderTranslucencyMode 控制 alpha 写入如何处理——INHERIT(默认,仅当源材质半透明时 alpha 才生效)、OPAQUE、TRANSLUCENT。在不透明模型上用 INHERIT 写 material.alpha 会被静默忽略。
  • 属性:vsInput.attributes / fsInput.attributes 暴露 glTF 顶点属性,名称区分大小写,必须带坐标空间后缀(如 positionMC、positionWC、positionEC、normalMC、normalEC、tangent/bitangent、texCoord_N、color_N、joints_N、weights_N)。构造函数会扫描着色器文本并抛出 DeveloperError。自定义下划线前缀属性(如 _SURFACE_TEMP)会被小写化并去掉前缀。
  • FeatureIds:统一三种 glTF 来源:featureId_N(含 EXT_mesh_features 的属性与隐式属性,也覆盖 feature ID 纹理,仅片元)、instanceFeatureId_N(来自 EXT_instance_features + EXT_mesh_gpu_instancing)、命名别名。旧版 3D Tiles 1.0 的 BATCH_ID / _BATCHID 会透明重命名为 featureId_0。GLSL 类型始终为 int。
  • Metadata(EXT_structural_metadata):属性属性(逐顶点,顶点与片元)、属性纹理(逐纹素,仅片元)、属性表(逐要素,按 feature ID 索引,1.139 加入)。同时提供 metadataClass.<prop>.noData/defaultValue/minValue/maxValue 与 metadataStatistics.<prop> 的统计字段(需 tileset.json 声明 statistics)。属性 ID 会按 GLSL 标识符规则做净化,净化后碰撞为未定义行为。

使用方式

最小示例(Model):

import { CustomShader, Model } from "cesium";

const shader = new CustomShader({
  fragmentShaderText: `
    void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {
      material.diffuse = vec3(1.0, 0.0, 0.0);
    }
  `,
});

const model = await Model.fromGltfAsync({ url: "./aircraft.glb", customShader: shader });
viewer.scene.primitives.add(model);

应用方式:Model 可构造函数选项或可变属性(支持热替换与置空);Cesium3DTileset 同样支持构造选项与可变属性,但只影响 Model 支撑的瓦片内容;VoxelPrimitive 为仅片元子集。引擎每帧自动调用 customShader.update(frameState),使用完后调用 customShader.destroy() 释放 GPU 纹理资源。

构造函数参数:mode、lightingModel、translucencyMode、uniforms、varyings、vertexShaderText、fragmentShaderText。通常至少需要 vertexShaderText 或 fragmentShaderText 之一。

可视化评估建议:添加带着色器的 Model 后,等待模型达到可渲染状态,然后显式框定已知目标点,不要依赖加载后的第一帧或极小的默认缩放。公开模型评估可设置 minimumPixelSize(通常 256–400)、使用适度缩放,并在判断着色器效果时添加轮廓或强烈色彩。

示例文件:01-diffuse-tint.js(时间 uniform 驱动 diffuse)、02-texture-swap.js、03-feature-id-tileset.js、04-translucent-override.js、05-vertex-displacement.js、06-metadata-ramp.js、07-voxel-shader.js。

适用场景

  • 为 glTF 模型编写自定义逐顶点/逐片元着色。
  • 在 3D Tiles 上按 feature ID 做分类着色。
  • 读取并可视化 EXT_structural_metadata(属性属性/纹理/表)。
  • 体素(VoxelPrimitive)的逐体素元数据着色与光线步进逻辑。
  • 顶点位移与程序化平面着色(REPLACE_MATERIAL + UNLIT)。

限制与注意事项

  • 坐标空间后缀必需;在错误阶段使用(如顶点中的 positionEC、片元中的 normalMC)或使用裸 position/normal/tangent/bitangent 会抛出 DeveloperError。
  • 修改 czm_modelVertexOutput.positionMC 会位移顶点,但不会更新图元的包围球,大幅位移可能被视锥剔除。
  • SAMPLER_CUBE 在构造时被拒绝,仅支持 SAMPLER_2D。
  • Cesium3DTileset.customShader 标记为 @experimental,使用 3D Tiles 规范中尚未最终确定的表面,可能不遵循标准弃用策略。其 JSDoc 指出与 Cesium3DTileStyle 搭配可能导致未定义行为,不要在同一瓦片集上组合使用。
  • VoxelPrimitive 仅片元,提供 vertexShaderText 会被静默忽略;其 fsInput.attributes 仅有 positionEC 与 normalEC,无 featureIds、metadataClass,metadataStatistics 仅有 minValue 与 maxValue。将 customShader 置为 undefined 会回退到 VoxelPrimitive.DefaultCustomShader。
  • 1.139 破坏性变更:unsigned 整数元数据不再转有符号 int,把 UINT 属性赋给 GLSL int 将无法编译,需使用匹配的无符号类型。
  • 1.130 破坏性变更:fsInput.voxel.positionUv/positionShapeUv/positionLocal 已移除,改用 fsInput.attributes.positionEC;fsInput.voxel.surfaceNormal → fsInput.attributes.normalEC。
  • 1.142 修复后,内置默认体素着色器能更稳健地处理常见元数据类型,仅在需要显式分类、着色、过滤或光线步进逻辑时保留自定义着色器。
  • 带 EXT_structural_metadata 的公开 .glb 资产较少,多数真实元数据位于 3D Tiles 上。
  • 其余版本说明(1.139–1.142):#13170 修复点云属性精度;#13124 增加属性表元数据访问;#13135 增加属性纹理支持的元数据类型;#13231 元数据变量正则扩展到 metadataClass 与 metadataStatistics;#13247 NGA-GPM 本地扩展与自定义着色器回归修复;#13258 当元数据存在于类定义时,不再对缺失元数据的图元禁用自定义着色器;#13323 通过降精度提供有限的双精度元数据支持。

完整枚举值与内置 czm_* 自动 uniform(如 czm_frameNumber、czm_pi、czm_model、czm_view、czm_projection、czm_modelView、czm_normal、czm_lightDirectionEC、czm_sunDirectionWC、czm_eyeHeight、czm_sceneMode、czm_viewerPositionWC、czm_splitPosition)见 REFERENCE.md。