基于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. 微信小程序:POST请求data数据请求不到 – 就看运气了

      最近开始开发小程序,遇到许多小问题,直奔主题。      wx.request()是微信封装的ajax请求 […]...

  2. VMware网络设置的三种方式

    VMWare提供了三种工作模式:host-only(主机模式)、NAT(网络地址转换模式)、bridged(桥 […]...

  3. 算法简介、7种算法分类

    算法简介、7种算法分类 一、算法 算法是以函数模板的形式实现的。常用的算法涉及到比较、交换、查找、搜索、复制、 […]...

  4. Vue.js 很好,但是比 Angular或React 更好吗?

    来源:众成翻译 链接:http://www.zcfy.cc/article/vue-js-is-good-bu […]...

  5. VMWare15 安装 Mac OS 系统

    文章目录VMWare15 安装 Mac OS 系统安装环境工具准备准备工作MAC虚拟机设置启动MAC前准备工作 […]...

  6. caffe实战笔记

    Caffe简要介绍: Caffe还没有windows版本,所以我需要远程登录linux服务器 Caffe主要处 […]...

  7. Linux服务器端程序设计V1

    Linux服务器端程序V1.0 功能要求 能接收来自远程客户端(有可能是多个客户端同时)发送的图片以及视频数据 […]...

  8. 数据库存储过程详解

    /* 存储过程可以看作是在数据库中的存储t-sql脚本 为什么使用存储过程 1、增加性能 本地存储发送的内容少 […]...

展开目录

目录导航