球谐光照——简单理解和实现

1.简介:

游戏中的光照可以被简单分为两个部分,直接光和间接光。

直接光中我们研究各种不同的BRDF材质,甚至BSDF,BSSSRDF等等。这些模型据有很不错的表现力,足够我们区分金属,皮肤,木头等等不同物体的着色表现。

但这并不能满足我们,因为光并不是那么简单,光会被反射,会被折射,会被透射,会被吸收,所以物体的受光情况同时又由这个场景的其他物体决定,这部分光照同时拥有着更加富强的表现力,被我们称作间接光。

用来做这部分光照的算法也有很多,如raytracing,photonmap之流。

这些算法很复杂也很有趣,不过这些并非我们讨论的重点。因为我们进一步思考就会发现,虽然raytracing这类算法已经从场景中的光源出发,一步一步的追踪光线,这已经十分符合我们在物理学光线发生的那样,但是,真实世界环境中的光源是极度复杂的,事实上——你不知道是个什么鬼东西的玩意就在发着微弱的光并且微弱的影响着场景。也就是我们游戏中的光源复杂度完全无法达到现实中的要求。

于是人们提出了一种叫环境光的概念——一个极度复杂的场景被360度采样后保留在一个环境球上。

大概看上去长这样,有时也会直接作为天空盒,用来表现一些游戏的远景。我们寄希望于用他来还原出这个场景会对某个具体的模型产生的光照效果——当然,由于环境光中只保留了方向性,所以这只是间接光计算中的一种辅助手段。

2.解决:

那么,我们如何解决环境光对物体的影响呢?

首先,我们要理解这样一个积分式:

由于环境光我们只考虑方向性,所以在求解一个点的着色时,我们对这个点的方向上做积分:从四面八方来的光(Lenv(s))->在这个方向上没有被遮挡(V(p->s))->由于辐射通量符合余弦衰减(H(s)就是点乘项)->与物体作用发生BRDF的影响(fr(p,s->d))最终积分累加得到的这个点的着色。

2.1球谐光照与预计算:

理解完积分式后,我们很难理解球谐函数在这里的提出,因为我们很自然的会想到,只需要离线先为模型的每个点计算一下这个积分,并存储在文件里,在实时绘制的时候拿出来运用就可以了。

但是这里的困境在于,虽然受到烘焙的物体常常是固定不动的,但是游戏中的天空盒常常我们希望是动态的,我们很自然的会希望在天气系统中,天空盒会动态改变,甚至进行一定的旋转。或许不同的天空盒,我们还可以通过,烘焙多次来解决,但是不同角度的天空盒,总是不能通过每个角度都来烘焙一次,然后实时绘制时用插值的方式来解决。

所以之前的研究中就想到,如果能分离Lenv(s)这一项的积分和其他项就好了。因为这样,与光源相关的积分我们可以单独烘焙,与模型相关的积分我们单独烘焙,到了实时,我们只需加载不同的天空盒与模型的数据组合就好了。

2.1.1球谐基函数:

为了解决这个问题,我们不得不暂时跳出这个积分式,来点数学知识。

在向量中,我们很好理解基向量这一概念 \overrightarrow{x} = a\overrightarrow{i}+b\overrightarrow{j}+c\overrightarrow{k},其实可以理解为i,j,k是坐标轴,x的坐标为(a,b,c)

在基函数中,我们扩展了这个概念,对于函数f(s) = a*f1(s)+b*f2(s)+c*f3(s),亦将f1,f2,f3称为基函数。我们暂且不讨论基函数其他方面的意义,回归到我们的问题,我们运用他,可以获得怎样好的性质?

\int f(s)*k(s) = \int \sum ci*yi(s)*k(s) = \sum ci\int yi(s)*k(s)

也就是对于我们的积分,我们如果将光源函数看做f(s),其余项看做一个统一的k(s)——也被称做预计算传输函数,然后我们将光源函数分解成一组基函数来表达,就可以把ci提出去,这样就做到了光源函数和其余项积分的解耦——ci为光源函数的积分,yi(s)*k(s)为其余项的积分。

特别的说明一下,ci = \int lenv(s)*yi(s),此过程又被称为投影。

这里我们有非常多的基函数可以选择,最典型的有球谐函数,小波函数,球高函数。

以球谐函数为例,其形式为:

其中的

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值