news 2026/6/9 19:40:02

Cesium进阶教程(1)在cesium后处理中使用shadertoy的代码

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Cesium进阶教程(1)在cesium后处理中使用shadertoy的代码

本系列教程适合有前端基础以及一定三维GIS开发基础、想学习cesium高阶内容的同学,例如:WebGIS开发工程师、前端工程师、GIS专业学生和相关科研人员等。
视频版戳此处观看

01 什么是shader

在 Cesium 中,CustomShader是一个非常强大的接口,用来自定义图形渲染过程中的 GLSL 着色逻辑,让开发者可以对 3D Tiles、模型(Model)或 Primitive 等对象实现更灵活、复杂的视觉效果。
CustomShader让你可以在 Cesium 的标准渲染管线中插入自己的 GLSL 代码,从而控制模型的 顶点变换 和 片元着色 过程。 也就是说,你可以让模型发光、流动、闪烁、根据高度变色、按时间变化、根据法线方向渐变等。

02 基本原理

在 Cesium 中,每个 3D 模型或 Tileset 都会使用一个默认的渲染着色器(Shader Program)。 而CustomShader的作用就是允许你在保留 Cesium 默认功能的前提下,往其中注入自定义的 GLSL 代码。
它主要能影响两个阶段:

  • Vertex Shader 阶段(顶点处理)
  • Fragment Shader 阶段(像素着色)

在这些阶段里面可以获取到一些重要的数据:

|Corresponding AttributeinModel|variableinshader|Type|AvailableinVertex Shader?|AvailableinFragment Shader?|Description||--------------------------------|------------------|-------|---------------------------|-----------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------||`POSITION`|`positionMC`|`vec3`|Yes|Yes|Positioninmodel coordinates||`POSITION`|`positionWC`|`vec3`|No|Yes|Positioninworldcoordinates(WGS84ECEF`(x, y, z)`).Low precision.||`POSITION`|`positionEC`|`vec3`|No|Yes|Positionineye coordinates.||`NORMAL`|`normalMC`|`vec3`|Yes|No|Unit-length normal vectorinmodel coordinates.Only availableinthe vertex shader||`NORMAL`|`normalEC`|`vec3`|No|Yes|Unit-length normal vectorineye coordinates.Only availableinthe fragment shader||`TANGENT`|`tangentMC`|`vec3`|Yes|No|Unit-length tangent vectorinmodel coordinates.This is always a`vec3`.For models that provide a`w`component,that is removed after computing the bitangent vector.||`TANGENT`|`tangentEC`|`vec3`|No|Yes|Unit-length tangent vectorineye coordinates.This is always a`vec3`.For models that provide a`w`component,that is removed after computing the bitangent vector.||`NORMAL`&`TANGENT`|`bitangentMC`|`vec3`|Yes|No|Unit-length bitangent vectorinmodel coordinates.Only available when both normal and tangent vectors are available.||`NORMAL`&`TANGENT`|`bitangentEC`|`vec3`|No|Yes|Unit-length bitangent vectorineye coordinates.Only available when both normal and tangent vectors are available.||`TEXCOORD_N`|`texCoord_N`|`vec2`|Yes|Yes|`N`-thsetoftexture coordinates.||`COLOR_N`|`color_N`|`vec4`|Yes|Yes|`N`-thsetofvertex colors.This is always a`vec4`;ifthe model does not specify an alpha value,it is assumed to be1.||`JOINTS_N`|`joints_N`|`ivec4`|Yes|Yes|`N`-thsetofjoint indices||`WEIGHTS_N`|`weights_N`|`vec4`|

在cesium后处理中使用shadertoy的代码

我们也可以去shdertoy上找一些比较好的移植到cesium里面,比如我找了一个下雪的:https://www.shadertoy.com/view/ldsGDn

我们只需要把Shadertoy的代码做以下修改适配Cesium:

  1. 入口函数:
    ShaderToy 用mainImage(out vec4 fragColor, in vec2 fragCoord)
    Cesium 用void main(void),最终写gl_FragColor

  2. 内置变量替换:
    iResolution.xyczm_viewport.zw
    fragCoord.xygl_FragCoord.xy
    iTimeczm_frameNumber / 60.0(假设帧率 60fps)
    iMouse→ 没有鼠标交互,通常直接去掉或改为常量

  3. 最终颜色混合:
    在 Cesium 中需要和场景颜色混合,所以要读取colorTexture
    vec4 img = texture2D(colorTexture, v_textureCoordinates);gl_FragColor = img + vec4(acc, 1.0);

最终结果为:

constsnowShader=/*glsl*/`uniform sampler2D colorTexture; varying vec2 v_textureCoordinates; #define LIGHT_SNOW #ifdef LIGHT_SNOW #define LAYERS 50 #define DEPTH .5 #define WIDTH .3 #define SPEED .6 #else // BLIZZARD #define LAYERS 200 #define DEPTH .1 #define WIDTH .8 #define SPEED 1.5 #endif void main(void) { const mat3 p = mat3( 13.323122,23.5112,21.71123, 21.1212,28.7312,11.9312, 21.8112,14.7212,61.3934 ); vec2 resolution = czm_viewport.zw; vec2 fragCoord = gl_FragCoord.xy; // ShaderToy 的 iTime -> 用 frameNumber 模拟时间 float iTime = float(czm_frameNumber) / 60.0; // ShaderToy 的 uv 计算 vec2 uv = vec2(1.0, resolution.y / resolution.x) * fragCoord / resolution; vec3 acc = vec3(0.0); float dof = 5.0 * sin(iTime * 0.1); for (int i = 0; i < LAYERS; i++) { float fi = float(i); vec2 q = uv * (1.0 + fi * DEPTH); q += vec2( q.y * (WIDTH * mod(fi * 7.238917, 1.0) - WIDTH * 0.5), SPEED * iTime / (1.0 + fi * DEPTH * 0.03) ); vec3 n = vec3(floor(q), 31.189 + fi); vec3 m = floor(n) * 0.00001 + fract(n); vec3 mp = (31415.9 + m) / fract(p * m); vec3 r = fract(mp); vec2 s = abs(mod(q, 1.0) - 0.5 + 0.9 * r.xy - 0.45); s += 0.01 * abs(2.0 * fract(10.0 * q.yx) - 1.0); float d = 0.6 * max(s.x - s.y, s.x + s.y) + max(s.x, s.y) - 0.01; float edge = 0.005 + 0.05 * min(0.5 * abs(fi - 5.0 - dof), 1.0); acc += vec3(smoothstep(edge, -edge, d) * (r.x / (1.0 + 0.02 * fi * DEPTH))); } vec4 img = texture2D(colorTexture, v_textureCoordinates); gl_FragColor = img + vec4(acc, 1.0); }`;constsnowPost=newCesium.PostProcessStage({name:"snow",fragmentShader:snowShader,});viewer.scene.postProcessStages.add(snowPost);


看不明白没关系,需要上述视频教程+源码的同学可以直接
+下方小助手↓备注【cesium进阶】无偿获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/9 19:06:36

原始云杉林环绕的秘境,藏着丽江的干净与辽阔

在云南丽江&#xff0c;玉龙雪山东麓海拔约3240米的山箐中&#xff0c;隐藏着一片独特的高山景观——云杉坪。这是一片被原始云杉林环抱的宽阔草甸&#xff0c;纳西语称其为“游午阁”。其核心特点在于&#xff0c;它集中展示了显著的植被垂直分布&#xff1a;从脚下平缓的高山…

作者头像 李华
网站建设 2026/6/10 11:43:39

怎么把安卓手机数据导入苹果手机?这4个工具最靠谱

同品牌换机迁移数据已经够让人头疼了&#xff0c;安卓换到苹果迁移数据更是愁上加愁。无论是照片、联系人还是其他数据&#xff0c;都希望能无缝过渡&#xff0c;以确保后续正常使用。那么&#xff0c;究竟该怎么把安卓手机数据导入苹果手机呢&#xff1f;这篇教程将提供清晰的…

作者头像 李华
网站建设 2026/6/8 22:50:52

降AIGC率神器实测,8款AI赶due救星!

哈喽&#xff0c;大家好&#xff01;我是小李&#xff08;自称老李也行&#xff0c;毕竟32岁了&#xfffd;&#xfffd;&#xff09;。今天咱们来聊聊一个火爆话题——论文被AI检测卡住了&#xff1f;别慌&#xff01;我亲身体验了8款AI工具&#xff0c;帮你赶due救急&#xf…

作者头像 李华
网站建设 2026/6/6 10:25:13

【预测模型】基于深度置信网络DBN锂电池寿命预测附Matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。&#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室&#x1f447; 关注我领取海量matlab电子书和…

作者头像 李华
网站建设 2026/6/5 0:13:16

CAN FD总线协议深度解析:技术特点与应用优势

&#x1f4e1; 核心背景与协议演进技术背景经典CAN局限&#xff1a;CAN 2.0A/2.0B协议&#xff08;1Mbps传输速率、8字节数据位宽&#xff09;已无法满足现代汽车电子系统对通信数据量和实时性的需求。协议推出&#xff1a;2012年由博世公司推出CAN FD&#xff08;Controller A…

作者头像 李华