一、效果图
二、实现思路
使用着色器,通过纹理坐标和其他参数计算出材质的颜色和透明度。通过给定的颜色、漫反射强度和透明度,计算出最终的反射颜色和透明度,并且根据给定的中心点位置和当前像素的纹理坐标,计算出距离中心的距离用来做透明度的参考值,然后计算得到的颜色加载到对应的材质上。
三、完整代码
<template><div><button @click="handlePolygon()">渐变面</button><CesiumViewer /></div>
</template>
<script setup>
import { ref, onMounted } from "vue";
import CesiumViewer from "./components/cesiumViewer.vue";let viewer;
onMounted(() => {viewer = window.cesiumViewer;
});const updateResolutionScale = (viewer) => {//判断是否支持图像渲染像素化处理if (Cesium.FeatureDetection.supportsImageRenderingPixelated()) {viewer.resolutionScale = window.devicePixelRatio;}
};const PolyGradientMaterial = `uniform vec4 color;
uniform float diffusePower;
uniform float alphaPower;
uniform float globalAlpha;
uniform vec2 center;czm_material czm_getMaterial(czm_materialInput materialInput) {czm_material material = czm_getDefaultMaterial(materialInput);float time = czm_frameNumber/600.;float per = fract(time);vec2 st = materialInput.st;float alpha = distance(st, center);material.alpha = color.a * alpha * alphaPower * globalAlpha;material.diffuse = color.rgb * diffusePower;return material;
}`;let index = 0;
const arrColor = ["rgb(18,76,154)","rgb(15,176,255)","#40C4E4","#42B2BE","rgb(51,176,204)","#8CB7E5","rgb(0,244,188)","#139FF0",
];const getColor = () => {return arrColor[++index % arrColor.length];
};let totalLabel = 0;const addPolygon = (positions, color, name) => {const polygonOptions = {extrudedHeight: 1000,polygonHierarchy: new Cesium.PolygonHierarchy(positions),};const geometry = new Cesium.PolygonGeometry(polygonOptions);const geometryInstance = new Cesium.GeometryInstance({geometry: geometry,id: "chinaocean",});const material = new Cesium.Material({fabric: {source: PolyGradientMaterial,uniforms: {color: Cesium.Color.fromCssColorString(color),diffusePower: 1.8,alphaPower: 1.2,center: new Cesium["Cartesian2"](0.5, 0.5),globalAlpha: 0x1,},},translucent: true,});const primitive = new Cesium.Primitive({releaseGeometryInstances: false,asynchronous: false,geometryInstances: [geometryInstance],appearance: new Cesium.EllipsoidSurfaceAppearance({material: material,}),});// const removeListener = viewer.scene.postRender.addEventListener(() => {// if (!primitive.ready) {// return;// }// totalLabel += 1;// const position = primitive._boundingSpheres[0].center;// viewer.entities.add({// position,// label: {// text: name,// font: "32px 楷体",// fillColor: Cesium.Color.WHITE,// outlineColor: Cesium.Color.BLACK,// style: Cesium.LabelStyle.FILL_AND_OUTLINE,// outlineWidth: 2,// disableDepthTestDistance: 1000000000,// scale: 0.5,// pixelOffset: new Cesium.Cartesian2(0, -10),// backgroundColor: new Cesium.Color.fromCssColorString(// "rgba(0, 0, 0, 0.7)"// ),// backgroundPadding: new Cesium.Cartesian2(10, 10),// verticalOrigin: Cesium.VerticalOrigin.BOTTOM,// },// });// removeListener();// });viewer.scene.primitives.add(primitive);
};const handlePolygon = () => {updateResolutionScale(viewer);viewer.scene.skyBox.show = false;var mapOptions = {scene: {center: {lat: 30.037072,lng: 91.091762,alt: 1600000.0,heading: 160000.0,// 视角heading: 355,pitch: -88,},},};viewer.camera.flyTo({orientation: {heading: Cesium.Math.toRadians(mapOptions.scene.center.heading),pitch: Cesium.Math.toRadians(mapOptions.scene.center.pitch),},destination: Cesium.Cartesian3.fromDegrees(mapOptions.scene.center.lng,mapOptions.scene.center.lat,mapOptions.scene.center.alt),duration: 0,});Cesium.GeoJsonDataSource.load("https://geo.datav.aliyun.com/areas_v3/bound/540100.json").then((dataSource) => {const entities = dataSource.entities.values;// 遍历所有实体entities.forEach((entity, index) => {if (entity.polygon) {const positions = entity.polygon.hierarchy._value.positions;addPolygon(positions, getColor(index), entity.name);}});});
};
</script>
<style scoped></style>
*注:<CesiumViewer/>