cesium水波纹

涟漪原理参考

#define MAX_RADIUS 2  //最大半径
#define DOUBLE_HASH 0

// Hash functions shamefully stolen from:
// https://www.shadertoy.com/view/4djSRW
#define HASHSCALE1 .1  //一维随机数种子
#define HASHSCALE3 vec3(0.1,0.2,0.3) //三维随机数种子
//随机值生成算法  //https://blog.csdn.net/UWA4D/article/details/120550874
float hash12(vec2 p)
{
    //返回x的小数部分 即x-floor(x)
   vec3 p3  = fract(vec3(p.xyx) * HASHSCALE1);
    p3 += dot(p3, p3.yzx + 10.);
    return fract((p3.x + p3.y) * p3.z);
}

vec2 hash22(vec2 p)
{
   vec3 p3 = fract(vec3(p.xyx) * HASHSCALE3);
    p3 += dot(p3, p3.yzx+20.);
    return fract((p3.xy+p3.yz)*p3.zy);
}

czm_material czm_getMaterial(czm_materialInput m)
{

      float tiling = 10.;

     vec2 uv = m.st *tiling;


    vec2 p0 = floor(uv);
    float iTime = czm_frameNumber/100.;
    vec2 circles = vec2(0.); // 结果接收变量

    // i,j 从 -1 扰动到 正1
    for (int j = -MAX_RADIUS; j <= MAX_RADIUS; ++j)
    {
        for (int i = -MAX_RADIUS; i <= MAX_RADIUS; ++i)
        {
            vec2 pi = p0 + vec2(i, j);  //通过随机值产生涟漪,循环采样叠加
            vec2 p = pi + hash22(pi);  // 第一次随机运算 得到带位置信息的随机值
            float t = fract(0.05*iTime + hash12(pi));  //随机时间产生,0.05为速度,可在外部调整,时间随机化,用一维函数,frac 在0-1之间循环
            vec2 v = p - uv;  //得出实际的位置信息 p -原始的uv,实际上涟漪最终就是uv的移动,相减之后得到法线信息
            float d = length(v) - (float(MAX_RADIUS) + 1.)*t; //接下来计算圆,圆的计算公式是length(position)-R
            // 这边是max_radius+1,如果不加1,所有值都会比原来的小,这样会导致法线强度太弱,然后乘以我们得到的t就可以产生扩散的圆了
            // x²+y²-(R²+1)*t  乘以t,即为当前圆的半径大小
            float h = 1e-3;
            float d1 = d - h;
            float d2 = d + h;
            // 将得到的d进行sine函数运算一下就能得到涟漪,将d和一个值相乘能得到不同圈数的涟漪,然后用smoothstep控制涟漪的边缘虚实效果。
            // 我们这边要做两层,用两层的插值来模拟渐变,用h来控制涟漪的偏移值。
            float p1 = sin(31.*d1) * smoothstep(-0.6, -0.3, d1) * smoothstep(0., -0.3, d1);
            float p2 = sin(31.*d2) * smoothstep(-0.6, -0.3, d2) * smoothstep(0., -0.3, d2);
            //水波算法  0.5*  法线uv - p的法线
            // 能动起来后,我们需要一个到达最大值后渐隐的效果,通过两者的差值乘以时间的反向,
            //即1-0来模拟边缘的渐变效果,乘以两次时间是为了增强对比度。

            circles += 0.5 * normalize(v) * ((p2 - p1) / (2. * h) * (1. - t) * (1. - t));
        }
    }
     // MAX_RADIUS ==1 , 即,圆圈要除9 ,使得看起来不那么乱
    circles /= float((MAX_RADIUS*2+1)*(MAX_RADIUS*2+1));
    //强度即便取1 也可以, 随波动时间变大再变小,即浪先大,慢慢衰减
    float intensity = mix(0.01, 0.15, smoothstep(0.1, 0.6, abs(fract(0.05*iTime + 0.5)*2.-1.)));
    //关键在于circles的 xy的计算意义 ,第三维不影响效果
    vec3 n = vec3(circles,sqrt(1. - dot(circles, circles))); //normal
    //n.xy偏移量会推动uv移动,使得看起来有波浪的效果
    vec3 color = texture2D(iChannel0, m.st - intensity*n.xy).rgb ;
    float nosie = 5.*pow(clamp(dot(n, normalize(vec3(1., 0.7, 0.5))), 0., 1.), 6.);
    color = color + nosie;
    gl_FragColor = vec4(color, 1.0);
    czm_material dm = czm_getDefaultMaterial(m);
    dm.diffuse = gl_FragColor.xyz;
    return dm;

}

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值