PISCOnoob

导航

FlowMap简单应用

1.让纹理动起来

我们应用一张水的纹理在面片上,假设这是水流,但水流应该是会动的,我们可以手动修改matetial的offset来让纹理“流动”。

 

 

 

 

 

 要想在playmode中让纹理自动“流动”,我们可以加入时间变量来扰动UV:

1  float4 frag (v2f i) : SV_Target
2  {
3       //获取unity内置时间变量
4        float offset=_Time.x;
5        //控制x y两个方向的移动
6        float4 finalCol=tex2D(_MainTex,i.uv+float2(offset,offset)*_FlowSpeed);
7 
8        return finalCol;
9  }

这样“河流”就自己“流动”起来了。

但是这样横平竖直地流动有点单调了,这时候我们引用flowmap来丰富效果。

flowmap如下所示:

 

乍眼一看我们无法理解flowmap到底是什么,有什么作用。实际上flowmap是用纹理的RG两个通道的记录该处向量场的方向,让纹理上某一点出现定向流动的效果。简单理解,flowmap给上面水纹理指出:你接下来要“流动”的方向。我们将flowmap采样的结果放到原uv上进行扰动便有了向不同方向流动的结果。

我们还缺少点东西。如果我们在DCC工具上做了一张flowmap是0~255,到了shader里面计算会normalized成0~1,实际上我们向量表示范围应该是-1到1之间,因此我们需要把flowmap采样结果从0~1映射到-1~1:

 1 float4 frag (v2f i) : SV_Target
 2   {
 3 
 4             //获取unity内置时间变量
 5             float offset = _Time.x;
 6             float2 flowmap = tex2D(_FlowpMap,i.uv).xy;
 7             flowmap=flowmap * 2 - 1 ;
 8             //控制x y两个方向的移动
 9             float4 finalCol = tex2D(_MainTex,i.uv + flowmap * _FlowSpeed * float2(0,offset);
10 
11             return finalCol;
12  }

如此一来就有了还不错的效果。

2.advanced in flowmap

 

 

我们会发现flowmap一开始的几秒效果不错,然而随着时间推移效果逐渐变得离谱,我们希望只要开头几秒的效果。

我们使用了时间变量来让其流动,时间是不断增长的,可以简单看是是f(x)=x这样一个函数:

ps:我们通过desmos这个网站帮我们可视化一下,但是desmos中数学公式与unity shaderlab中写法有所不同,不过表达的意思是一样的。

 

当我们在shader中使用frac函数后会返回数值的小数部分,这样就能不断重复0~0.99:

这样我们就能只放出flowmap开头的效果。

但是这样每次0.99突然跳回0太突兀了,这个过渡能否柔和一点不被玩家察觉呢?我们可以构造一个锯齿波,让其值在区间内来回波动:

 

 

 

 其实跟sin cos很像。

实际上当我们看久了依然会感觉比较单调,毕竟是遵循周期规律变化,因此我们可以构造两个一样的函数周期频率一样,但是周期会错开

这种技术源自valve在GDC 2010上的分享,当时被应用在了求生之路2和传送门2中。

思路是这样的:我们构造两个这样的周期函数A和B,A与B的周期频率一样,但是他们一开始的位置,或者说值是不同的,比如大家从0秒开始,一个值为1,一个为0,通过lerp函数进行线性插值来进行平滑过渡。

 

 

 

 

 

 为了更好理解,我们称之为“层”,即本质上我们希望有两层一样的效果,错开周期,并把效果lerp到一起。

 

posted on 2022-04-13 18:00  PISCOnoob  阅读(230)  评论(0编辑  收藏  举报