直接上代碼吧
方法一:采用自定義shader 的實現,利用cesium內置的glsl變量是紋理隨着時間按照指定方向進行流動。效果圖中科技感的數字流動是呈現沿着線往上流動,這種效果很適合在智慧城市數字孿生的場景中結合其他的三維地物作為裝飾。我們可以看到wall的方向跟線的方向流動的方向是不一樣的,wall 的流動方向是橫着流動,這是着色器中的紋理方向的設置相關,我這里沒有把wall的代碼放出來。不過,如何更改流動方向,我相信聰明的你應該清楚如何更改了。趕緊去試一試吧。這種方式用的是addPrimiFlowline 方法
let source1 = "czm_material czm_getMaterial(czm_materialInput materialInput)\n\
{\n\
czm_material material = czm_getDefaultMaterial(materialInput);\n\
vec2 st = fract (repeat *materialInput.st);\n\
float time = czm_frameNumber * animationSpeed;\n\
vec4 colorImage = texture2D(image, vec2(st.t,fract((st.s - time)) ));\n\
vec4 fragColor;\n\
fragColor.rgb = (colorImage.rgb+color.rgb) / 1.0;\n\
fragColor = czm_gammaCorrect(fragColor);\n\
material.alpha = colorImage.a * color.a;\n\
material.diffuse = (colorImage.rgb+color.rgb)/2.0;\n\
material.emission = fragColor.rgb;\n\
return material;\n\
}";
function addPrimitiveFlowAppear(pos){
var primitive = new Cesium.Primitive({
geometryInstances : new Cesium.GeometryInstance({
geometry : new Cesium.PolylineGeometry({
positions : pos,
width : 5,
vertexFormat : Cesium.PolylineMaterialAppearance.VERTEX_FORMAT//可以不設置,一般會根據 appearance的類型自動默認對應的類型
}),
attributes : {
//color : Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(1.0, 1.0, 1.0, 1.0))
}
}),
appearance : new Cesium.PolylineMaterialAppearance({
material :
Cesium.Material.fromType(Cesium.Material.FadeType, {
repeat: true,
fadeInColor: Cesium.Color.BLUE.withAlpha(0),
fadeOutColor: Cesium.Color.WHITE,
time: new Cesium.Cartesian2(0.0, 0.0),
fadeDirection: {
x: true,
y: false,
}
})
})
});
return primitive
}
function addPrimiFlowline(pos,fs){
var primitive = new Cesium.Primitive({
geometryInstances : new Cesium.GeometryInstance({
geometry : new Cesium.PolylineGeometry({
positions : pos,
width : 10
}),
attributes : {
//color : Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(1.0, 1.0, 1.0, 1.0))
}
}),
appearance : new Cesium.PolylineMaterialAppearance({
translucent : true
})
});
primitive.appearance.material=new Cesium.Material({
fabric: {
uniforms://uniforms,
{
image:wallMater,
animationSpeed:0,
color:Cesium.Color.GREEN.withAlpha(0.5),
repeat:new Cesium.Cartesian2(1.0,1.0)
},
source:fs
},
});
return primitive
}
// 通過設置fadetype 實現流動的線
let primi = this.addPrimitiveFlowAppear(positions)
viewer.scene.primitives.add(primi);
// 添加數字流動線
let linePos = Cesium.Cartesian3.fromDegreesArrayHeights([120.21725, 23.63556, 0,120.21725, 23.63556, 15000.0])
let linePos1 = Cesium.Cartesian3.fromDegreesArrayHeights([120.32044, 23.63392, 0, 120.32044, 23.63392, 15000.0])
let lineUniforms = {image:wallMater, animationSpeed:10,color:Cesium.Color.BLUE.withAlpha(0.6), repeat:new Cesium.Cartesian2(2.0,1.0)}
let num_line = this.addPrimiFlowline(linePos,source1)
num_line.appearance.material.uniforms=lineUniforms
let num_line1 = this.addPrimiFlowline(linePos1,source1)
num_line1.appearance.material.uniforms.color=Cesium.Color.BLACK
num_line1.appearance.material.uniforms.repeat=new Cesium.Cartesian2(2.0,1.0)
viewer.scene.primitives.add(num_line);
viewer.scene.primitives.add(num_line1);
var timex = 0;
function render() {
timex += 0.01;
if (timex >= 1.0) {
timex = 0; // 控制在0.0到1.0之間
}
primi.appearance.material.uniforms.time.x = timex;
requestAnimationFrame(render);
}
requestAnimationFrame(render);
方法二:根據cesium 內置的材質類型實現。具體介紹各位可以去API文檔查看,有哪些uniforms和各個屬性代表的意思也寫的很清楚。示例代碼看addPrimitiveFlowAppear方法。
要注意:
1、cesium繪制地物有兩種方式,一種是通過entity的方式。entity是cesium封裝的一種高級接口,很適合上手入門。entity添加的地物可以使用如以下已經封裝好的materialProperty 來組合各種材質效果,enetity詳細內容參考官方文檔,具體使用例子可以參考前面文章cesium property實現飛行實時姿態仿真中飛行尾部軌跡的實現
另一種是primitive的方式,本文中這兩個都是通過primitive來繪制幾何體。他們的材質跟前面講的property是不一樣的機制,cesium通過primitive提高了渲染的自由度,讓精通GLSL編程的開發者有更大的發揮舞台。在接口使用上的區別是:1、primitive通過appearance來給material賦值。2、上面列舉的materialproperty是不可以在這里使用的,但是內置的幾種類型材質可以使用,第二種實現方式實現就是利用內置的類型。
2、第二種實現方式中,通過內置材質類型的uniforms中的time必須是變化才能使其材質產生流動效果,因此為了讓其變換,我們將其放到requstAnimation中,進行修改。有沒有更好的實現方式呢,我們下期進行探討。
原文鏈接:https://blog.csdn.net/qq_26991807/article/details/123429407