【笔记】【百人计划】图形2.8 flowmap的实现

一、Flowmap是什么

  • Flowmap的实质
    • 一张记录了2D向量信息的纹理
    • Flowmap上的颜色(RG)记录该处向量场的方向,让模型上某一点表现出定量流动的特征
    • 通过在shader中偏移uv再对纹理进行采样,来模拟流动效果。

image-20220806235307299

==ue4与unity相比反转了绿通道==

二、Flowmap shader

  1. 采样Flowmap获取向量场信息
    • Flowmap不能直接使用,需要从0,1映射到-1,1
  2. 用向量场信息,使采样贴图时的uv随时间变化
  3. 对同一贴图以半个周期的相位差采集两次,并线性插值,使贴图流动连续
  • 随着时间进行,变形越来越大,为了把偏移控制在一定范围内
1
2
3
4
5
float phase = frac(_Time);
// 解决frac产生的跳变
// 构造周期相同,相位相差半个周期的波形函数
float phase0 = frac(_Time * 0.1 * _TimeSpeed);
float phase1 = frac(_Time * 0.1 * _TimeSpeed + 0.5);

image-20220807000102114

  • 用相位差半个周期的两层采样进行加权混合,使纹理流动一个周期重新开始时的不自然情况被另一层采样覆盖

image-20220807000117694

1
2
3
4
5
6
7
float2 tiling_uv = i.uv * _MainTex_ST.xy + _MainTex_ST.zw;
half3 tex0 = tex2D(_MainTex, tiling_uv - floatDir.xy * phase0);
half3 tex1 = tex2D(_MainTex, tiling_uv - floatDir.xy * phase1);
//构造函数计算随波形函数变化的权值,
//使得纹理采样值在接近最大偏移时有权值0,并因此消隐,构造较平滑的循环
float flowLerp = abs((0.5-phase0)/0.5);
half3 finalColor = lerp(tex0,tex1,flowLerp);

三、Flowmap的制作

Flowmap painter

Flowmap painter是unity制作的绘制flowmap的工具(用该工具得到的flowmap是线性空间颜色,不需要gamma矫正,在unity中取消勾选sRGB)

本来还以为这种东西要手动在ps里画RG通道。。。有点头疼来着,没想到这个工具这么方便,并且可以支持flow的效果实时可视化。

Houdini Labs

Houdini Labs是内置在Houdini中的一组游戏开发相关的节点,可以在github中搜索sidefx Labs或直接在houdini中安装(在较早版本中的shoudini中无法在shelf内找到,在这些未被内置到houdini的版本中,这组工具名称为gamedev)

  1. flowmap相关节点功能
  • grid
    • 细分
  • flowmap
    • 初始化向量场
  • flowmap_brush
    • 向量场笔刷
  • flowmap_to_color
    • 将向量映射到颜色
    • 并添加uv(如有uv则直接沿用)
  • flowmap_visualize
    • 可视化flowmap效果
  • maps_baker
    • 导出
    • 输出顶点色,并设置gamma(1-线性空间)
  • flowmap_guide
    • 输入flowmap field(flowmap向量场)和曲线
    • 利用曲线修改向量场
  • flowma_obstacle
    • 输入模型和向量场
    • 以模型和flowmap绘制平面进行检测,模型作为障碍,阻挡flow

Flowmap的烘焙和相关设置

  • flowmap贴图设置:

    • 无压缩或高质量
    • 确认色彩空间
  • Houdini

    • Labs Map Baker节点
    • 导出时注意gamma矫正选项、uv匹配
    • 用Labs UV transfer节点来匹配高模和低模的UV

作业

实现流动效果

我也是第一次听说flowmap这个概念,然后看看我的桌面壁纸发现:

image-20220802184553447

这不就是flowmap做的水流效果吗?也是非常有趣。

作业直接拿去年图形学作业用的水面贴图拿过来用了。flowmap是用Flowmap painter画的。

中间平滑插值的一步看到图像其实很想用三角函数来做,但实操发现影响好像不太大,并且这个计算比起教程里的消耗会更大一点,所以还是没什么必要。

1
float flowLerp = (cos(2*UNITY_PI * _Time*0.1 * _TimeSpeed)+1)/2;//abs((0.5-phase0)/0.5);//

中间过程中一直发现有锯齿,最后发现是纹理压缩的问题,默认是法线质量压缩,在一些边缘处就会出现奇怪的锯齿

image-20220816163919751

把压缩模式换成无压缩就好了(这也是为什么人家工具导出的就是png格式)。

感觉flowmap很适合放在球面上,加一点自发光和半透明,做成朝一个方向旋转的水元素效果。一时间想不起来这种效果的案例哪里有了。

Flowmap

感觉可以再进一步做一个顶点噪声扰动也许效果更好

参考资料

[1] https://www.bilibili.com/video/BV1Zq4y157c9

【技术美术百人计划】图形 2.8 flowmap的实现——流动效果实现