Cesium圆锥渐变色实现:融合顶点着色器、Canvas动态贴图与静态纹理的多方案整合

在Cesium中渲染圆锥体时,无论采用顶点着色器Canvas动态贴图 还是静态图片贴图,其渐变色均需满足以下条件:

  1. 圆形结构:渐变范围限定在圆锥底面的圆形区域内。
  2. 径向扩散:颜色从圆心向外逐步变化(如红→黄→蓝)。
  3. 一致性:三种方案均基于"圆形中心→边缘"的渐变逻辑。

方案一:顶点着色器动态计算(实时性最高)

特点 :通过GLSL代码直接计算圆心到边缘的距离,实现纯圆形渐变

javascript 复制代码
// 创建圆锥几何体(底面为圆形)
const coneGeometry = Cesium.CylinderGeometry.createGeometry(
    new Cesium.CylinderGeometry({
        length: 200000,
        topRadius: 0,
        bottomRadius: 100000, // 底面半径
        vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT,
    })
);

// 自定义着色器:基于UV距离计算圆形渐变
const material = new Cesium.Material({
    fabric: {
        type: 'RadialGradientCone',
        source: `
      czm_material czm_getMaterial(czm_materialInput materialInput) {
        czm_material material = czm_getDefaultMaterial(materialInput);
        
        // 计算当前像素到圆心的距离(UV坐标系中)
        vec2 st = materialInput.st;
        vec2 center = vec2(0.5, 0.5); // 圆心位置
        float distance = length(st - center); // 径向距离
        
        // 归一化到 [0,1],确保渐变从中心向外扩展
        float normalizedDistance = clamp(distance / 0.5, 0.0, 1.0);

        // 圆形渐变逻辑(红→黄→蓝)
        if (normalizedDistance < 0.33) {
          material.diffuse = vec3(1.0, 0.0, 0.0); // 红色
        } else if (normalizedDistance < 0.66) {
          material.diffuse = vec3(1.0, 1.0, 0.0); // 黄色
        } else {
          material.diffuse = vec3(0.0, 0.0, 1.0); // 蓝色
        }

        // 透明度随距离增加而降低
        material.alpha = 1.0 - normalizedDistance * 0.5;
        return material;
      }
    `,
        uniforms: {},
    },
});

// 应用到Primitive
const geometryInstance = new Cesium.GeometryInstance({ geometry: coneGeometry });
const primitive = new Cesium.Primitive({
    geometryInstances: geometryInstance,
    appearance: new Cesium.MaterialAppearance({
        material: material,
        closed: true,
    }),
});
viewer.scene.primitives.add(primitive);

关键点

  • length(st - center):确保渐变方向从圆心向外。
  • clamp(distance / 0.5, 0.0, 1.0):限制渐变范围在圆形区域内。
  • 实时性:适合动态属性(如风速、温度)驱动的渐变。

方案二:Canvas动态生成径向渐变贴图(灵活性高)

特点 :通过Canvas绘制径向渐变圆形纹理,贴合圆锥底面。

javascript 复制代码
// 1. 创建Canvas并绘制圆形径向渐变
const canvas = document.createElement('canvas');
canvas.width = 256;
canvas.height = 256;
const ctx = canvas.getContext('2d');

// 定义径向渐变(圆心→边缘)
const gradient = ctx.createRadialGradient(128, 128, 0, 128, 128, 128);
gradient.addColorStop(0, 'red');
gradient.addColorStop(0.5, 'yellow');
gradient.addColorStop(1, 'blue');
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, 256, 256);

// 2. 将Canvas转换为ImageResource
const imageResource = new Cesium.ImageResource({
    source: canvas,
});

// 3. 创建贴图材质(圆形渐变)
const imageMaterial = new Cesium.Material({
    fabric: {
        type: 'ImageRadialGradient',
        source: `
      czm_material czm_getMaterial(czm_materialInput materialInput) {
        czm_material material = czm_getDefaultMaterial(materialInput);
        vec2 st = materialInput.st;
        vec4 color = texture(imageMap, st);
        material.diffuse = color.rgb;
        material.alpha = color.a;
        return material;
      }
    `,
        uniforms: {
            imageMap: imageResource,
        },
    },
});

// 应用到Primitive
const geometryInstance = new Cesium.GeometryInstance({ geometry: coneGeometry });
const primitive = new Cesium.Primitive({
    geometryInstances: geometryInstance,
    appearance: new Cesium.MaterialAppearance({
        material: imageMaterial,
        closed: true,
    }),
});
viewer.scene.primitives.add(primitive);

关键点

  • createRadialGradient:Canvas API原生支持径向渐变。
  • 贴图适配:需确保圆锥底面UV映射为正方形区域(避免拉伸)。
  • 灵活性:可动态调整Canvas渐变参数(如颜色分段)。

方案三:静态图片贴图(性能最优)

特点:预加载圆形渐变图片,适合固定渐变逻辑。

javascript 复制代码
// 1. 准备静态圆形渐变图片(如 gradient.png)
const imageMaterial = new Cesium.Material({
    fabric: {
        type: 'StaticRadialGradient',
        source: `
      czm_material czm_getMaterial(czm_materialInput materialInput) {
        czm_material material = czm_getDefaultMaterial(materialInput);
        vec2 st = materialInput.st;
        vec4 color = texture(staticMap, st);
        material.diffuse = color.rgb;
        material.alpha = color.a;
        return material;
      }
    `,
        uniforms: {
            staticMap: 'path/to/gradient.png', // 需预先绘制圆形渐变
        },
    },
});

// 应用到Primitive
const geometryInstance = new Cesium.GeometryInstance({ geometry: coneGeometry });
const primitive = new Cesium.Primitive({
    geometryInstances: geometryInstance,
    appearance: new Cesium.MaterialAppearance({
        material: imageMaterial,
        closed: true,
    }),
});
viewer.scene.primitives.add(primitive);

关键点

  • 图片设计:需手动绘制或生成圆形径向渐变(如Photoshop或程序生成)。
  • 性能优势:无需运行时计算,适合大规模渲染。

三种方案对比与选择建议
方案 渐变类型 实时性 灵活性 性能 适用场景
顶点着色器 ✅ 圆形径向 ✅ 高 ✅ 高 ✅ 高 动态属性驱动、实时变化
Canvas动态贴图 ✅ 圆形径向 ⚠ 中 ✅ 高 ⚠ 中 复杂渐变、交互式调整
静态图片贴图 ✅ 圆形径向 ❌ 低 ❌ 低 ✅ 高 固定渐变、大规模渲染

总结

三种方案均通过圆形结构+径向扩散实现渐变色,区别在于:

  • 顶点着色器:实时计算,适合动态数据。
  • Canvas贴图:灵活定制,适合复杂渐变。
  • 静态贴图:性能最佳,适合固定逻辑。

最终选择建议

  • 需要实时响应属性变化 → 使用顶点着色器。
  • 需要复杂渐变设计 → 使用Canvas动态生成贴图。
  • 需要极致性能 → 使用静态图片贴图。
相关推荐
geobuilding23 分钟前
将大规模shp白模贴图转3dtiles倾斜摄影,并可单体化拾取建筑
算法·3d·智慧城市·数据可视化·贴图
da_vinci_x6 天前
Substance Designer“程序化地形”与“Splat Map”生成管线
游戏·aigc·设计师·贴图·技术美术·游戏美术·substance designer
流星魂小七8 天前
颜色选择器
android·着色器·环形颜色选择器·圆形颜色选择器·colorpicker·colorwheelview
da_vinci_x8 天前
在Substance Designer里“预演”你的游戏着色器(Shader)
人工智能·游戏·技术美术·着色器·游戏策划·游戏美术·substance designer
reddingtons8 天前
ZBrush细节烘焙全“糊”了?Painter“平均法线”+“偏斜贴图”的“无笼”烘焙管线
游戏·设计师·贴图·技术美术·substance painter·游戏美术·zbrush
gis分享者8 天前
学习threejs,基于噪声函数的顶点着色器动态插桩技术实现模型形变
threejs·模型·着色器·顶点·动态插桩·噪声函数·形变
摄影图10 天前
精美酒瓶艺术改造图片:插花雕塑灯具创意展示 从旧酒瓶到生活艺术品:手残党改造灵感
贴图
bb456b16 天前
Snipaste (截图贴图工具) 精准截图 中文免费版
java·工具·贴图
da_vinci_x18 天前
Substance Designer的通道合并(Channel Packing)自动化工作流
3d·自动化·贴图·技术美术·游戏策划·游戏美术·substance designer
悦人楼20 天前
C4D实战技巧:域与顶点贴图在布料动力学中详细解析附资源
贴图·c4d实战技巧·域与顶点贴图·布料动力学中详细解析