?????在Cesium中渲染圓錐體時,無論采用頂點著色器、Canvas動態貼圖還是靜態圖片貼圖,其漸變色均需滿足以下條件:
- 圓形結構:漸變范圍限定在圓錐底面的圓形區域內。
- 徑向擴散:顏色從圓心向外逐步變化(如紅→黃→藍)。
- 一致性:三種方案均基于“圓形中心→邊緣”的漸變邏輯。
方案一:頂點著色器動態計算(實時性最高)
特點:通過GLSL代碼直接計算圓心到邊緣的距離,實現純圓形漸變。
// 創建圓錐幾何體(底面為圓形)
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繪制徑向漸變圓形紋理,貼合圓錐底面。
// 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漸變參數(如顏色分段)。
方案三:靜態圖片貼圖(性能最優)
特點:預加載圓形漸變圖片,適合固定漸變邏輯。
// 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動態生成貼圖。
- 需要極致性能?→ 使用靜態圖片貼圖。