这节课,我们真正动手“写”材质——在 Fabric 里直接撸 GLSL 源码,让条纹动起来,为后面做扫描、雷达、飞线打好底子。
先弄清两个结构,再写两行代码,你就能让像素听你指挥。
一、两个“工具箱”先认全
https://cesium.com/downloads/cesiumjs/releases/b28/Documentation/czm_materialInput.html?classFilter=material&show=glsl
czm_materialInput—— 传进来的“原材料”
官网老文档(b28)里列得清清楚楚:s/st/str:一维、二维、三维纹理坐标,就是 UV;normalEC:眼睛坐标系的法线;tangentToEyeMatrix:切线→眼睛转换矩阵;positionToEyeEC:当前点到相机的向量。
想画渐变、扫描、雷达圈,全靠它们。
czm_material—— 要返回的“成品”
调用czm_getDefaultMaterial(...)就能拿到带默认值的结构,常用字段:diffuse:漫反射颜色(rgb 0~1);alpha:透明度;emission:自发光;specular/shininess:高光颜色与系数。
改哪个字段,像素就呈现哪部分效果。
二、UV 可视化:把坐标当成颜色
把st直接塞进diffuse,一眼就能看到 UV 分布:
czm_material czm_getMaterial(czm_materialInput materialInput) { czm_material mat = czm_getDefaultMaterial(materialInput); mat.diffuse = vec3(materialInput.st, 0.0); // R=U, G=V, B=0 return mat; }屏幕瞬间变成“红→绿”渐变:左边 U=0 全黑,右边 U=1 全红;下边 V=0 全黑,上边 V=1 全绿——UV 范围一目了然。
三、手撕条纹:mod 函数一秒出十条
想让矩形表面出现 10 条红白相间横纹,只需对 U 方向求余:
float strength = mod(materialInput.st.x * 10.0, 1.0); // 0~1 循环 10 次 mat.diffuse = vec3(strength, 0.0, 0.0); // 纯红渐变乘 10 再把结果限制在 0~1,就出现 10 条“从黑到红”的条纹;
想竖条?把
st.x换成st.y;想彩条?给 G、B 也加不同系数,彩虹立刻出来。
四、让条纹跑起来:uniform + GSAP 双剑合璧
静态不过瘾,我们把时间变量uTime传进着色器,让条纹移动:
const rawMaterial = new Cesium.Material({ fabric: { uniforms: { uTime: 0.0 // 初始时间 }, source: ` czm_material czm_getMaterial(czm_materialInput materialInput) { czm_material mat = czm_getDefaultMaterial(materialInput); float strength = mod((materialInput.st.x + uTime) * 10.0, 1.0); mat.diffuse = vec3(strength, 0.0, 0.0); return mat; } ` } });外面用 GSAP 不停改uTime,条纹就会平滑游走:
gsap.to(rawMaterial.uniforms, { uTime: 1.0, // 从 0 跑到 1 duration: 2.0, // 两秒一圈 repeat: -1, // 无限循环 ease: 'linear' });想反向跑?把
+ uTime改成- uTime即可;想竖向跑?换
st.y;想斜着跑?
st.x + st.y + uTime随便组合。
五、小结与展望
记住“原材料”
czm_materialInput和“成品”czm_material两大结构,就能随便改 diffuse、alpha、emission。mod(uv * 倍数 + 时间, 1.0)是扫描、雷达、跑马灯的灵魂公式。用 GSAP(或任何帧循环)改 uniform,就能把静态图案变成动画。
下节课,我们在这个“会动的条纹”上加圆遮罩、改自发光,一条完整的“雷达扫描圈”就诞生了。