1. 程式人生 > 其它 >Cesium之流動線紋理實現的兩種方式

Cesium之流動線紋理實現的兩種方式

直接上程式碼吧

方法一:採用自定義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,如有侵權,請聯絡刪除。