Cesium自定义着色器-abs() 函数

98 阅读3分钟

书接上文,前面我们探讨过片段着色器里面的模型位置坐标和模型坐标系中的各轴,下面我们继续由浅入深探讨:

void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material){
    vec3 positionMC = fsInput.attributes.positionMC;
    
    // 简单的 XYZ 颜色映射
    material.diffuse = vec3(
        abs(positionMC.x) * 0.01,
        abs(positionMC.y) * 0.01, 
        abs(positionMC.z) * 0.01
    );
}

上面代码代表什么意思呢?——

abs() 函数

一、是什么

意思是取绝对值

  • abs(x) 返回参数 x 的绝对值
  • 如果 x 是正数或零,返回 x 本身
  • 如果 x 是负数,返回 -x(即去掉负号)

在代码中的具体作用:

material.diffuse = vec3(
    abs(positionMC.x) * 0.01,  // 取X坐标的绝对值 × 0.01
    abs(positionMC.y) * 0.01,  // 取Y坐标的绝对值 × 0.01
    abs(positionMC.z) * 0.01   // 取Z坐标的绝对值 × 0.01
);

二、为什么要用 abs()

  1. 确保颜色值为正:颜色值通常需要在 0-1 范围内,使用绝对值避免负值
  2. 对称效果:在模型的原点(0,0,0)两侧产生相同的颜色分布
  3. 可视化目的:让负坐标区域也能显示颜色,而不是黑色

举例说明:

  • 如果 positionMC.x = -5.0abs(-5.0) * 0.01 = 0.05
  • 如果 positionMC.x = 5.0abs(5.0) * 0.01 = 0.05

这样就在X轴正负方向相同距离的位置显示相同的红色分量。

三、详细解释

继续之前的步骤,分轴测试:

(一) 测试 X 轴

1. 代码分析:
material.diffuse = vec3(
    abs(positionMC.x) * 0.01,  // 红色
    0.0,                       // 绿色 = 0  
    0.0                        // 蓝色 = 0
);

可以看到中间有条黑色的竖线

2. 颜色变化规律:
  • 在X=0处(Y-Z平面)
    • abs(0) * 0.01 = 0
    • RGB = (0, 0, 0) → 纯黑色
  • 在X=±10处
    • abs(10) * 0.01 = 0.1
    • RGB = (0.1, 0, 0) → 很暗的红色
  • 在X=±50处
    • abs(50) * 0.01 = 0.5
    • RGB = (0.5, 0, 0) → 中等红色
  • 在X=±100处
    • abs(100) * 0.01 = 1.0
    • RGB = (1.0, 0, 0) → 最亮的红色
3. 总结:

确实离X轴越近越黑,离X轴越远越红,形成了一个从中心黑色向两侧红色渐变的视觉效果。

(二) 测试 Y 轴

1. 代码分析:
material.diffuse = vec3(
    abs(positionMC.x) * 0.01,  // 红色通道
    abs(positionMC.y) * 0.01,  // 绿色通道  
    0.0                        // 蓝色通道 = 0
);

2. 颜色变化规律:
  • 原点 (0,0) :RGB(0,0,0) → 黑色
  • 纯X方向:RGB(红,0,0) → 红色
  • 纯Y方向:RGB(0,绿,0) → 绿色
  • X和Y都有值:RGB(红,绿,0) → 黄色
  • X大Y小:RGB(深红,浅绿,0) → 橙黄色
  • X小Y大:RGB(浅红,深绿,0) → 黄绿色
3. 总结:

这个着色器创建了一个在XY平面上的颜色渐变:

  • X轴控制红色分量
  • Y轴控制绿色分量
  • 两者结合产生从黑→红→绿→黄的渐变效果

(三) 测试 Z 轴

1. 代码分析:
material.diffuse = vec3(
    abs(positionMC.x) * 0.01,  // X轴 → 红色
    abs(positionMC.y) * 0.01,  // Y轴 → 绿色  
    abs(positionMC.z) * 0.01   // Z轴 → 蓝色
);

2. 颜色过渡规律:

在坐标轴上(纯色):

  • X轴上:RGB(红,0,0) → 纯红色
  • Y轴上:RGB(0,绿,0) → 纯绿色
  • Z轴上:RGB(0,0,蓝) → 纯蓝色

在坐标平面间(二次色):

  • XY平面:RGB(红,绿,0) → 黄色
  • XZ平面:RGB(红,0,蓝) → 紫色
  • YZ平面:RGB(0,绿,蓝) → 青色

在空间对角线上(三次色):

  • 所有坐标都有值:RGB(红,绿,蓝) → 白色/灰色
  • 原点:RGB(0,0,0) → 黑色
3. 过渡特点:
  1. 从中心向外辐射:原点最暗,向外逐渐变亮
  2. 颜色混合平滑:相邻区域颜色自然过渡
  3. 对称分布:由于abs(),每个象限颜色对称
  4. 三维感知:通过颜色可以直观判断点在空间中的位置
4. 视觉效果:

形成一个从中心黑色向各个方向渐变的彩色球体效果,非常适合可视化三维坐标系统和空间位置关系。

四、具体应用

如果想要实现如下十字形扫光,需要在两个方向上都使用绝对值来确保对称。

  • 水平扫光:在X轴正负方向对称出现
  • 垂直扫光:在Y轴正负方向对称出现
  • 组合效果:形成十字形的扫光图案

这样就能实现从中心向四个方向扩展的十字扫光效果!