基于Cesium实现逼真的水特效[转]


基于Cesium实现逼真的水特效

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

var primitives = scene.primitives.add(

new Cesium.Primitive({
geometryInstances: new Cesium.GeometryInstance({
geometry: new Cesium.RectangleGeometry({
rectangle: Cesium.Rectangle.fromDegrees(
-180.0,
-90.0,
180.0,
90.0
),
vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
}),
}),
appearance: new Cesium.EllipsoidSurfaceAppearance({
aboveGround: false,
}),
show: true
})
);

primitive.appearance.material = new Cesium.Material({

fabric: {
type: "Water",
uniforms: {
specularMap: "../images/earthspec1k.jpg",
normalMap: Cesium.buildModuleUrl(
"Assets/Textures/waterNormals.jpg"
),
frequency: 10000.0,
animationSpeed: 0.01,
amplitude: 1.0,
},
},
});

说明:
specularMap: 着色器源码:float specularMapValue = texture2D(specularMap, materialInput.st).r;用于判断当前区域是否为水域。
normalMap:水波动的法线纹理贴图
frequency:波的数量
animationSpeed:水震动的速度
amplitude:振幅大小

使用发现自带的水特效效果不是特别好,于是简单改改,将水透明化,代码如下:

fragmentShaderSource: 'varying vec3 v_positionMC;\n' +
'varying vec3 v_positionEC;\n' +
'varying vec2 v_st;\n' +
'void main()\n' +
'{\n' +
  'czm_materialInput materialInput;\n' +
  'vec3 normalEC = normalize(czm_normal3D * czm_geodeticSurfaceNormal(v_positionMC, vec3(0.0), vec3(1.0)));\n' +
  '#ifdef FACE_FORWARD\n' +
  'normalEC = faceforward(normalEC, vec3(0.0, 0.0, 1.0), -normalEC);\n' +
  '#endif\n' +
  'materialInput.s = v_st.s;\n' +
  'materialInput.st = v_st;\n' +
  'materialInput.str = vec3(v_st, 0.0);\n' +
  'materialInput.normalEC = normalEC;\n' +
  'materialInput.tangentToEyeMatrix = czm_eastNorthUpToEyeCoordinates(v_positionMC, materialInput.normalEC);\n' +
  'vec3 positionToEyeEC = -v_positionEC;\n' +
  'materialInput.positionToEyeEC = positionToEyeEC;\n' +
  'czm_material material = czm_getMaterial(materialInput);\n' +
   '#ifdef FLAT\n' +
   'gl_FragColor = vec4(material.diffuse + material.emission, material.alpha);\n' +
   '#else\n' +
     'gl_FragColor = czm_phong(normalize(positionToEyeEC), material, czm_lightDirectionEC);\n' +
   'gl_FragColor.a=0.85;\n' +
   '#endif\n' +
'}\n'

 

 

 

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

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

 

 

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

vertexShader: [

'#include <common>',
'#include <fog_pars_vertex>',
'#include <logdepthbuf_pars_vertex>',

'uniform mat4 textureMatrix;',

'varying vec4 vCoord;',
'varying vec2 vUv;',
'varying vec3 vToEye;',

'void main() {',

' vUv = uv;',
' vCoord = textureMatrix * vec4( position, 1.0 );',

' vec4 worldPosition = modelMatrix * vec4( position, 1.0 );',
' vToEye = cameraPosition - worldPosition.xyz;',

' vec4 mvPosition = viewMatrix * worldPosition;', // used in fog_vertex
' gl_Position = projectionMatrix * mvPosition;',

' #include <logdepthbuf_vertex>',
' #include <fog_vertex>',

'}'

].join( '\n' ),

fragmentShader: [

'#include <common>',
'#include <fog_pars_fragment>',
'#include <logdepthbuf_pars_fragment>',

'uniform sampler2D tReflectionMap;',
'uniform sampler2D tRefractionMap;',
'uniform sampler2D tNormalMap0;',
'uniform sampler2D tNormalMap1;',

'#ifdef USE_FLOWMAP',
' uniform sampler2D tFlowMap;',
'#else',
' uniform vec2 flowDirection;',
'#endif',

'uniform vec3 color;',
'uniform float reflectivity;',
'uniform vec4 config;',

'varying vec4 vCoord;',
'varying vec2 vUv;',
'varying vec3 vToEye;',

'void main() {',

' #include <logdepthbuf_fragment>',

' float flowMapOffset0 = config.x;',
' float flowMapOffset1 = config.y;',
' float halfCycle = config.z;',
' float scale = config.w;',

' vec3 toEye = normalize( vToEye );',

// determine flow direction
' vec2 flow;',
' #ifdef USE_FLOWMAP',
' flow = texture2D( tFlowMap, vUv ).rg * 2.0 - 1.0;',
' #else',
' flow = flowDirection;',
' #endif',
' flow.x *= - 1.0;',

// sample normal maps (distort uvs with flowdata)
' vec4 normalColor0 = texture2D( tNormalMap0, ( vUv * scale ) + flow * flowMapOffset0 );',
' vec4 normalColor1 = texture2D( tNormalMap1, ( vUv * scale ) + flow * flowMapOffset1 );',

// linear interpolate to get the final normal color
' float flowLerp = abs( halfCycle - flowMapOffset0 ) / halfCycle;',
' vec4 normalColor = mix( normalColor0, normalColor1, flowLerp );',

// calculate normal vector
' vec3 normal = normalize( vec3( normalColor.r * 2.0 - 1.0, normalColor.b, normalColor.g * 2.0 - 1.0 ) );',

// calculate the fresnel term to blend reflection and refraction maps
' float theta = max( dot( toEye, normal ), 0.0 );',
' float reflectance = reflectivity + ( 1.0 - reflectivity ) * pow( ( 1.0 - theta ), 5.0 );',

// calculate final uv coords
' vec3 coord = vCoord.xyz / vCoord.w;',
' vec2 uv = coord.xy + coord.z * normal.xz * 0.05;',

' vec4 reflectColor = texture2D( tReflectionMap, vec2( 1.0 - uv.x, uv.y ) );',
' vec4 refractColor = texture2D( tRefractionMap, uv );',

// multiply water color with the mix of both textures
' gl_FragColor = vec4( color, 1.0 ) * mix( refractColor, reflectColor, reflectance );',

' #include <tonemapping_fragment>',
' #include <encodings_fragment>',
' #include <fog_fragment>',

'}'

].join( '\n' )

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


 

 图1

  图2

 
图一和图二是同一份数据,,图一的水折射用的是影像图,图二的水折射是在水面几何数据下贴了石块纹理图,其实实际上的水是透明无色


转自:https://www.cnblogs.com/wanghui2011/articles/13100925.html

 

评论

#11楼  [ 楼主]

@shenwuyuexy

vs =
'attribute vec3 position;' +
'attribute vec2 st;' +
'uniform mat4 u_modelViewMatrix;' +
'uniform mat4 u_invWorldViewMatrix;' +
//'uniform vec2 u_texCoordOffset;' +
//'uniform vec2 u_texCoordScale;' +
//'uniform float u_frameTime;' +
'uniform int u_clampToGroud;' +
'uniform vec3 u_camPos;' +
'uniform vec3 u_scale;' +

    //'varying vec3 eyeDir;' + 'varying vec3 vToEye;' + //'varying vec2 texCoord;' + 'varying vec2 vUv;' + //'varying float myTime;' + //'varying vec4 projectionCoord;' + 'varying vec4 vCoord;' + 'void main(void)' + '{' + //gl_Position = ftransform(); 'vec4 positionW = u_modelViewMatrix * vec4(position.xyz, 1.0);' + 'vec4 eyep = czm_modelView * positionW;' + 'gl_Position = czm_projection * eyep; ' + 'if (u_clampToGroud == 1)' + '{' + //'eyeDir = (u_camPos - position.xyz) * u_scale;' +vToEye 'vToEye = (u_camPos - position.xyz) * u_scale;' + '} else {' + 'vec4 pos = u_modelViewMatrix * vec4(position.xyz,1.0);' + //'eyeDir = vec3(u_invWorldViewMatrix*vec4(pos.xyz,0.0));' + 'vToEye = vec3(u_invWorldViewMatrix*vec4(pos.xyz,0.0));' + //'projectionCoord = gl_Position;' + 'vCoord = gl_Position;' + '}' + //'texCoord = (st+u_texCoordOffset)*u_texCoordScale;' + //'vUv = (st+u_texCoordOffset)*u_texCoordScale;' + 'vUv = st;' + //'myTime = 0.01 * u_frameTime;' + '}'; var fs = [ 'uniform sampler2D tReflectionMap;', 'uniform sampler2D tRefractionMap;', 'uniform sampler2D tNormalMap0;', 'uniform sampler2D tNormalMap1;', 'uniform sampler2D tFlowMap;', 'uniform vec3 color;', 'uniform float reflectivity;', 'uniform vec4 config;', 'varying vec4 vCoord;', 'varying vec2 vUv;', 'varying vec3 vToEye;', 'void main() {', ' float flowMapOffset0 = config.x;', ' float flowMapOffset1 = config.y;', ' float halfCycle = config.z;', ' float scale = config.w;', ' vec3 toEye = normalize( vToEye );', // determine flow direction ' vec2 flow;', //' #ifdef USE_FLOWMAP', //' flow = texture2D( tFlowMap, vUv ).rg * 2.0 - 1.0;', ' flow = texture2D( tFlowMap, vUv ).rg;', //' #else', //' flow = flowDirection;', //' #endif', //' flow.x *= - 1.0;', // sample normal maps (distort uvs with flowdata) ' vec4 normalColor0 = texture2D( tNormalMap0, ( vUv * scale ) + flow * flowMapOffset0 );', ' vec4 normalColor1 = texture2D( tNormalMap1, ( vUv * scale ) + flow * flowMapOffset1 );', ' float flowLerp = abs( halfCycle - flowMapOffset0 ) / halfCycle;', ' vec4 normalColor = mix( normalColor0, normalColor1, flowLerp );', ' vec3 normal = normalize( vec3( normalColor.r * 2.0 - 1.0, normalColor.b, normalColor.g * 2.0 - 1.0 ) );', // calculate the fresnel term to blend reflection and refraction maps ' float theta = max( dot( toEye, normal ), 0.0 );', ' float reflectance = reflectivity + ( 1.0 - reflectivity ) * pow( ( 1.0 - theta ), 5.0 );', // calculate final uv coords ' vec3 coord = vCoord.xyz / vCoord.w;', ' vec2 coord1 = gl_FragCoord.xy / czm_viewport.zw;', ' vec2 uv = coord1.xy + coord.z * normal.xz * 0.05;', ' vec4 reflectColor = texture2D( tReflectionMap, vec2( 1.0 - uv.x, uv.y ) );', ' vec4 refractColor = texture2D( tRefractionMap, uv );', ' gl_FragColor = vec4( color, 1.0 ) * mix( refractColor, reflectColor, reflectance );', 'gl_FragColor = refractColor;', '}' ].join('\n');


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM