背景:为什么需要在Cesium中编写glsl代码?

在三维数字孪生系统中,使用Cesium的基础功能已经能满足常见的三维渲染需求,但想要追求更好的效果,比如高质量水面、体积云、流体模拟、流动飞线、雷达扫描等酷炫的效果,则需要通过编写glsl代码来实现。

Cesium中glsl代码入口盘点

1. Appearance(最底层)

  • 本质:直接定义完整的渲染管线,包括顶点着色器、片元着色器、渲染状态(深度测试、剔除等)。
  • 特点:完全从零开始控制渲染,没有预设逻辑,需要自己实现所有顶点变换…

Cesium中Appearance的vertexShaderSource、FragmentShaderSource,Materia的shaderSource,material.fabric.source,这三者里面写着色器代码有啥区别

在 Cesium 中,AppearancevertexShaderSource/fragmentShaderSourceMaterialshaderSource以及material.fabric.source这三种方式都用于编写着色器代码,但它们的抽象层级、使用场景和功能边界有显著区别,核心差异体现在封装程度与 Cesium 渲染管线的集成方式上。

1. Appearance 中的 vertexShaderSource /fragmentShaderSource

  • 定位:最底层的着色器定义方式,直接控制完整渲染管线。

  • 特点

    • 需要编写完整的顶点着色器和片元着色器代码,从顶点变换到最终像素颜色输出的全流程都需手动实现。
    • 必须遵循 Cesium 的着色器规范(例如使用czm_modelViewProjection等内置变量、out_FragColor作为片元输出等)。
    • 不依赖任何预设逻辑,完全自主控制渲染,适合实现高度定制化的几何体渲染(如特殊网格、自定义地形效果等)。
  • 示例场景:自定义 Primitive 渲染复杂几何体时,需要精确控制顶点处理和像素着色逻辑。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Appearance中直接定义完整着色器
const appearance = new Cesium.Appearance({
vertexShaderSource: `
attribute vec3 position;
void main() {
gl_Position = czm_modelViewProjection * vec4(position, 1.0);
}
`,
fragmentShaderSource: `
void main() {
out_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // 红色
}
`
});

2. Material 中的 shaderSource(传统 Material 定义)

  • 定位:中等抽象层级,用于定义材质的着色逻辑,依赖 Cesium 的材质系统框架。
  • 特点:
    • 主要用于Material的传统定义方式(非 Fabric 语法),需编写片元着色器代码(顶点着色器通常由 Cesium 自动生成)。
    • 着色器代码会被嵌入到 Cesium 的标准渲染管线中,自动集成光照、纹理采样等基础功能。
    • 可通过uniforms传递参数,但灵活性低于直接编写 Appearance 着色器。
  • 示例场景:定义简单的自定义材质(如纯色、纹理混合等),无需控制顶点处理逻辑。
1
2
3
4
5
6
7
8
9
10
11
12
// 传统Material定义(较少使用)
const material = new Cesium.Material({
shaderSource: `
uniform vec3 color;
void main() {
out_FragColor = vec4(color, 1.0);
}
`,
uniforms: {
color: new Cesium.Color(1.0, 0.0, 0.0)
}
});

3. material.fabric.source(Fabric 材质系统)

  • 定位:最高级的抽象,基于 Cesium 的 Fabric 声明式语法定义材质,是推荐的材质定义方式。
  • 特点:
    • 支持顶点着色器(vertexShaderSource)和片元着色器(fragmentShaderSource),但代码会被 Cesium 的 Fabric 系统处理,自动整合到标准渲染流程中。
    • 可通过componentsuniformssources等配置项复用内置材质(如ImageStripe),实现材质组合(如纹理 + 颜色混合)。
    • 自动处理与 Cesium 内置功能的集成(如光照、雾化、深度测试),无需手动编写完整管线代码。
  • 示例场景:大多数自定义材质需求,如颜色渐变、纹理动画、基于高度的颜色混合(如水深渲染)等。

javascript

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Fabric材质定义(推荐)
const material = new Cesium.Material({
fabric: {
type: 'WaterDepth',
uniforms: {
depth: 1000.0
},
source: `
uniform float depth;
void main() {
out_FragColor = vec4(depth / 2000.0, 0.0, 1.0, 1.0);
}
`
}
});

核心区别总结

维度 Appearance 着色器 Material.shaderSource material.fabric.source
抽象层级 最底层(直接控制渲染管线) 中等(依赖材质框架) 最高级(Fabric 声明式语法)
编写内容 完整顶点 + 片元着色器 仅片元着色器(顶点由 Cesium 生成) 可定义顶点 / 片元着色器,支持复用
灵活性 最高(完全自定义) 中等(受材质框架限制) 较高(兼顾灵活性与集成性)
集成难度 高(需手动处理管线细节) 中(需了解材质系统) 低(声明式语法,自动集成)
典型用途 复杂几何体渲染、特殊管线需求 简单自定义材质(较少使用) 大多数自定义材质(推荐)

选择建议

  • 若需完全控制渲染流程(如特殊几何体、自定义顶点处理),使用Appearance 的着色器
  • 若需定义可复用的材质(如颜色、纹理、特效),优先使用Fabric 的 source,它是 Cesium 推荐的材质定义方式,兼顾灵活性和易用性。
  • 传统的Material.shaderSource已逐渐被 Fabric 系统替代,除非维护旧代码,否则不建议使用。