基于Cesium实现逼真的水特效

wanghui2011 2021-09-07 原文


基于Cesium实现逼真的水特效


基于Cesium实现逼真的水特效

Cesium 自带有水特效材质,实例代码如下:

 1 var primitives = scene.primitives.add(
 2     new Cesium.Primitive({
 3       geometryInstances: new Cesium.GeometryInstance({
 4         geometry: new Cesium.RectangleGeometry({
 5           rectangle: Cesium.Rectangle.fromDegrees(
 6             -180.0,
 7             -90.0,
 8             180.0,
 9             90.0
10           ),
11           vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
12         }),
13       }),
14       appearance: new Cesium.EllipsoidSurfaceAppearance({
15         aboveGround: false,
16       }),
17       show: true
18     })
19   );

 

 1 primitive.appearance.material = new Cesium.Material({
 2     fabric: {
 3       type: "Water",
 4       uniforms: {
 5         specularMap: "../images/earthspec1k.jpg",
 6         normalMap: Cesium.buildModuleUrl(
 7           "Assets/Textures/waterNormals.jpg"
 8         ),
 9         frequency: 10000.0,
10         animationSpeed: 0.01,
11         amplitude: 1.0,
12       },
13     },
14   });
说明:
specularMap: 着色器源码:float specularMapValue = texture2D(specularMap, materialInput.st).r;用于判断当前区域是否为水域。
normalMap:水波动的法线纹理贴图
frequency:波的数量
animationSpeed:水震动的速度
amplitude:振幅大小

使用发现自带的水特效效果不是特别好,于是简单改改,将水透明化,代码如下:
 1 fragmentShaderSource: \'varying vec3 v_positionMC;\n\' +
 2                     \'varying vec3 v_positionEC;\n\' +
 3                     \'varying vec2 v_st;\n\' +
 4                     \'void main()\n\' +
 5                     \'{\n\' +
 6                     \'czm_materialInput materialInput;\n\' +
 7                     \'vec3 normalEC = normalize(czm_normal3D * czm_geodeticSurfaceNormal(v_positionMC, vec3(0.0), vec3(1.0)));\n\' +
 8                     \'#ifdef FACE_FORWARD\n\' +
 9                     \'normalEC = faceforward(normalEC, vec3(0.0, 0.0, 1.0), -normalEC);\n\' +
10                     \'#endif\n\' +
11                     \'materialInput.s = v_st.s;\n\' +
12                     \'materialInput.st = v_st;\n\' +
13                     \'materialInput.str = vec3(v_st, 0.0);\n\' +
14                     \'materialInput.normalEC = normalEC;\n\' +
15                     \'materialInput.tangentToEyeMatrix = czm_eastNorthUpToEyeCoordinates(v_positionMC, materialInput.normalEC);\n\' +
16                     \'vec3 positionToEyeEC = -v_positionEC;\n\' +
17                     \'materialInput.positionToEyeEC = positionToEyeEC;\n\' +
18                     \'czm_material material = czm_getMaterial(materialInput);\n\' +
19                     \'#ifdef FLAT\n\' +
20                     \'gl_FragColor = vec4(material.diffuse + material.emission, material.alpha);\n\' +
21                     \'#else\n\' +
22                     \'gl_FragColor = czm_phong(normalize(positionToEyeEC), material, czm_lightDirectionEC);\n\' +
23                     \'gl_FragColor.a=0.85;\n\' +
24                     \'#endif\n\' +
25                     \'}\n\'

 

 结合倾斜摄影数据,改改水的相关参数也还凑合,可以看。但是你想要的水面倒影,水折射肯定是没有的。

下面我们可以看看three.js的水,看着挺清澈透明的,现实生活中也就生活用水有这个效果。但几乎有水的折射和反射效果了。

 

 这里借鉴一下three.js的水特效代码:

  1 vertexShader: [
  2 
  3         \'#include <common>\',
  4         \'#include <fog_pars_vertex>\',
  5         \'#include <logdepthbuf_pars_vertex>\',
  6 
  7         \'uniform mat4 textureMatrix;\',
  8 
  9         \'varying vec4 vCoord;\',
 10         \'varying vec2 vUv;\',
 11         \'varying vec3 vToEye;\',
 12 
 13         \'void main() {\',
 14 
 15         \'    vUv = uv;\',
 16         \'    vCoord = textureMatrix * vec4( position, 1.0 );\',
 17 
 18         \'    vec4 worldPosition = modelMatrix * vec4( position, 1.0 );\',
 19         \'    vToEye = cameraPosition - worldPosition.xyz;\',
 20 
 21         \'    vec4 mvPosition =  viewMatrix * worldPosition;\', // used in fog_vertex
 22         \'    gl_Position = projectionMatrix * mvPosition;\',
 23 
 24         \'    #include <logdepthbuf_vertex>\',
 25         \'    #include <fog_vertex>\',
 26 
 27         \'}\'
 28 
 29     ].join( \'\n\' ),
 30 
 31     fragmentShader: [
 32 
 33         \'#include <common>\',
 34         \'#include <fog_pars_fragment>\',
 35         \'#include <logdepthbuf_pars_fragment>\',
 36 
 37         \'uniform sampler2D tReflectionMap;\',
 38         \'uniform sampler2D tRefractionMap;\',
 39         \'uniform sampler2D tNormalMap0;\',
 40         \'uniform sampler2D tNormalMap1;\',
 41 
 42         \'#ifdef USE_FLOWMAP\',
 43         \'    uniform sampler2D tFlowMap;\',
 44         \'#else\',
 45         \'    uniform vec2 flowDirection;\',
 46         \'#endif\',
 47 
 48         \'uniform vec3 color;\',
 49         \'uniform float reflectivity;\',
 50         \'uniform vec4 config;\',
 51 
 52         \'varying vec4 vCoord;\',
 53         \'varying vec2 vUv;\',
 54         \'varying vec3 vToEye;\',
 55 
 56         \'void main() {\',
 57 
 58         \'    #include <logdepthbuf_fragment>\',
 59 
 60         \'    float flowMapOffset0 = config.x;\',
 61         \'    float flowMapOffset1 = config.y;\',
 62         \'    float halfCycle = config.z;\',
 63         \'    float scale = config.w;\',
 64 
 65         \'    vec3 toEye = normalize( vToEye );\',
 66 
 67         // determine flow direction
 68         \'    vec2 flow;\',
 69         \'    #ifdef USE_FLOWMAP\',
 70         \'        flow = texture2D( tFlowMap, vUv ).rg * 2.0 - 1.0;\',
 71         \'    #else\',
 72         \'        flow = flowDirection;\',
 73         \'    #endif\',
 74         \'    flow.x *= - 1.0;\',
 75 
 76         // sample normal maps (distort uvs with flowdata)
 77         \'    vec4 normalColor0 = texture2D( tNormalMap0, ( vUv * scale ) + flow * flowMapOffset0 );\',
 78         \'    vec4 normalColor1 = texture2D( tNormalMap1, ( vUv * scale ) + flow * flowMapOffset1 );\',
 79 
 80         // linear interpolate to get the final normal color
 81         \'    float flowLerp = abs( halfCycle - flowMapOffset0 ) / halfCycle;\',
 82         \'    vec4 normalColor = mix( normalColor0, normalColor1, flowLerp );\',
 83 
 84         // calculate normal vector
 85         \'    vec3 normal = normalize( vec3( normalColor.r * 2.0 - 1.0, normalColor.b,  normalColor.g * 2.0 - 1.0 ) );\',
 86 
 87         // calculate the fresnel term to blend reflection and refraction maps
 88         \'    float theta = max( dot( toEye, normal ), 0.0 );\',
 89         \'    float reflectance = reflectivity + ( 1.0 - reflectivity ) * pow( ( 1.0 - theta ), 5.0 );\',
 90 
 91         // calculate final uv coords
 92         \'    vec3 coord = vCoord.xyz / vCoord.w;\',
 93         \'    vec2 uv = coord.xy + coord.z * normal.xz * 0.05;\',
 94 
 95         \'    vec4 reflectColor = texture2D( tReflectionMap, vec2( 1.0 - uv.x, uv.y ) );\',
 96         \'    vec4 refractColor = texture2D( tRefractionMap, uv );\',
 97 
 98         // multiply water color with the mix of both textures
 99         \'    gl_FragColor = vec4( color, 1.0 ) * mix( refractColor, reflectColor, reflectance );\',
100 
101         \'    #include <tonemapping_fragment>\',
102         \'    #include <encodings_fragment>\',
103         \'    #include <fog_fragment>\',
104 
105         \'}\'
106 
107     ].join( \'\n\' )

融入到Cesium当中效果勉强可以看了,效果图如下:

 

图1

 

 图2


图一和图二是同一份数据,,图一的水折射用的是影像图,图二的水折射是在水面几何数据下贴了石块纹理图,其实实际上的水是透明无色的。
发表于
2020-06-12 17:43 
彡丨灬麷 
阅读(5750
评论(15
编辑 
收藏 
举报

 

版权声明:本文为wanghui2011原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/wanghui2011/articles/13100925.html

基于Cesium实现逼真的水特效的更多相关文章

随机推荐

  1. Ubantu安装Odoo10学习日志

    Windows安装是十分简单的,无论是何种方式,在了解大体情况下,我开始尝试下将Odoo搭建部署在Ubantu […]...

  2. web服务器专题:tomcat(三)tomcat-user.xml 配置文件

    回顾:web服务器专题:tomcat(二)模块组件与server.xml 配置文件 Tomcat管理模块 安装 […]...

  3. Windows 防火墙出站 入站规则简单说明

    1. Windows防火墙其实比linux的iptabels 要好用一些. 打开设置方式: 运行->输入 […]...

  4. 在没实践机会的前提下,如何跨越级别

        我在之前的面试过程中,一直会遇到这样的问题:比如我要面试架构师,但我当时工作时,只有机会实践高级开发的 […]...

  5. 如何给U盘和移动硬盘加密?

    给U盘加密和给移动硬盘加密其实很简单,我可以给您介绍一款很不错的u盘和移动硬盘加密软件,那就是u盘超级加密30 […]...

  6. 微软BI SSRS 2012 Metro UI Win 8 风格的报表课程案例全展示 – BIWORK

    微软BI SSRS 2012 Metro UI Win 8 风格的报表课程案例全展示 2014-12-15 2 […]...

  7. 关于排序函数的问题

    众所周知,自定义函数之间的参数引用传值传地址,即直接在函数中改变变量的值是没有任何意义的,当你跳出该自定义函数 […]...

  8. 这次一定让你记住 TCP 三次握手、四手挥手!

    TCP协议全称为:Transmission Control Protocol,是一种面向链接、保证数据传输安全 […]...

展开目录

目录导航