zoukankan      html  css  js  c++  java
  • 基于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; ' +
    'varying vec3 v_positionEC; ' +
    'varying vec2 v_st; ' +
    'void main() ' +
    '{ ' +
      'czm_materialInput materialInput; ' +
      'vec3 normalEC = normalize(czm_normal3D * czm_geodeticSurfaceNormal(v_positionMC, vec3(0.0), vec3(1.0))); ' +
      '#ifdef FACE_FORWARD ' +
      'normalEC = faceforward(normalEC, vec3(0.0, 0.0, 1.0), -normalEC); ' +
      '#endif ' +
      'materialInput.s = v_st.s; ' +
      'materialInput.st = v_st; ' +
      'materialInput.str = vec3(v_st, 0.0); ' +
      'materialInput.normalEC = normalEC; ' +
      'materialInput.tangentToEyeMatrix = czm_eastNorthUpToEyeCoordinates(v_positionMC, materialInput.normalEC); ' +
      'vec3 positionToEyeEC = -v_positionEC; ' +
      'materialInput.positionToEyeEC = positionToEyeEC; ' +
      'czm_material material = czm_getMaterial(materialInput); ' +
       '#ifdef FLAT ' +
       'gl_FragColor = vec4(material.diffuse + material.emission, material.alpha); ' +
       '#else ' +
         'gl_FragColor = czm_phong(normalize(positionToEyeEC), material, czm_lightDirectionEC); ' +
       'gl_FragColor.a=0.85; ' +
       '#endif ' +
    '} '

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

    下面我们可以看看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( ' ' ),

    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( ' ' )

    融入到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('
    ');
    饮水思源,不忘初心。 要面包,也要有诗和远方。
  • 相关阅读:
    [LeetCode] 159. Longest Substring with At Most Two Distinct Characters 最多有两个不同字符的最长子串
    [LeetCode] 76. Minimum Window Substring 最小窗口子串
    window.scrollTo和window.scrollBy
    background-clip与background-origin
    page-break-before和page-break-after
    CSS counter计数器(content目录序号自动递增)详解
    移动端网页巧用 margin和padding 的百分比实现自适应
    监听屏幕旋转事件window. onorientationchange
    apple-touch-startup-image 制作iphone web应用程序的启动画面
    当把链接保存到手机桌面。设置图标 只在safari浏览器中有用
  • 原文地址:https://www.cnblogs.com/mazhenyu/p/14622604.html
Copyright © 2011-2022 走看看