shader之cesium应用

shader之cesium应用

 shader用作编写cesium自定义材质的着色器。

效果:

代码:

<template>
    <div class="earthSence">
        <!-- 地图 -->
        <div id="earthContainer"></div>
    </div>
</template>

<script>
import { mapUrl } from '@/config'
export default {
    name: 'flyline',
    data() {
        return {
            _earth: {},
            _viewer: {}
        }
    },
    mounted() {
        XE.ready().then(() => {
            this.initMap()
        })
    },
    methods: {
        // 初始化earthSDK地图
        initMap() {
            //创建viewer实例
            Cesium.Ion.defaultAccessToken =
                'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI2N2UwZWU2Zi1jN2UzLTQ3YTAtOTZmNC05MzNkM2IxZDViMzgiLCJpZCI6MjY1MzgsInNjb3BlcyI6WyJhc3IiLCJnYyJdLCJpYXQiOjE1ODc5MDQ0NTF9.lLpxvsIwB9Se5GeINW-jp5nm406S7KVWMdvH8swDHQ4'
            this.viewer = new Cesium.Viewer('earthContainer', {
                geocoder: false, // 隐藏搜索
                homeButton: false, // 隐藏主页
                sceneModePicker: false, // 隐藏二三维转换
                baseLayerPicker: false, // 隐藏图层选择控件
                navigationHelpButton: false, // 隐藏帮助按钮
                animation: false, // 隐藏时钟
                timeline: false, // 隐藏时间轴
                fullscreenButton: false, // 隐藏全屏
                vrButton: false, // 隐藏双屏模式
                infoBox: false, // 隐藏点击 entity 信息框
                selectionIndicator: false, // 隐藏点击 entity 绿框
                shouldAnimate: true,
                // 设置底图
                imageryProvider: new Cesium.UrlTemplateImageryProvider({
                    url:mapUrl,
                    style: 'default',
                    format: 'image/png'
                })
            })

            // 定位到全国
            // 中国坐标
            let chinaPosition = Cesium.Cartesian3.fromDegrees(
                113.41726298378288,
                10.290411251106182,
                700000.0
            )
            this.viewer.camera.flyTo({
                destination: chinaPosition,
                orientation : {
                    heading : Cesium.Math.toRadians(0.0),
                    pitch : Cesium.Math.toRadians(-25.0),
                    roll : 0.0
                },
                duration: 1, // 飞行时间
                offset: new Cesium.HeadingPitchRange(0.0, Cesium.Math.toRadians(-20.0)) // 偏移量
            })
            this.addCube()
        },
        // 创建柱状体并赋予shader着色器材质
        addCube() {
            var viewer = this.viewer
            // 创建长方体对象
            const extrudedPolygon = new Cesium.PolygonGeometry({
                polygonHierarchy: new Cesium.PolygonHierarchy(
                    Cesium.Cartesian3.fromDegreesArray([
                        112.41726298378288,
                        23.290411251106182,
                        113.67072522399741,
                        23.560312361463682,
                        114.09370956893551,
                        22.590768298743153,
                        112.83803246418894,
                        22.285610818885644,
                    ])
                ),
                extrudedHeight: 100000,
            })
            const instance = new Cesium.GeometryInstance({
                geometry: extrudedPolygon,
                id: 'box with height',
            })
            const extrudedPolygon2 = new Cesium.PolygonGeometry({
                polygonHierarchy: new Cesium.PolygonHierarchy(
                    Cesium.Cartesian3.fromDegreesArray([
                        114,
                        22,
                        115,
                        22,
                        115,
                        23,
                        114,
                        23,
                    ])
                ),
                extrudedHeight: 100000,
            })
            const instance2 = new Cesium.GeometryInstance({
                geometry: extrudedPolygon2,
                id: 'box with height',
            })
            // 创建材质,在MaterialAppearance中若不添加基础材质,模型将会透明
            var material = new Cesium.Material.fromType("Color");
                material.uniforms.color =  Cesium.Color.WHITE;
            // 自定义材质
            const aper = new Cesium.MaterialAppearance({
                material: material,
                translucent: true,
                closed: true,
                vertexShaderSource: `
                        attribute vec3 position3DHigh;
                        attribute vec3 position3DLow;
                        attribute vec3 normal;
                        attribute vec2 st;
                        attribute float batchId;
                        varying vec3 vNormal;
                        void main() {
                            //将attributes的normal通过varying赋值给了向量vNormal
                            vNormal = normal;
                            //projectionMatrix是投影变换矩阵 modelViewMatrix是相机坐标系的变换矩阵
                            vec4 p = czm_computePosition();
                            gl_Position = czm_modelViewProjectionRelativeToEye * p;
                        }
                    `,
                fragmentShaderSource: `         
                        //片元着色器同样需要定义varying vec3 vNormal;
                        varying vec3 vNormal;
                        void main() {
                        //vNormal是一个已经归一化的三维向量
                            float pr = (vNormal.x + 1.0) / 2.0; //pr红色通道值范围为0~1
                            float pg = (vNormal.y + 1.0) / 2.0; //pg绿色通道值范围为0~1
                            float pb = (vNormal.z + 1.0) / 2.0; //pb蓝色通道值范围为0~1
                            gl_FragColor=vec4(pr, pg, pb, 1.0); //最后设置顶点颜色,点与点之间会自动插值
                        }
                `,
            })
            // 加载模型
            var p = viewer.scene.primitives.add(
                new Cesium.Primitive({
                    geometryInstances: [instance, instance2],
                    appearance: aper,
                    releaseGeometryInstances: false,
                    compressVertices: false,
                })
            )
        },
    }
}
</script>

<style scoped lang="scss">
.earthSence {
    width: 100%;
    height: 100%;
    background: grey;
    overflow: hidden;
    position: relative;
    #earthContainer {
        width: 100%;
        height: 100%;
        overflow: hidden;
        position: absolute;
    }
}
</style>

 

 

合作:@浩

钻研不易,转载请注明出处。。。。。。

 

posted @ 2021-01-23 11:14  莫小龙  阅读(4078)  评论(0编辑  收藏  举报