Cesium基础代码段(三)天气shader

本文介绍了使用Cesium和Vue构建的一个包含雨、雪、雾、云天气效果的简易案例系统。通过自定义shader实现各种天气效果,包括雨的流动感、雪的飘落、雾的弥漫以及云的动态展示。代码示例展示了如何添加这些效果到场景中,为三维可视化应用增加了更多生动元素。
摘要由CSDN通过智能技术生成

        之前用cesium+vue搭建了一个简易的案例系统,算是基础功能的堆砌,也不知道有什么实际用处,算是学习的记录,后续会放在github上。

        有一个天气效果的展示,雨、雪、雾、云的基础展示,前三者比较常见,网上很多现成的shader,后者官方沙盒中有云的案例,可以自己改改。cesium效果一般,可以尝试去threejs或者ue试试玩。

        雨效果:

 

        shader:

//雨
    setRainEffect() {
        const tiltAngle = .2
        const rainSize = 0.3
        const rainSpeed = 60
        if (viewer) {
            let Rain = "uniform sampler2D colorTexture;\n\
            varying vec2 v_textureCoordinates;\n\
            uniform float tiltAngle;\n\
            uniform float rainSize;\n\
            uniform float rainSpeed;\n\
            float hash(float x) {\n\
                return fract(sin(x * 133.3) * 13.13);\n\
            }\n\
            void main(void) {\n\
                float time = czm_frameNumber / rainSpeed;\n\
                vec2 resolution = czm_viewport.zw;\n\
                vec2 uv = (gl_FragCoord.xy * 2. - resolution.xy) / min(resolution.x, resolution.y);\n\
                vec3 c = vec3(.6, .7, .8);\n\
                float a = tiltAngle;\n\
                float si = sin(a), co = cos(a);\n\
                uv *= mat2(co, -si, si, co);\n\
                uv *= length(uv + vec2(0, 4.9)) * rainSize + 1.;\n\
                float v = 1. - sin(hash(floor(uv.x * 100.)) * 2.);\n\
                float b = clamp(abs(sin(20. * time * v + uv.y * (5. / (2. + v)))) - .95, 0., 1.) * 20.;\n\
                c *= v * b;\n\
                gl_FragColor = mix(texture2D(colorTexture, v_textureCoordinates), vec4(c, 1), .5);\n\
            }\n\
            "
            let rainStage = new Cesium.PostProcessStage({
                name: 'yang_rain',
                fragmentShader: Rain,
                uniforms: {
                    tiltAngle: () => {
                        return tiltAngle;
                    },
                    rainSize: () => {
                        return rainSize;
                    },
                    rainSpeed: () => {
                        return rainSpeed;
                    }
                }
            });

            return window.viewer.scene.postProcessStages.add(
                rainStage
            );
        }
    }

        雪效果:

        shader:

 //雪
    setSnowEffect() {
        if (viewer) {
            let fs = "uniform sampler2D colorTexture;\n\
            varying  vec2 v_textureCoordinates;\n\
            \n\
            float snow(vec2 uv,float scale){\n\
                float time = czm_frameNumber / 60.0;\n\
                float w=smoothstep(1.,0.,-uv.y*(scale/10.));\n\
                if(w<.1)return 0.;\n\
                uv+=time/scale;\n\
                uv.y+=time*2./scale;\n\
                uv.x+=sin(uv.y+time*.5)/scale;\n\
                uv*=scale;\n\
                vec2 s=floor(uv),f=fract(uv),p;\n\
                float k=3.,d;\n\
                p=.5+.35*sin(11.*fract(sin((s+p+scale)*mat2(7,3,6,5))*5.))-f;\n\
                d=length(p);\n\
                k=min(d,k);\n\
                k=smoothstep(0.,k,sin(f.x+f.y)*0.01);\n\
                return k*w;\n\
            }\n\
            \n\
            void main(){\n\
                vec2 resolution = czm_viewport.zw;\n\
                vec2 uv=(gl_FragCoord.xy*2.-resolution.xy)/min(resolution.x,resolution.y);\n\
                vec3 finalColor=vec3(0);\n\
                float c = 0.0;\n\
                c+=snow(uv,30.)*.0;\n\
                c+=snow(uv,20.)*.0;\n\
                c+=snow(uv,15.)*.0;\n\
                c+=snow(uv,10.);\n\
                c+=snow(uv,8.);\n\
                c+=snow(uv,6.);\n\
                c+=snow(uv,5.);\n\
                finalColor=(vec3(c));\n\
                gl_FragColor = mix(texture2D(colorTexture, v_textureCoordinates), vec4(finalColor,1), 0.3);\n\
                \n\
            }\n\
            ";
            return window.viewer.scene.postProcessStages.add(new Cesium.PostProcessStage({
                name: 'snowEffect',
                fragmentShader: fs
            }));
        }
    }

         雾效果:

        shader:

// 雾天
    setFogEffect() {
        if (viewer) {
            let fragmentShaderSource =
                '\n\
                uniform sampler2D colorTexture;\n\
                     uniform sampler2D depthTexture;\n\
                     varying  vec2 v_textureCoordinates;\n\
                     void main(void)\n\
                     {\n\
                        vec4 origcolor=texture2D(colorTexture, v_textureCoordinates);\n\
                         vec4 fogcolor=vec4(0.8,0.8,0.8,0.5);\n\
                         float depth = czm_readDepth(depthTexture, v_textureCoordinates);\n\
                         vec4 depthcolor=texture2D(depthTexture, v_textureCoordinates);\n\
                         float f=(depthcolor.r-0.22)/0.2;\n\
                         if(f<0.0) f=0.0;\n\
                         else if(f>1.0) f=0.6;\n\
                         gl_FragColor = mix(origcolor,fogcolor,f);\n\
                     }'

            return window.viewer.scene.postProcessStages.add(new Cesium.PostProcessStage({
                name: 'FogEffect',
                fragmentShader: fragmentShaderSource
            }));
        }
    }

         云效果:

        代码:

//云
    setcloudEffect(numClouds, startLong, stopLong, startLat, stopLat, minHeight, maxHeight) {
        //加载云特效
        Cesium.Math.setRandomNumberSeed(2.5);
        const clouds = new Cesium.CloudCollection()
        // randomly generate clouds in a certain area
        const rangeLong = stopLong - startLong;
        const rangeLat = stopLat - startLat;
        for (let i = 0; i < numClouds; i++) {
            let long = startLong + getRandomNumberInRange(0, rangeLong);
            let lat = startLat + getRandomNumberInRange(0, rangeLat);
            let height = getRandomNumberInRange(minHeight, maxHeight);
            let scaleX = getRandomNumberInRange(150, 350);
            let scaleY = scaleX / 2.0 - getRandomNumberInRange(0, scaleX / 4.0);
            let slice = getRandomNumberInRange(0.1, 0.7);
            let depth = getRandomNumberInRange(5, 20);
            let aspectRatio = getRandomNumberInRange(1.5, 2.1);
            let cloudHeight = getRandomNumberInRange(5, 20);
            clouds.add({
                position: Cesium.Cartesian3.fromDegrees(long, lat, height),
                scale: new Cesium.Cartesian2(scaleX, scaleY),
                maximumSize: new Cesium.Cartesian3(
                    aspectRatio * cloudHeight,
                    cloudHeight,
                    depth
                ),
                slice: slice,
            });
        }
        viewer.scene.primitives.add(clouds);
        viewer.camera.flyTo({
            destination: Cesium.Cartesian3.fromDegrees(startLong, startLat, 800),//相机位置
            orientation: {
                heading: -5.3, //方位角
                pitch: 0, //倾角
                roll: 0 //旋转角            
            }
        });
        function getRandomNumberInRange(minValue, maxValue) {
            return (
                minValue + Cesium.Math.nextRandomNumber() * (maxValue - minValue)
            );
        }
    }

         参考博客:http://t.csdn.cn/ENVCN

  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Cesium Shader is a set of shader programs and techniques used to render 3D graphics in the Cesium JavaScript library. These shaders are designed to run on the GPU (graphics processing unit) and provide high-performance rendering of various types of visual effects such as lighting, shadows, reflections, and more. The Cesium Shader system is built on top of WebGL, a standard API for rendering 3D graphics in web browsers. Cesium Shader uses a combination of vertex shaders and fragment shaders to render 3D models with high fidelity and realism. The vertex shader is responsible for transforming the 3D model's vertices into screen space coordinates. It also calculates lighting and other effects based on the position and orientation of the camera and other factors. The fragment shader is responsible for rendering each pixel of the 3D model based on the lighting and other effects calculated by the vertex shader. This includes determining the color and intensity of each pixel, as well as handling transparency and other visual effects. Cesium Shader also includes advanced techniques such as deferred shading, which allows for complex lighting effects with multiple light sources and shadows. This technique involves rendering the scene in multiple passes, with each pass generating a separate buffer of information that is then combined to produce the final image. Overall, Cesium Shader provides a powerful and flexible system for rendering 3D graphics in web-based applications. Its use of WebGL and GPU acceleration allows for high-performance rendering of complex scenes and effects, making it a popular choice for a wide range of applications, from games and simulations to scientific data visualization and more.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值