百人计划(图形部分)Flow map的实现

https://space.bilibili.com/7398208?spm_id_from=333.788.b_765f7570696e666f.1

 什么是FlowMap

 FlowMap

 Flow map是Valve在2010年的GDC中,介绍的他们在《求生之路2》和《传送门2》中用到的实现水面流动效果的艺术。这种方式因为原理简单,容易实现,而且运算量比较少,所以到现在都还在使用。

image.png

 FlowMap的实质

 一张记录了2D向量信息的纹理

假设有一个2D平面,平面上每个点都对应一个向量,这个向量指向这个点接下来要运动的方向。

我们通过颜色的色值(RG两个通道)来记录这些向量的信息,就得到了一张flowmap

在shader中干扰uv(偏移uv),对纹理进行采样,这样就得到了一个模拟流动的效果

 UV映射(纹理映射)

 Flowmap的原理

 UV经过Flow Map发生偏移之后,它让一个原本采样正常的图,变成了一个扭曲的效果。

需要注意的是UE4和Unity的UV坐标有所不同,UE4它翻转了绿通道

为什么要使用flowmap?

真实感水体渲染技术总结:https://zhuanlan.zhihu.com/p/95917609

 下图为战神中flowmap在天空球中的应用,通过交替出现的云朵可以看出flowmap的典型特征周期性变化

 请添加图片描述

 FlowMap shader

实现思路

  1. 采样Flow map获取向量场信息
  2. 用向量场信息,使采样贴图时的UV随时间变化
  3. 对同一贴图以半个周期的相位差采集两次,并线性插值,使贴图流动连续

如何实现最简单的随时间偏移?

使用UV - time

为什么是相减?
先来看看 uv+time 的情况(u,v) + (time,0) :模型上某个点: 随着time增加,采样到的像素越远
视觉上可以形容为:更远距离的像素偏移向该点,视觉效果和我们直观认识到的运算法则是相反的,所以需要相减

uv偏移并没有改变顶点位置,只是采样到了更远的像素

我们需要更好的运动方向,正确的方法是从flowMap获取流动方向

颜色值范围是[0,1]的,而方向向量的范围都是[-1,1],因此我们就需要使用映射手段(即乘以2,减去1),这样才能从FlowMap获取我们的流向(之前推导mvp矩阵时也用过这个方法)

 把变形控制在一定范围之内

 这个时候时间到达最大值之后会跳变至0,为了解决这个问题需要构造两层相差半个周期的采样,再对它们进行一个插值混合。

在这个插值混合中,我们需要用到一个变化的权重。

1.构造了相差半个周期的的采样

image.png

2.通过frac函数我们限制在了[0,1]范围,

3.接下来使用一个函数来代表我们采样贴图的过程,它会呈现出周期性的脉动的趋势。

image.png

其中红色代表的是我们构造的权重

我们可以看到当它采样到的纹理偏移到最大值的时候,这个时候他对应的这个权值对应的是0

image.png

也就是说,它会在到达最大值的时候会消隐,并且被另外一层所取代

当蓝色的权重取到1的时候,它正好是蓝色处于偏移到半个周期位置之时。

而此时红色正好达到了它的一个最大的偏移,这就意味着当某一层偏移到最大值的时候,它会完全消隐。

这时候我们看到另一层我们所采用的贴图,它会从偏移到半个周期的时候,然后在这一层也到达一个最大偏移的时候又替换为另外一层。

image.png

 这样就是规避了我们偏移到最大的时候,产生的跳变问题,如果我们使用一个函数来进行线性插值来混合这两个用来模拟采样的函数的话,你会发现它会从一层的中间位置,缓慢地过渡到另一层的中间位置,这样就构成了一个连续的函数。

image.png

image.png

 代码

image.png

image.png

image.png

 用flowmap修改法线贴图

应用在光照模型之前

image.png

 绘制FlowMap的工具

需要注意的是,用FlowMapPainter得到的flowmap为线性空间下的颜色,也就是Gamma1.0,不需要Gamma校正,在Unity导入后请取消勾选sRGB,使用无压缩或者高质量。如果使用有损压缩会看到奇怪的小方块。

作业 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值