基于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
实现特效的代码js101 ' #include <tonemapping_fragment>',
102 ' #include <encodings_fragment>',
103 ' #include <fog_fragment>',
104
105 '}'
106
107 ].join( '\n' )
融⼊到Cesium当中效果勉强可以看了,效果图如下:
图1
图2
图⼀和图⼆是同⼀份数据,,图⼀的⽔折射⽤的是影像图,图⼆的⽔折射是在⽔⾯⼏何数据下贴了⽯块纹理图,其实实际上的⽔是透明⽆⾊的。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论