cesium特效之电子围栏实现

前言

在一些智慧城市、智慧园区等等数字孪生的项目里,往往需要实现一些炫酷的特效去展示孪生数据,今天来教大家实现一个"电子围栏"的特效,可以用于区域范围展示、建筑效果选中等等功能,效果如下图。

基本原理

图形学中给模型贴图的原理是通过给每一个顶点加上一个‘UV’坐标,再通过这个左边取贴图读取相应的像素值,两个点之间的‘UV’坐标会插值。那么如何让贴图移动起来呢?原理很简单,我们只需要每一帧都给‘UV’坐标加上一个偏移的值,这样每一帧读取的像素值就会改变,贴图就‘移动’起来了。
在这里插入图片描述

cesium实现

要实现这个效果,我们先用WallGeometry创建一个‘围栏’的模型,代码如下,需要注意的是我们要把appearance的faceForward设置为true,不然看不到‘围栏’的背面

const wall = new Cesium.WallGeometry({
    positions : Cesium.Cartesian3.fromDegrees(points),
    });
const geometry = Cesium.WallGeometry.createGeometry(wall);
const instanceTop = new Cesium.GeometryInstance({
    geometry : geometry,
    attributes : {
        color : Cesium.ColorGeometryInstanceAttribute.fromColor(Color.AQUA)
    },
});
let wallMesh = viewer.scene.primitives.add(
    new Cesium.Primitive({
        geometryInstances: instanceTop,
        asynchronous: false,
        appearance :  new Cesium.PerInstanceColorAppearance({
            flat: true,
            faceForward: true,
            renderState: {
                depthTest: {
                    enabled: true
                }
            }
        })
    })
);

接下来我们准备两张贴图,然后再修改一下appearance
在这里插入图片描述

let wallMesh = viewer.scene.primitives.add(
    new Cesium.Primitive({
        geometryInstances: instanceTop,
        asynchronous: false,
        appearance :  new Cesium.MaterialAppearance({
            faceForward: true,
            material:  new Cesium.Material({
                fabric: {
                    type: "Image",
                    uniforms: {
                        image: "./img/glowWall.png",
                    },
                },
            }),
        })
    })
);

修改后可以得到以下的效果
在这里插入图片描述

目前贴图还是静止的,我们再来修改material来贴图动起来

 let wallMesh = viewer.scene.primitives.add(
    new Cesium.Primitive({
        geometryInstances: instanceTop,
        appearance : new Cesium.MaterialAppearance({
            faceForward: true,
            material:  new Cesium.Material({
                fabric: {
                    type: "zfImage",
                    uniforms: {
                        image: "./img/glowWall.png",
                    },
                    source: `czm_material czm_getMaterial(czm_materialInput materialInput)
                    {
                        czm_material material = czm_getDefaultMaterial(materialInput);
                        vec2 st = materialInput.st;
                        //这里通过不断对st.t加上偏移,让贴图动起来, * 3是可以让贴图重复贴三次。
                        vec4 colorImage = texture(image,vec2(st.s, fract(st.t * 3.0 - czm_frameNumber * 0.032)));
                        material.alpha = colorImage.a;
                        material.diffuse = colorImage.rgb;
                        return material;
                    }`,
                },
            }),
        }),
        asynchronous: false
    })
);

在这里插入图片描述

优化效果

我们可以看到目前有了一个基本的‘电子围栏’的效果,但是感觉还是差点,比如顶部围栏消失太过生硬。
在这里插入图片描述

解决这个问题我们可以在一张贴图去让其渐变
在这里插入图片描述

 let wallMesh = viewer.scene.primitives.add(
    new Cesium.Primitive({
        geometryInstances: instanceTop,
        appearance : new Cesium.MaterialAppearance({
            faceForward: true,
            material:  new Cesium.Material({
                fabric: {
                    type: "zfImage",
                    uniforms: {
                        image: "./img/glowWall.png",
                        image1:"./img/glowWall.jpg"
                    },
                    source: `czm_material czm_getMaterial(czm_materialInput materialInput)
                    {
                        czm_material material = czm_getDefaultMaterial(materialInput);
                        vec2 st = materialInput.st;
                        vec4 colorImage = texture(image,vec2(st.s, fract(st.t * 3.0 - czm_frameNumber * 0.032)));
                        vec4 color2 = texture(image1, st);
                        material.alpha = colorImage.a * color2.x;
                        material.diffuse = colorImage.rgb;
                        return material;
                    }`,
                },
            }),
        }),
        asynchronous: false
    })
);

最终效果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

智方科技

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值