unity gizmo在游戏中绘制_游戏中的大气散射和雾效 Unity中实现推导

雾效在游戏的作用:

在大型的3D项目中都会考虑使用雾效调节画面色调、增强游戏纵深感,雾效又可细分为高度雾、体积雾、线性距离雾。

下面是怪物猎人世界的场景雾效

a42d77846b4d92229d49716e5dfe21f5.png

e16490ce65ad90d6838b37e3a0d85698.png

雾效原理:

单次散射(single scattering)

首先我们需要了解单词散射的大气渲染模型,即光线从太阳发出过,经过一次散射被改变方向并衰减过后射入人眼。

0651019e4ba33d88c3da5b79cdf8cf31.png

光经过大气中的粒子,散射衰减,而大气中又很多不同种类的大气粒子,一般在大气渲染模型中把它们分为两大类:一种是小分子,例如氮气和氧气分子,另一种是大粒子,例如各种尘埃粒子。

小分子:指的是大小远小于光线波长的粒子,小分子对光的散射在前后方向上分布比较均匀,通常会使用瑞丽散射(Rayleigh Scattering)来表示渲染模型,由于这些分子大小比波长还要小很多,因此光的波长也会影响瑞利散射的程度。

大粒子:指大小远大于光线波长的粒子。大粒子在发生散射的时候会把更多的光散射到前向,通常会使用米氏散射(Mie Scattering)来表示渲染模型,由于这些分子大小比波长大很多,波长几乎可以忽略,因为我们认为米氏散射跟光线波长无关。

95a828fdbd9ed39e451b525d0afcf293.png

下面以Rayleigh散射为例,解释S(λ,θ,h)的含义。这里直接给出公式,在Rayleigh散射模型中,散射到θ方向上的比例为:

7d5454876d9f36203624be2dffd6d147.png

其中,λ是光的波长,n是粒子折射率,N是海平面处的大气密度,ρ(h)是高度h处的相对大气密度(即相对于海平面的密度,可以理解成h处真正的大气密度与海平面处大气密度的比值,因此它在海平面处值为1,随着h增加不断减小),我们一般会使用指数函数对它的真实曲线进行数学拟合(是一种近似拟合,不要和后面提到的指数函数弄混):

e947de0716d4121385fb49b2d9b71c74.png

其中,H是大气的整体厚度。

可以看出Rayleigh散射大致和波长的4次幂的成反比,波长越小(越靠近紫光)的光被散射得越厉害。所以白天的时候天空为蓝色,因为蓝光在大气里不断被散射,黄昏的时候天空会变红,因为相比于白天,阳光此时要穿越更厚得多的大气层,在到达人眼之前,大多数蓝光都被散射到其他方向,所以剩下来的就是红光了。

以上内容参考冯乐乐的雾效专题:https://zhuanlan.zhihu.com/p/36498679



以下内容根据上面内容推导:

由于我参与的是手游项目,这么复杂的雾效模型在手游上肯定是行不通的,我们需要对其拟合并用一些通俗易懂的语言解释。

1928695524c0bcdc2ff83f9935218ab6.png

上面的公式中有很多游戏中无法判定的数据,比如光的波长λ,粒子折射率n,海平面处的大气密度N,我们把这些数据合并成常量A来表示,称之为雾浓度。

因此可以拟合为:

30478cca18938cc68b41f5e11b85186c.png

这个公式可以理解为,雾效从海平面向天空衰减,并乘以自定义的雾效浓度数据。

同理,水平方向上的雾效也可以用这个公式来处理,只不过h和H替换成摄像机与物体之间的距离d和D,最后我们得到这个公式。

eb0ef6b6e0df043da13150609ab45dc1.png

Unity中的实现公式可以参考下面两篇文章,具体细节由于项目还未上线,暂时无法提供。

参考:http://iquilezles.org/www/articles/fog/fog.htm

参考:https://www.alanzucconi.com/2017/10/10/atmospheric-scattering-1/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值