游戏开发论坛

 找回密码
 立即注册
搜索
查看: 2093|回复: 0

涟漪和下雨 shader的实现

[复制链接]

1

主题

1

帖子

11

积分

新手上路

Rank: 1

积分
11
发表于 2018-5-1 23:45:32 | 显示全部楼层 |阅读模式
下雨shader的实现:





1.实现
#### 1.空间划分+相邻grid之间采样实现
其中
```c
y = sin(31.*t) * smoothstep(-0.6, -0.3, t) * smoothstep(0., -0.3,t)
```
图形解析为:  



```c
// create by JiepengTan
// https://github.com/JiepengTan/FishManShaderTutorial
// 2018-04-25
// email: jiepengtan@gmail.com
// all right reserve
float _Ripple(float period,float spreadSpd,float waveGap,float2 uv,float rnd){
     // sample the texture
    const float WAVE_NUM = 2.;
    const float  CROSS_NUM = 1.0;
    float ww = -WAVE_NUM * .5 * waveGap;
    float hww = ww * 0.5;
    float freq = WAVE_NUM * PI2 / waveGap/(CROSS_NUM + 1.);
    float radius = (float(CROSS_NUM));
    float2 p0 = floor(uv);
    float sum = 0.;

    //多个格子中的波动全部累计起来
    for (float j = -CROSS_NUM; j <= CROSS_NUM; ++j){
        for (float i = -CROSS_NUM; i <= CROSS_NUM; ++i){
            float2 pi = p0 + float2(i, j);
            float2 h22 = Hash23(float3(pi,rnd));
            float h12 = Hash13(float3(pi,rnd));
            float pd = period*( h12 * 1.+ 1.);//让周期随机
            float time = ftime+pd*h12;//让时间偏移点  不会全部同时出现
            float t = fmod(time,pd);
            float spd = spreadSpd*((1.0-h12) * 0.2 + 0.8);//让传播速度随机
            float size = (h12)*0.4+0.6;
            float maxt = min(pd*0.6,radius *size /spd);
            float amp = clamp01(1.- t/maxt);
            float2 p = pi +  Hash21(h12 + floor(time/pd)) * 0.4;
            float d = (length(p - uv) - spd*t)/radius * 0.5;
            sum -= amp*sin(freq*d) *  smoothstep(ww*size, hww*size, d) *  smoothstep(0., hww*size, d);//让波动传播开来
        }
    }
    sum /= (CROSS_NUM*2+1)*(CROSS_NUM*2+1);
    return sum;
}

float Ripples(float2 uv ,float layerNum,float tileNum,float period,float spreadSpd,float waveGap){
    float sum = 0.;
    //分多层
    for(int i =0;i<layerNum;i++){
        sum += _Ripple(period,spreadSpd,waveGap,uv*(1.+i/layerNum ) * tileNum,float(i));
    }
    return sum ;
}
```

2.图像处理+波动传播   
思想:波动传播     
优点:无论多么复杂的运动,时间复杂度都是O(1)  
缺点:需要两个缓存buffer来实现,同时效果和精度,受buffer的大小限制   

```c
// p11 是紫色坐标前两帧的值
// p10,p01,p21,p12对于的是自身坐标上下左右相邻像素的前一帧值
// The actual propagation:
   d += -p11 + (p10 + p01 + p21 + p12)*.5;
   d *= .999; // 衰减
```

全部源码下载地址


下雨的实现
https://blog.csdn.net/tjw02241035621611/article/details/80038608


您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2024-3-29 12:48

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表