基于Cesium实现逼真的⽔特效基于Cesium实现逼真的⽔特效
Cesium ⾃带有⽔特效材质,实例代码如下:
1var primitives = scene.primitives.add(
2new 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 vec
3 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                    'alEC = normalEC;\n' +
15                    'materialInput.tangentToEyeMatrix = czm_eastNorthUpToEyeCoordinates(v_positionMC, alEC);\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 + ission, 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 - ;',
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.w;',
93        '    vec2 uv = + coord.z * * 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
实现特效的代码js
101        '    #include <tonemapping_fragment>',
102        '    #include <encodings_fragment>',
103        '    #include <fog_fragment>',
104
105        '}'
106
107    ].join( '\n' )
融⼊到Cesium当中效果勉强可以看了,效果图如下:
图1
图2
图⼀和图⼆是同⼀份数据,,图⼀的⽔折射⽤的是影像图,图⼆的⽔折射是在⽔⾯⼏何数据下贴了⽯块纹理图,其实实际上的⽔是透明⽆⾊的。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。