GAMES202-高质量实时渲染 - P3:Lecture3 Real-time Shadows 1 - GAMES-Webinar - BV1YK4y1T7yY
Hello各位亲爱的同学们。
我们又见面了,今天我们来说Games202的第三讲,然后从今天开始,我们要开始讲一个话题,我们将用两节课的时间来说,实时阴影的渲染,OK那么今天是第一讲,在这之前有几个事情跟大家说一下,第一。
就是说我看有很多同学已经开始,在玩起了作业0,而且感觉要被玩坏了,这个行,大家喜欢,我自然会觉得非常好,这也就说明作业0帮助到了大家,大家可以用它来上手,挺好的,好吧,那么作业一,按照我之前的安排。
这周很可能是和咱们的下一节讲座,一起发布,好吧,然后咱们拭目以待,当然了,我们的助教同学们非常辛苦,这里还要向他们表示感谢,好的,作业一差不多这么安排,然后作业一的内容,自然就是和实时的软硬相关。
我是希望大家去实现一下,这节课要讲的PCSS,Percentage Closer Soft Shadows,至于怎么翻译之后,我们就算了,像这些术语就会越来越复杂,咱们就不翻译了,PCSS。
然后这节课讲PCSS,但是还不太够,可能还需要下一节课开始的知识,差不多咱们这么安排,然后我简单的调整了一点点课程的内容,然后这里从哪可以看,可以从我们的课程主页,这里会反映出最新的内容的改变。
虽然我就是这三讲,调了一下顺序而已,好吧,那么,比如说这节课,咱们原本安排是讲,Variance Shadow Mapping,对吧,然后我们现在要改成说,我们这节课来讲PCSS,因为我想了一下。
这毕竟还是一方面是基础,一方面是现在大家在用的东西,比较重要,咱们先说,好吧,然后关于这本书,这本书我要来澄清一个事情,就是说上一次我说,这本书咱们不作为要求去参考,可能有同学会觉得这本书。
当真是没什么意义,这是不对的,这本书是非常好的书,然后我们这节课,我们这某一课,确实有很多的主题,是从这本书里可以查得到的,特别是第4版,我之前我一直在看着第3版,我觉得它不够新,然后所以说。
如果现在让我重新推荐大家的话,我会欢迎大家用这本书的第4版,来当做一个参考,然后它的参考就好像什么,以我的感觉,就好像说,我们在上数学分析的课,然后你拿一本,高数的书,其实并非不合适,可以作为一个。
咱们要讲什么的一个目录,或者是一个大纲之类的事情,然后但是这本书,绝对不会讲得那么深入,然后我们这个课,可能讲的稍微难一点,会讲一些它背后的一些知识,好吧,这么个意思,好,那么,确实推荐用这本书。
咱们改一改说法,好嘞,还是一样,我们会多讲这些思路原理,而不是会针对说工业界是怎么做的,只讲方法这么一种方式,好吧,那么上一节课,我们已经提到了一些,关于计算机图形学的基础知识,对吧。
比如说我们之前说的硬件的渲染管线,然后OpenGL的基本理解方式,对吧,理解成画油画,然后我们说了怎么样去理解,然后上手去写,GLSL这种着色器的语言,然后我们就开始复习了一点,关于渲染方程的知识。
然后我说我们要,我说我们要复习一下,维基分,结果好像没时间了,没时间了是这么回事,我好好思考了一下,我们这门课要讲东西其实非常多,非常多,这怎么说,就是说,我是很想安排一整节课,来好好复习一下维基分的。
但是这里就算了吧,穿插到每一节课里面,如果我们要用,比如说咱们这节课很快就要用,用的时候,我来提一句,反正我觉得肯定不会缺失一些内容,这样的话,咱们也省一点时间,好吧,这样安排,咱们这节课的开始。
就不会从复习维基分开始了,好吧,那么咱们从什么开始,咱们要从,shadow mapping的基本知识上,来开始说,然后我们在Games 101里面,提到一些基本怎么样做,这么一个概念,对吧。
shadow mapping怎么做,然后我们会在这门课里面,在这节课,我们会多分析一些问题,然后以及它对应的一些解决方式,然后咱们把这一块,相当于是硬阴影的绘制,说清楚,然后我们开始回顾一下。
说我们shadow mapping,到底它背后有什么样的数学原理,为什么我们可以这么做,这块就是我所说的事情,也是我愿意说的事情,就是RTR这本书里面没有的,然后想跟大家探讨一下,对吧。
关于这些实时渲染和离线渲染,或者说基本的渲染知识之间的联系,所以我非常愿意说一些这些话题,然后我们就会说到这节课的重中之重,就是percentage closer soft shadows。
那么在说之前,我先说清楚,这percentage closer软阴影,它这个方法比较古老了,但是它却是现在的所谓state of the art,也就是说中间大家做了很多各种各样不同的探索。
但是最终大家还是选择了,用这么一种方法来实现软阴影,当然不一定,就是说我说的是多数,现在可能认为说,如果大家提到软阴影怎么做,那就用PCSS这么个意思,好吧,那行,咱们就先开始第一部分。
shadow mapping的一些简单回顾,不过在这之前我先看一下,有没有同学问什么问题呢,有同学说RTL4是有翻译的,是吧,那不是挺好吗,不过话说回来真的,就是这本书写得非常好。
英文就包括之前我们说虎书也是一样,这些英文写的都非常不错,然后大家就直接看,我觉得不会有什么问题,好吗,特别是大家不是从头开始看,对吧,比如说大家在学这门课的过程中,比如我们讲到哪。
比如现在在说shadow mapping,大家就可以对着shadow mapping的,那么一那么几张,来看一看,没什么问题,另外给大家展示一下,我是手头是有一本实体的书的,我为什么看不见呢。
那是因为有延迟,看一下,可以可以没问题,好,那么咱们回到shadow mapping这个话题上来,课上不只会讲点光源了,我们要讲软阴影,怎么会只是点光源呢,对不对,哈哈哈哈,好。
那么咱们当然要从点光源的shadow map开始,咱们先说清楚,要渲染一个点光源,在场景中投射出的阴影,我们要怎么做呢,我们要用shadow mapping的技术,这个技术要怎么做呢。
shadow mapping,我们在Games101里面简单提过,它是一个两趟的算法,什么两趟呢,也就是说我会渲染场景,渲染两遍,那么第一遍渲染场景的时候,我是认为我会从light所在的地方。
看向这个场景,然后并且渲染一遍场景的时候,输出一个,这个light所能看到的,最前的,或者最近的深度,这就是所谓的shadow map,那就是第一个path,那么有了这张shadow map之后。
咱们就可以之后的path都用它,对吧,咱们上节课已经说了,这是一个,每一个path它输出的texture,这文理可以拿到后面的path里面去用,那么后面的path是什么呢,那就是第二个path。
我真正的从我的相机的位置出发,我去渲染一遍整个场景,我用这样一种方式,渲染整个场景,我在这个过程中,再配合着,刚才light path,我得到的shadow map,然后我就可以去检测。
我现在的相机所看到的,任何一个点,是否在阴影里,或者是否能被light所看到,这么个意思,大家应该这些算法,基本算法还记得,对吧,然后确实回顾一下,咱们上节课为什么要说,opengl。
它的各个不同的path,一个场景,它为什么要渲染不止一遍呢,这就是一个非常生动的例子,对吧,我们要渲染两遍,第一遍是为了拿到shadow map,然后第二遍才是真正的渲染,对吧,然后也同样道理。
这里也反映了说,frame buffer,然后和texture,然后就是说,我如果从light去渲染,我要把它渲染到一个texture上面去,而这个texture,就是我要的shadow map,对吧。
大家对照着这么一个算法的思路,然后想一想,opengl,我应该怎么样去实现它,差不多这么一个思路,那么shadow mapping,是一个完全在图像空间中的算法,那么它的好处就是。
一旦shadow map已经生成了,那么就相当于shadow map,就已经可以作为,场景中的一个集合表示,可以这么理解,那么为了得到阴影,你只需要shadow map,你不需要实际的场景的集合。
这是一,当然既然是这么做了,那也有它的坏处,它的坏处是什么,我们要特意说两个事情,在咱们回顾完shadow mapping方法之后,说两个事情,第一,就是它的,所谓self occlusion。
这要怎么说,就是,自遮挡现象,会出现这么一种情况,然后另外一个,它会有走样的现象,也就是有锯齿发生,好,咱们待会再具体说,另外shadow mapping,它是一个非常家喻户晓的算法,可以这么说。
做实时渲染,肯定是要从这里开始了,对吧,那么shadow mapping,甚至在最早的情况下,在离线渲染中,也是一个非常有用的,生成阴影的方法,就是说最早的时候。
比如说像pixar的random map,对吧,他们做,这叫什么,toy story叫什么来着,玩具总动员的时候,那个时候还没有什么光线追踪的方法,来做,离线渲染,也就是说离线渲染,即使是光线追踪。
其实对于离线渲染,都已经开锹太大了,这么个意思,所以那个时候用的方法也都是,比如用shadow mapping,来生成这些阴影,这是基本的一些概况,那么它是怎么做的,两趟,对吧,第一趟从light出发。
看向这个场景,然后我要生成一幅图,什么生成一幅图,就相当于是对于每一个像素,对吧,我可以看到一个什么东西,我看到的,这个像素里面的东西,我就只记录它的最浅的深度,就是这么个意思,大家可以看到。
我有很多个不同的像素,它们各自看到的最浅的深度,或者最近的物体,它们的位置在哪,然后我把它存下来,这就是第一步,对吧,然后我就得到了一张texture,然后这一步完成,那么第二步我要干什么。
第二步我从眼睛出发,然后我要再渲染场景一遍,然后对于这次,我渲染的每一个像素,我都要来看,它是否能被light照到,如果能被light照到的话,它就不在阴影里,如果它不能被照到,那它自然就在,对吧。
大家可以看这么两个点,那么第一个点来说,大家可以看到,我在场景中看到这么一个点,如果我连向light的话,我会发现之前,我在light上面,记录了这么一个shadow map上,对应的位置。
它记录的最浅深度,就是这个深度,那也就是说,当前这点到light的距离,跟我之前记录的最小的,light,往这个方向能看到的距离,是一致的,它就可见,否则什么情况,咱们来看这样一个例子,否则的话。
大家可以看到,对于这个点来说,很明显,这个点它连向light的时候,你会发现,它离light这么远,但是如果light往这个方向看,它会看到一个比它更浅的物体,是上面绿色一个小圆的点,我把鼠标停留一下。
是这里对不对,之前shadow map记录的是在这里,也就是说shadow map上,记录的深度要更浅一些,这样的话,就是说明light是不可能看到这个点,也就是说这个点一定在阴影里,对吧。
还记得这么一个基本操作,那么shadow map的效果怎么样,大家可以看到,这是非常不错的,对于这么一个复杂场景,虽然来说有同学说,这场景怎么能算复杂,虽然这个场景的几何不算复杂,但是他们的遮挡关系。
算是挺复杂的了,对吧,这些球一个会叠另外一个,然后大家可以看到,这是一个场景,然后light在左上方,然后它会投射出来一个阴影,在这个平面上,效果非常不错。
对吧,然后如果我们要对比,说有阴影和没有阴影的区别,大家可以看到,有阴影的话,大家会明显的感觉到,多了一种未知感,大家就知道这些小球,他们都在哪,而不是让人感觉是一个非常,完全悬浮的。
和后面的背景没有任何关系的,就是贴上去的一个感觉,对吧,所以说有阴影是非常重要的。
那么在game 101里面,我们还做了这么一些探讨,对吧,如果说我要从light的方向,去渲染这么一个场景,这也正是我们的第一趟,对吧,生成shadow map,不过生成shadow map。
我们可不需要生成一个,shading的结果,像现在大家看到了,大家现在看到的,就是说,如果我真的在light上,那个位置上,放一个camera,然后他对着场景,看过去,会看到什么。
就是真正shading之后的结果,对吧,大家会看到这,但实际上我们更关心的是。
我只需要在light这边的,这个path,我去渲染出来一个深度的,一个buffer,也就是相当于对它的output,我只需要写入GLFragColor,里面只是它的对应的深度,就好了,对吧。
然后大家看到了,这幅左边这幅图,自然就是对应深度,大家还可以看到,对吧,比如说颜色深的,那是当然表示偏黑,偏黑是什么意思,值比较小,对吧,也就是说比较近,当然大家可以看到,这中间这个球。
离大家是最近的,这是非常对的,没错吧,好,那么大家在实际渲染的时候,在第二个path里面,对于任何一个像素,你也都可以计算,它到light的所谓深度,对吧,然后再和shadow map上。
记录的深度来比较,那就是这么一个思路,对吧,这里讲的稍微快了一点,这是因为咱们CMG101,之前都学过这些,所以大家是明白,就算是一个复习,好吧。
那么基本上来说,就是这么一个思路,然后它就可以得到一些,不错的结果,好了,那么这就是我们之前所说的,shadow mapping的技术,然后我这次说,特意说到这两个path,然后大家在OpenGL里面。
按说就可以,应该是可以,简单实现出来的,还真有同学问OpenGL里面怎么做,就是因为OpenGL里面,你的第一个path,你就真在那儿放一个相机,然后往某个方向去看。
定义它要写到某个frame buffer,然后写到某个texture,然后你在fragment shader里面,你要规定你写的是一个深度,而不是一个最后,所谓什么phone shading。
得出来的结果,对吧,咱们刚才说过,然后第二个path,就只要用这个texture就行了,好吧,咱们这里就不再多说,那么这里有一个小问题,有个小问题,就是说这里关于深度,如果大家之前学GAMES101。
应该还记得,我在某一节课之后,我问过这么一个问题,就是说我们在做透视投影的时候,我们说怎么理解透视投影,我们可以把它当成是两步,第一步先把透视投影给挤压成,平行投影,对不对,还是叫正交投影。
我已经不记得中文了,然后先把它挤压成一个长方体,然后再把它拍平,对吧,这么一思路,然后我做挤压的过程中,中间的那么些点,或者说三角形,或者顶点,他们应该是会向近平面移动,还是向远平面移动,对吧。
我问过这么一个问题,对吧,所以说不管答案是什么,然后如果我没记错的话,答案是所有的这些点,都要会被推向远平面,这么个意思,但是不管怎么样,大家可以看到这么一个事情,就是什么,就是说这些点。
他们在经过了透视投影之后,你所得到的z,它其实并不是它实际的,他们原来的这些几何上的点,到所谓light的距离,对吧,这是两个事情,因为它前后发生移动了,对吧,这样的话,大家在做深度测试的时候。
只需要做一个,不是深度测试,就是在做第二步,是真正生成阴影的时候,我要去比较两个所谓的depth,对吧,这时候只需要做到一致就行了,要么是说我light这边,我就都用z值,就是投影过之后。
mvp之后的z值,然后我来比较它的前后相互关系,这可以,要么我用它的所谓线性距离,就真的,我肯定知道某个fragment的位置,对吧,我知道它的位置,然后我又知道light的位置,light的位置。
因为它是个全球变量,我肯定也知道它,我知道这两点的位置,我得一向量,我肯定能算它的实际距离,对吧,所以说我就可以,也算出来一个实际的距离,这个实际的距离,你之前如果shadowmap上记录的。
也是一个实际的距离,那么你就都用实际的距离去比较,这样也可以,这咱们说清楚,这两样都是没问题的,好吧,就是用z值去比较,或者是用,就是实际的距离去比较,都是没问题的,但是要一致,这样就没问题了,好。
咱们现在回到shadowmapping上,这是之前所说过的内容,对吧,那么哪些是没说过的呢。
shadowmapping它是有些问题的,这一点是想跟大家探讨一下,之前我们是没有特别说,对吧,我们就说怎么样做,然后大家可以看到,这里有一个问题,这是什么情况,大家可以看到这张图。
首先是从RTR4这本书里面来的,然后另外多说一句,反正之后可能要说他的工作,这RTR4这本书,他用的这张图也不是RTR4,他们自己做的,他用的是一个人的图,这个人叫做Christoph Peters。
然后Christoph Peters是谁,他就是发明了,我们会说一点点的,moment shadowmap的人,可以说是相当于现在的,state of the art的保持者,这么个意思。
然后我认识Christoph Peters,我之前跟他在NVIDIA,在一块实习这个意思,然后他是标准的moment的大师,这是太厉害了,推了各种各样不同的公式,然后Christoph长什么样。
Christoph就是大家所想象的,一听到Christoph,然后能够立刻浮现出来那张脸,那就是Christoph,然后他有一小辫,德国人,然后挺有意思的一个人,然后平常我们还一直在聊。
然后之后也可能有一些合作,或者什么,这么个意思,挺有意思的人,然后他做了很多这些,shadowmap相关的工作,这就是他为了展示,传统shadowmap上,有一些什么问题,这里可以看得很明显。
我不知道这个角色,是不是真的是劳拉,还是一山寨的模型,咱们就假设他是劳拉,那么他是站在一个平面上,对吧,一个平面上,大家可以看到,他会投射出一个阴影,这些都没问题,那么问题在哪呢,很明显,对吧,很明显。
大家可以看到,在地板上有一些这些,一圈一圈的这些纹路,这都是什么,然后我看有同学说这是摩尔纹,这还真不是摩尔纹,这是它的产生,并不是由于采样造成的,好吧,它是由数值精度造成的,大家看到的,这是另外一个。
某一种纹路,这么个意思,那么它这是怎么回事,为什么shadowmap会造成,这么一个严重的情况,咱们来看一看,这是还是一样,我手绘的图,大家可以看到这么一个事情,首先我生成一个shadowmap。
我肯定shadowmap,它有个分辨率,对吧,它既然有一个分辨率,而且每一个像素,我是不是要记录一个深度,对吧,我一个像素,我要记录,它所能看到的最浅的深度,这是基本操作,对不对,那也就是说,换句话说。
在一个像素内部,它的深度是一个常数,可以这么理解,对吧,这说明了什么,说明如果我从light,看向一个场景,然后咱们就假设是场景,什么也没有,就是一个地板,好吧,然后我从light,看向这个场景的时候。
我比如说沿着某一个像素,往前看过去,我看到的那么一个位置,我就会认为,这是这个像素所代表的深度,也就是相当于,我认为这个场景说,在这个像素所覆盖的,这么一个区域内,都是一个常数的深度,也就是说。
在shadowmap看来,这场景是离散成了,这么一系列的,由红色的这些小片,形成的一个场景,它看到的并不是这么一个平面,没问题吧,咱们再说一遍,是因为在任何一个像素内,它都假设有一个常值的深度,没错吧。
它这个深度是,当然是从light出发,看向场景对应的深度,所以应该跟light看的方向垂直的,所以这么一个思路,对吗,出现这样一种思路的话,这种描述这场景,这就是shadowmap所描述的场景。
我们可以这么理解,那么它为什么就会造成有问题,那就是说,我在第二次渲染的时候,第二个pass的时候,我从camera出发,然后我会打到一个,某一个什么物体,对不对,假设我打到了这,打到这我怎么办。
常规操作,对不对,连向light,连向light之后,然后我会发现,这段虚线长度,对吧,这段虚线长度,就是它的深度,它的深度,但是我发现在shadowmap上,大家看这里,脚点这个位置。
这么一个橙色的点,这么一个位置,它才是在对应的shadowmap的,像素上记录的深度,大家会发现,他们俩差的不多,对吧,差一点点,但是在shadowmap上,记录的深度要更浅,那就发生了一个什么问题。
那就发生了一个,自遮挡的问题,就是说,理论上来说,怎么可能会出现这块的地板,会遮住另外它旁边的地板,但是它就是由于你的shadowmap,它记录的深度是不连续的,对不对,它记录的是每一个像素。
一个长值的深度,而造成的这么一种,对场景的曲解,对吧,是这么一个意思,好吧,那么这里,我会问几个问题,比如说第一,有没有一些情况下,不存在这个问题,对吧,大家可以看,比如说我立刻可以看到一点。
那就是当light,如果说我是从上往下照的时候,从上往下照的时候,这样的话,我记录的深度,虽然还都是长值,但都跟平面,它是保持一致的,对吧,跟平面没有一个夹角,这样的话就说明,在从上往下照的情况下。
这是问题最小的,那么同样道理,什么时候问题是最大的,对吧,咱们立刻就可以知道,当light,它变得非常偏的时候,它几乎可以认为是一个,如果大家还记得这个词的话,grazing angle,这么一个角度。
对吧,几乎平行的照相,这么一个地面,它会造成这么一个问题,对吧,这就是它最严重的时候,这么个意思,这个问题,其实就是所有的这些,使用shadow mapping的方法,都会有的一个问题。
甚至之前我自己亲测,我在塞尔达晃宇之息里面,我是见到过这么一个问题的,就是在夕阳西下的时候,就这种情况,要不是阴影拉的最长,对吧,也是light和平面最平行的时候,就那种时候,大家会看到。
即便是塞尔达这样的游戏,都是会有一些问题的,确实是这样,好吧,这就是这么一手,那么自然有了问题,咱们就要想办法去解决问题,对不对,怎么解决问题呢,这时候就是,人们聪明的地方,大家来看。
就是说出现这种情况,它不是自己挡自己吗,对吧,我们只要避免说这样一种,自己挡自己的情况就可以了,是吧,然后我们怎么办,大家可以看,还是这段手绘,就是说如果我认为,就是说,我要判断之前。
shadow map上,记录的深度,比我实际的深度小,还不够,我还要认为说,它得明显的,比我现在实际的深度要小,也就是说,如果说大家看,在这么一段范围内,中间有东西,我就不算了,我就说,如果我之前认为。
有这些障碍物什么的,它在这一点到light之间,我都算是这的,如果障碍物出现了,是黄色的,这么一小段里面,我就不算,不算,就是这么个意思,然后所以道理是非常简单的,对不对,而且这个地方,还有一些技巧。
可以讲究,什么,咱们刚才才说过,对吧,在光源和地板垂直的时候,是没这问题的,对吧,然后在光源和地板是斜着的时候,会有这个问题,那是不是说我可以在,这么一个所谓容忍的,这么一个小的区间,的长度上。
做一点文章,对吧,如果说我是垂直打的话,我就认为,小的区间可以非常小,也就是说,我可以让它更精确一些,然后如果说light和地板,它的夹角很大的情况下,如果出现这样一种情况,我就让所谓的。
这么一小段的长度更长一些,这是不是非常有道理的,对吧,那么怎么判断,还是之前,咱们GAMES101,已经用了很多次了,对吧,判断说两个方向的夹角,对吧,咱们用一个什么cosine,用什么都可以,没问题。
但是咱们可以调整,这就是我所说的这么一个事情,大家看标题,就是说我们可以加上一个所谓的,bias,就是这段的长度,那就是bias,对吧,然后去降低这么一种,自遮挡的情况,对吧。
那么这一个bias项是可以,不是一个常数的,它是可以变动的,并且可以根据角度来调整,没问题,但是话又说回来了,它引入了一个bias,它解决了这么一个情况,它会不会造成一些什么其他的问题,对吧,答案是会。
它确实,解决了这么一个自遮挡问题,但它引入了另外一个问题,大家来继续看,大家从这幅图上就可以看到,看到两个事情,对吧,第一,自遮挡问题没了,这个纹路没问题了,但是第二个问题就是这块不对,大家可以看到。
劳拉鞋子这边投影出来,按说这块阴影应该是连着的,怎么会断在这儿的,对吧,对了,那就是说,为什么会有这个问题,咱们还是看这段bias,咱们不是说吗,在这段bias之内,咱们都如果真的有一个什么物体。
出现在这儿,那么我不算它遮挡这个点,如果我bias调的过大了,会丢失一些,原本可能造成遮挡的一些物体,产生的阴影,对不对,这里就出现这么一个事情,然后这就是它造成的一个问题,那么这个问题怎么解决。
咱们马上再说,然后我看到有同学在,就是说我们是有工业界的朋友们,就是大家对工业界的这些黑话,是非常熟悉的,对吧,就是说关于刚才的所谓self occlusion,工业界是有一套自己的说法的。
然后关于这里,Detached shadow,工业界也有一个什么名字,叫什么彼得潘,各种各样的这些神奇的这些命名,工业界有很多这些,就是不怎么严谨,但是听起来很有趣的一些命名,但没关系。
咱们就反正把这个意思说到,对吧,我们就管它叫detached shadow,就是不接触的阴影,就是出问题,对吧,好,咱们现在回到这个问题上来,怎么样解决这个问题呢,首先我先说清楚。
工业界真正去解决这个问题的方法,是几乎没有的,好吧,咱们就说,没有人真正试图去完全百分之百的,去解决这么一个问题,而是说我要找一个比较合适的,这么一个bias,这么一个数,然后使得说。
我又不会有这些所谓的自遮挡,又不会出现detached shadow,会去找一些这些参数,为什么这么做,是因为这是最简单的一个方法,咱们先说清楚,工业界就这么解决了,好吧,但是学术界还是有一些。
提出的一些方法,虽然这也算是工业界的,但是没有太多人在工业界用,我们先说清楚,这里要告诉大家的一个方法,叫second depth shadow mapping,这是一个非常有趣的方法。
那么这是一个什么方法呢,他说的一个核心思想是这样的,咱们第一趟,不是说从light,我要看向场景,我要记录他所能看到的最小深度,对吧,他做了一个额外操作,我不仅存最小深度,每个像素不仅存最小深度。
我还要存第二小或者次小的深度,OK,咱们现在看下面这个例子,下面这个例子,假设这就是场景,然后灯是从上往下照过来的,所以说你的shadow map,一开始从上往下来生成的。
那么原本的shadow map,他肯定会给你生成一个,就是上面这么一个东西,然后第二个深度,或者说深度第二小的深度是什么,会看到这些东西,这条线,这条线,这么个意思,然后他们的,他的这个做法是什么。
他是用最小深度,和第二小的深度中间的深度,来做这些阴影后续的这种比较,那么大家可以看,如果有光线从上往下过来,也就是我从上往下看,我如果看的是这么一溜的话,他这是最小深度,这是次小深度。
那么他会用他们两个的中间深度,用这么一个深度,来做后续的阴影比较,但是咱们这说清楚,在这就不再用bias了,没有bias什么事,他就是说就用这个深度,和你实际在场景中看到的物体。
他对应的那一个点的深度来比较,然后这样比较就可以解决问题,那么这样解决,为什么能解决问题,大家可以想象成,比如说这上面这个面,就是刚才看到劳拉的鞋子的鞋面,好吧,然后这底下,这就算是劳拉的鞋子鞋底。
咱们这么理解,那么就算是你有一个平面,它就贴着这个鞋底,咱们假设说你是在这个位置,我的鼠标放的这个位置,那么它是和谁比较深度,它并不是和鞋底的这个位置比较深度,它是和鞋面和鞋底的,中间的这么一个位置。
它和它比较深度,它中间是有一个很明显的一个差别,它会被挡住,那么在这个地方,这是一个更极端的情况,对吧,咱们假设在这,好吧,在这的话大家可以看到,最浅深度是这里,次浅的深度是在这里。
那么它们平均的中间的深度是在这里,那么就算你底下是一个平面,紧贴着这么一个鞋底的位置,你都会发现,它这里会遮挡,没有问题,这是挺有意思的一个事情,好吧,那就是说这是一个不错的思路,那么咱们说清楚。
听起来非常美好,实际中没有人用,为什么呢,因为它首先它有若干问题,咱们挨个说,首先它有一个问题,就是要求所有的物体,都得是所谓watertight,什么叫watertight,就是说这个模型本身。
它不能是一张纸这种,就是它有正面,它就一定得有反面,就算你要描述一张纸,你也得把它做成一个很薄的一个盒子,这么一个概念,好吧,对吧,对地板也没有,就有同学意识到这么一个问题,地板就是这么一个问题。
就是它不是一个watertight的一个物体,那么这就是一个非常严重的问题了,对吧,那么另外还有一个什么问题呢,就是说,是这样的同学们,我地板的话,其实是有一个特殊的办法,你可以记录个次显的。
距离是无限大,其实就可以了,这里其实跟,比如说在地板和光源中间放张纸,这还不是一个概念,这么个意思,不是再说就多了,没问题,咱们就停在这,那么我这里就是说,还有另外一个问题,我们来说清楚是怎么回事。
比如说大家应该怎么样去实践,说我去保留,最小和次小的两个深度,咱们把这个问题给抽象一下,好不好,咱们不是每一个像素都要对任何一个,输入的fragment,我们要测试一下的深度,对吧,它是不是最小。
是不是次小,对吧,然后我现在就等于我有一个,这个算法,有一个算法,它的输入是一系列无序的数,对吧,无序的数,你并不知道这些fragment,到底哪一个是先给你,哪一个是后给你,对不对,然后它会按顺序。
输入到你的算法里面,你会接收到这些数,并且你要始终保持着最小和次小,大家想如果要保持最小,那是非常简单的,我只用每一次跟最小比较,是不是要更新就好了,我要保持最小跟次小的,我两个都要比。
还要涉及到swap,对不对,涉及到这么一个实现,但是不管怎么样都是on的,对吧,然后但是你肯定可以实现出来,但是这样一来,大家就可以发现,这个事情就稍微实现要麻烦那么一点,虽然来说,这么一个时间复杂度。
是没有变化的,所以这里其实是我想借这个机会,跟大家说一个事情,就是说这里的实现,就已经多了一些EF或者什么的,然后有同学会问,这个影响很大吗,答案是确实影响很大,然后这里给大家下一个结论。
什么,实时渲染,不相信复杂度,好吧,正如什么,正如电子竞技不相信眼泪,一个道理,实时渲染,不相信复杂度,他只相信绝对的速度,就是说,你要是为了做一个什么样的算法,比如说咱们说什么矩阵乘n的多少。
2点多少,对吧,人们在研究各种各样的方法,哈哈,然后这一点是怎么说,就是在实时渲染中,大家非常不关注的一件事情,哈哈,ok,有同学说没有听见,我说电子竞技不相信眼泪,不是,我说实时渲染,不相信复杂度。
这个意思,ok,然后就是说,这么个意思,ok,那怎么办,行吧,这块多跟大家说一下,好吧,就是说,就是你可能会设计了一个on的一个算法,但是你要把整个一个,比如说一个串,你得走个好多遍,像这种情况下。
像这种,real time rendering,像这些就会觉得,这已经挺慢的了,好像这么个意思,就是说它的级别是要求非常苛刻的,大家知道real time rendering。
它为了达到real time,每一帧只有非常少的时间,给大家去做一些各种各样的效果,反正我多扯一点,这样吧,是这样,我有一位师兄,师兄叫做王熙,他在网易应该是什么,奇马遇坎,不。
我去我这说起来有点像黑他,我去不好意思,战疫,战疫的制作,人,OK,是我们之前在清华实验室的,算是大师兄了,然后之前我还是本科生的时候,然后他当时就回去给实验室做了一个报告,然后他当时不是在做战疫。
他当时在做Xbox的荒野大镖客1,这么个意思,然后他,我想一想,他当时说了一个,让我非常震惊的一个速度要求,是这么个意思,比如说我在游戏中引入某一种,某一种什么,引入某一种新的效果,咱们说好吧。
做一个新的什么样的效果,然后我们加到游戏里面,咱们比如说镜头光,好吧,咱们就说这么一个简单的事情,那么给效果分配的时间是多少,大家可以猜一猜,就是说如果我要加这么一种效果,然后这个效果它实际跑起来。
我会给他多长的时间的分配,因为大家知道吗,每一帧对吧,咱们就说30帧每秒,那我是不是要,是不是应该把它给分配到,不同的这些关键的这些步骤里面,对吧,那么给一个某一种效果的时间,是多少,是一毫秒,一毫秒。
没那么夸张,0。1毫秒,没那么夸张,一毫秒,意思也就是说,如果超过了一毫秒,这种方法再好,我们不能用,没办法,因为它会拖慢,严重拖慢时间了,也就是相当于会降低它的帧率,是这么个意思,那就得忍痛割爱。
一点办法都没有,所以大家可以想象一下,这个实时渲染,它对各种各样,不同方面的这些要求,有多么苛刻,对吧,特别是时间,OK,行,那行吧,这块就给大家稍微多说一下这个话题,对吧,因为实时渲染。
确实它有一些很不可思议的一些要求,但是想想都很有道理,这个意思,咱们回到刚才的shadow mapping,这个事情上来,我们刚才说到什么了呢,对吧,我们刚才说到,就是它的一个问题,就是自遮挡,对吗。
shadow mapping还有另外一个问题,这个问题非常显而易见,大家从这幅图就可以看得出来,那么什么问题,就是走样问题,对吗,因为你的阴影图本身,就是shadow map本身,它有一定的分辨率。
它不可能无限大,对吧,它有一定的分辨率,也就是说你对场景,就相当于有了一个,有一定分辨率的一种表达方式,当然就是说,你要是在渲染的时候,如果分辨率不够大的话,你就有可能会看到一些,这种巨石状的东西。
因为刚才就说了,shadow map上每一个像素,它就可以理解成一个小片,对吗,constant depth的一个小片,那么它投影出来阴影,自然而然会是这样的,那就会有问题,对不对,怎么办呢。
这里就会有几种不同的思路,首先一个是咱们这课上,不会特别多说的,是cascaded的方法,然后这是一些工业界的一些做法,然后,他们可以就是说,给这个shadow map不同位置,不同的分辨率,这是一个。
另外一个各种各样不同的,其他的所谓动态分辨率的shadow map,这些都是比较高端的,所谓,这个叫什么,technique就是技术了,对吧,然后咱们在第一节课已经说了。
就是关于shadow map本身,它背后的科学,其实这就说到差不多了,然后剩下的就是各种各样技术,怎么样去解决这么些实际问题,好吧,ok,那么到此为止,算是咱们把这块复习,以及加上一些新内容。
给说清楚了,然后我来停一下,我来看看同学们,有没有什么其他的问题,ok,好,有同学说我今天有点卡,确实我自己开这边,就是直播间,我也可以看到,我确实画面上有点卡,我问一下同学们,我声音卡吗,真的,ok。
风扇在呼啸,这个暂时没什么办法,声音不卡那就好,另外一个事情是这样的,我也不知道,我这边是不是录播了的效果就会好,因为我这边是一边直播一边录,然后可能录下来的,或者之后上传到b站的,就不会卡了,好吗。
然后之后我再想办法,看我们家网络要怎么样解决,没办法,这边网络确实条件跟国内没法比,这是真的,有很多基础设施都没法比的,这是什么公路保险,然后像网络,这美国跟国内真的没办法比,这是实话,好吧。
然后我来看一下,有同学说,这么些问题,ok,csmpc,是这样的,软阴影,我刚才说了,就是说现在大家用的普遍多的就是pcss,我们待会区分一个概念,pcf和pcss两个不是一回事,ok,然后。
csm有同学问会不会说,就convolutional shadow mapping,如果有时间,我们在下一节课的最后,给大家提一句,只能这样玩。
因为convolutional shadow mapping的话,我的感觉是用的不如,甚至不如moment shadowmap用的多,然后如果说正常情况下,对速度要求非常高的话。
用vsm可能就variance shadow mapping,咱们下节课会主要说的一个内容,可能会更好一点,快一点,这意思,ok,就是csm有自己的一些问题,等一下。
大家说csm不是指convolutional shadow mapping,cascade是吗,是吗,反正在我这边,至少我一说,csm指的就是convolutional shadow mapping。
是我一个师兄做的东西,好吧,那行吧,工业上是cascade,好,我知道了,还是一样,像这些纯工业界的东西,我们就放在最后一节课说,好吧,这个意思,ok,有同学说反应说,如果都是on的算法。
有一个是两倍的n,那我就觉得不太能接受,是说的太对了,没错,两倍的n就比一倍的n要慢很多,所以我们很在乎常数的,好吧,不是说只在乎复杂度,ok,ok,行吧,关于再深入的cascade的这些问题。
我就真的不知道了,好吧,行吧,咱们就先继续,好吧,咱们还是有不少东西的,ok,那么这样看来的话,我们有希望可以讲完,我说按准点讲完,看吧,好吧,咱们现在要讲另外一个话题,这个话题在实时渲染中。
大家其实不怎么特别多提,但是我非常愿意提,为什么,这是说实时渲染背后到底是什么,它的背后一定还是这些理性渲染,或者说真正的这些渲染的这些基本知识,咱们看怎么样把shadow mapping。
和我们之前所学的一些渲染的,基本知识给结合在一块,好吧,这么个意思,那么咱们怎么理解,咱们首先要从微积分开始,大家还记得吗,我说我们不刻意复习微积分了,咱们穿插式进行,那么微积分里面,大家都上过微积分。
对吧,大家都知道,微积分里面有很多非常有用的,不等式,对吧,比如说大家看到的这么个截图,这是什么施瓦茨不等式,和什么明可夫斯基不等式,对吧,哈哈哈哈,大家虽然不记得了,但是肯定还记得自己之前曾经接触过。
对吧,证明过,对吧,然后这么个意思,然后它表示各种各样的不等的这些性质,然后大家看非常有意思,这两个式子尤其有意思,什么呢,因为它反映了一些,一些可能比较常用的一些操作。
比如说你要对两个函数的成绩进行积分,像施瓦茨不等式,对吧,然后它会有一个不等关系,就是对它们分别进行积分的一个关系,然后对于求和式或者说平方和,和的平方,这么一个式子在积分里面,你也可以把它给拿出来。
然后去做一个这么一个比较,对吧,然后如果大家维基分比较熟的话,大家还会记得,还有什么Jensen不等式,什么Holder不等式,特别多,哈哈哈哈,对吧,各种各样不同的不等式。
然后以及说我们下一节课会说的,切比雪夫不等式,然后这些都会说,ok,那么,这就是维基分,咱们学过很多各种各样理论的东西,然后这些东西,大家其实之前会一直说,咱们学这东西证明这东西干什么。
这回大家发现有用,怎么有用了,在实时渲染中有用了,但是有一个细微差别,细微差别什么,在实时渲染中,我们不太关心不等,好吧,我们不太关心不等,我们关心什么,我们关心近似相等,这么一个概念,换句话说。
就是说我们更希望说,把这些不等式,拿来当约等式使用,是不是一个非常大的假设,对吧,它原本是不等的,对吧,但是我会认为他们约等,特别是建立在一系列的条件下,那么同学们现在给大家介绍,在实时渲染中。
几乎是穿插着各种各样,不同的领域,子领域的一个重要的,近似的等式,什么,是这么一个等式,OK,这是什么等式,大家可以看,大家以前肯定是,见过,如果说接触过这些实时渲染的各种各样,不同的这些奇迹引巧。
对吧,肯定都见到过,这个不等式,不是不等式约等式,但是这次我们单独把它拎出来,单独好好去看一下,这说的是什么,这里说的是,如果你有两个函数的乘积,你又想把它给积分起来,你是可以想办法把它给拆出来。
什么拆出来,大家可以看,左边的两个函数乘积,然后积分,右边大家虽然看到有一个分数,对吧,咱们先不考虑分母,咱们考虑分数的分子,再看右边这一部分,那是不是就是两部分函数f,我把它给积分起来。
g我把它给积分起来,对不对,然后大家就可以看到,这个约等式,它做了件什么事,它又把两个乘积的积分,给拆成了积分的乘积,对吗,是这么个意思,那么大家在学微积分的时候,老师们就说,这是绝对不可能的,对不对。
这是因为这是错的,它肯定是不能这么做的,但是我们可以近似的认为,它可以这么做,那么就是说它有几个事情,我要说,对吧,一个是什么时候,我可以认为,这它算是基本上可以接受的,对吧,咱们简单做一个分析。
但是在这之前,我先给大家解释一下,为什么说这里会有一个分数,对吧,它有一个分母,这分母貌似在积一个完全空的东西,对不对,大家可以看到这个事情,那么这里简单解释一下,像这种所谓分母上的事情。
这些都是所谓皈依化的常数,意思就是,你把这些式子给拆出来了之后,然后它不希望说能量上,比如都成了个10,然后像这种情况,对吧,然后你不希望乘上那么一个常数,你希望它最后的能量还是一样的。
差不多是一个数量级,那么这里怎么理解,对于一系列的皈依化常数,如果你不好理解,很简单,你找一束试试,咱们就假设,fx它是一个常值函数,它的值一直是2,好吧,咱们这么说,它是常值函数fx一直等于2。
说清楚,然后积分线是什么,积分线咱们假设是一维的,假设是一维的,积分线是0~3,OK,也就是说,它会有一个积分的区间,长度是3,OK,这么个意思,那么我们想,左边的式子,左边式子fx,既然它是常数2。
那么2可以拿到左边去,对吧,也就是两倍的gx的积分,对吧,右边这个式子,那我看,如果我对fx在0~3这个区间去积分,那我上面积分出来是6,对吧,2乘3得6,然后下面空的积分,它会记出来结果是3。
所以6除以3正好得2,没问题,皈依化常数,这么个意思,行,那么在实际用的过程中,我们就看底下就是个常数,但不管怎么样,它是要算的,对吧,但是它的真正的最大的作用,就在于把fx和gx,这成积再积分。
给先拆开了,拆成了积分再成积,这是非常有用的事情,然后就有同学会问,这是一个最关键的一个问题,对吧,我也写在这里,就是说它什么时候是准确的,或者说什么时候这么做,是可以认为更准确一些,对吗。
什么时候准确,我给大家提供两个条件,第一,当g的support非常小的时候,这个事情support的话,怎么翻译,大家就可以理解成积分线,但其实并不是严格意义上这么回事,就是说大家可以想象。
Omega积分,它如果在一维的情况下,它是区间,对不对,二维情况下,也许是个整个球面,对不对,也许是整个球面,但是如果gx,它本身是长得像一个高斯一样的东西,它就在球面上的一个很小的位置上,这种情况下。
也就是说,当你的实际的积分的范围挺小的时候,那么这个积分这么一个近似是准确的,对,就是它的所谓,可以理解成积分域,实际的积分域小的时候,那么这是一,然后第二个事情,我先把结论说明白了。
第二个事情就是g这个函数,它是足够的光滑的情况下就可以了,就是说这个gx,就是说,它在它的积分域的范围内,它的变动不要太大,这两个条件满足其中一种,它就会比较的准确,大家之后自行可以用南派来验证。
对不对,ok,然后这么两个事情,那么我平常在学术界,大家就会说gx is smooth,smooth这里指的,并不是说什么,那种连续的那种smooth的概念,而是说,或者说就是说,gx在它的范围内。
min max差别不大,或者说它比较低频,这么个意思,这个意思,gx变化不大,这两种情况下是比较准的,那么这两种情况下,都可以在渲染中对号入座,咱们马上再说,好吧,那么咱们立刻就可以用。
刚才提供的这么一个,不等式,不是不等式,约等式,咱们来做一个简单操作,什么呢,咱们上节课刚刚复习,对吧,对于实时渲染来说,人们写rendering equation,就更愿意把 visibility项。
给单独的拆出来写,对吧,那我把它拆出来写,有什么好处呢,那就是这样,咱们立刻用刚才的公式,立刻就可以推导出,我可以把v,和其他的这些项,它们不是乘起来了,对吧,L和BRDF和什么其他东西,全乘起来了。
v是另外一边,那我把v拿出来,并且我做规划,那么我把v拿出来之后,然后我是不是就可以得到,下面这么一个式子,那么下面这个式子,反映了什么,这就是一个非常有趣的一个事情了,大家看右边是什么。
右边没有 visibility,因为没有 visibility,它是什么,它就是shading,对吧,咱们之前讲过shading,他不考虑visibility,他就是我直接做shading的结果。
那么左边是什么,大家可以看左边是什么,左边是visibility,也就是说,我把visibility,从最后的结果,拆出来了,拆成了shading部分,和visibility部分,并且两者可以相乘。
这不正是我们shadowmap的一个,最基本的思路吗,对不对,我们只需要做shading,然后我之后再把visibility,给乘上去这么一个事情,那么另外一个事情是这样的,咱们继续看,我们刚才问到说。
这么一个近似的等式,它什么时候是准的,咱们第一个条件就说了,当support或者积分线很小的时候,对吧,很小的时候,它是准的,那么我就问大家,什么时候积分的范围是最小的,它最小能小到什么程度。
咱们就想象说,在eway情况下,这个区间小小小小小到一定程度,那是不是就小成了一个delta了,对吧,也就是说,它变成了一个delta的时候,对,或者一个点,对吧,一回事,那就没有积分什么事了,对吧。
那也就是说,那右边也没有这么积分了,那就是大家做的shading,那么左边这个积分也没有积分了,它就是一个visibility,对吧,它一个visibility,什么时候积分范围是一个点的。
那也就是一个点光源,或者方向光源的时候,只有这一个方向上能够有一个,或者只有一个这个点上,它会有光照,对不对,这个时候就不需要积分,也就是说,对于点光源和方向光源来说,这么拆分准的没问题。
这就是shadow mapping,背后的基础,做硬阴影的理论基础,对吧,这还是挺有意思的,对不对,就是说平常来说,大家,就是说特别是实时现场,大家就会对背后的这些数学,什么东西,就是看的会比较少。
对吧,然后但是我们是可以这么解释的,非常有趣的一个事情,对吧,另外一个事情,我之前说,什么时候是准的,就是说,当另外半边的函数,大家还记得吗,就是留在积分里的函数,就是整个就是g,对吧,这个函数。
它是足够smooth的情况下就可以了,smooth就是变化不大,低频,那么大家看,这里的g项对应的是什么,这g项对应的是光照,光照,然后又有一个brdf,对吧,它这些是smooth的,对。
然后大家可以看到,什么时候我可以认为,这两项是smooth的,那也就是说,如果我的这些光照,它是uniform的,也就是l,它不变,l不变,这里对于渲染,它是有一个非常明显的一个例子。
就是对应一个面光源,好吧,咱们假设有个面光源,它的积分线,它自然就是在面光源所形成的立体角上,对吧,和shading point形成立体角上,然后面光源内部,它的radiance各处都不变。
这是我们之前可以假设的一个事情,对不对,那么这里它的l,我就认为它是完完全全是smooth的,那么如果对于这个物体,对于shading point来说,它的brdf什么时候,我认为它是smooth的呢。
那当然就是这个brdf是diffuse的时候,我认为它变化非常小,没问题,如果它是glossy,肯定有的地方接近零,有的地方值特别大,对吧,那就是这么回事,那也就是说,如果当光源是一个正常的面光源。
上面没有什么radiance的变化的话,然后shading point又是diffuse的话,这时候我也认为得到的结果是准确的,这里也没有问题,对吧,这里就是,大家会看到学术上的各种各样这些paper。
大家都会说,我的shadow mapping,它在什么情况下是不准的,什么时候不准,那就是说在brdf,它是对于面光源,或者说对于环境光照,这些都是环境光照,就算是超大的面光源,就是这个意思。
然后像这种情况下,然后如果又是glossy brdf,其实是不太适合用shadow mapping的,这里同样我们可以这么来解释,这就是因为brdf那一项变得不再smooth了,这么个意思,好吧。
然后两个条件有一个就可以,没什么问题,而且这本来就是近似,当真这两个条件都不怎么具备,你还可以强行的这么来用,大家会在哪见到,会在ambient occlusion,也就是环境光遮蔽这块。
待会之后跟大家说的一个话题,这里还会用到,但是这里如果有同学,早点愿意推的话,大家会发现有一个cos的问题,好像跟我写的不太一样,但没关系,到时候我们会发现,其实是完全一样的一个道理。
用的仍然还是这么一个,阅等式,也就是说,这个阅等式是非常有用的一个东西,好吧,那么这里我再停一下,这算是背后的数学基础,OK,好,那么,OK,A貌似,好像没什么特别多问题,还是说这块有点难,没关系了。
就是说真的,我觉得大家最喜欢的话,就是直接拿什么南派去自己做实验,对吧,你自己去积分一下,这fx gx成绩的积分,和积分的成绩,对吧,OK,离线渲染中有这种估计吗,离线渲染正常,我好像没怎么特别见到过。
这个意思,好,这种没有什么误差公式,而且大家之后可能会更习惯,就是在实时渲染中间,很少有人说会分析一下,他的理论上误差的上下界,像这些,我知道大家做这些什么机器学习理论,有很多老师同学们。
特别擅长推这些误差的界限,特别是什么o多少的,这没什么特别大的这些,必要,我就是说在real time rendering里面,毕竟它是一个非常偏硬的用的东西,之后把这个公式,大概在不同的情况下。
把它想明白就可以了,对吧,没问题,近似近似,好,目前拆出来这项是表示阴影,没错,然后但是我就是说,它是一个通用的一个做法,它还可以再拆出其他的一些什么东西,好吧,好的。
还有同学说small support,对两个同样要求,这么一说,它应该是只要求一个,具体我就不再继续往后面说得更详细了,因为咱们照这样说,好像又说不完了,行吧,拖沧,日常拖沧,那么下一个话题。
下一个话题,PCSS,这个意思,那么这块来说,就是今天的,看看主要内容,当然了,这是前面做的这些内容铺垫,都会用到这个里面来,大家会看到我这里说的,描述方法叫PCSS。
Percentage Closer Soft Shadows,所以说这种方法,才是产生软阴影的一个方法,好吧,那么首先还是一样,按照咱们之前的套路,说为什么会涉及到,我们要用这样一种方法来产生阴影。
咱们刚才说的shadow mapping,难道不能产生阴影吗,能对吧,shadow mapping可以给你所谓的硬阴影,这个意思,但是在实际的生活中,人们更加会喜欢,或者说更多遇到的,是这种软阴影。
大家看到左下角这幅,对吧,那么软阴影和硬阴影,得,这个说的绕的,硬阴影的区别是什么,那就是说大家会看到软阴影,它在阴影的边界上,或者说它干脆就没有一个明显的,从有阴影到没有阴影的中间的一个界限。
而它会有一个过渡,过渡这么一个意思,而这样的话,就让人看起来会很自然,是不是,而这是因为绝大多数光源,人们在日常生活中见到的都是些面光源,咱们这些在Games 101里面,又已经提到过了,对吧。
那咱们就不再多说了,特别的就是对于地球来说,有一个非常明显的面光源,就是太阳,太阳的话,它无论如何,它是具有一个非常大的大小的,对吧,然后像我们平常见到的这些,所谓日食或者什么现象。
都可以用这些所谓半影,这些理论来解释,好吧,那么软阴影实则是什么呢,就是说我从本影到没有阴影之间,它会有一个所谓半影的区域,这些半影的区域,光源,如果说在这些区域上看向光源,你会发现光源是部分被遮挡。
部分没被遮挡。
它就这样的话,就会有一个过渡这么个意思,这就是之前的这么一个解释,也是我们为什么要想办法,把这个软阴影的效果,在实时渲染中做出来的一个理由,对不对,好,那么,为了做软阴影的这么一个效果,在实时渲染中。
大家首先大家会用到一个工具,这个工具叫做percentage closer filtering,叫PCF,然后PCF咱们首先先说一句,它最早研发出来,并不是为了生成软阴影,就是PCF的基础。
它是用来干什么的,它是为了做抗锯齿,OK,或者说反走样,这么个意思,然后就是说,咱们把这个事情说起来,就是说,在学术上,我们稍微区别一下这两种方法。
percentage closer filtering,叫PCF,然后如果用它来做软阴影,叫PCSS,这两个上,PCF是用来做抗锯齿的,就刚才大家看到,那个忍者的阴影投影在墙上,对不对。
它有各种各样锯齿,它是为了把这个东西处理掉,对吧,然后后来人们发现,这PCF还能被用来生成软阴影,这么个意思,好了,然后它做的一件什么事,就是PCF做了什么事,它做的事情就是相当于是。
我要把所谓我做阴影的这些比较,对吧,我在任何一个点,然后我原本我连向light,我会看它是不是在阴影里面,是的话,我们就把它标注成0,然后如果不是的话,那我就能看到,我就把它标注成1。
就是对于这一系列的结果,它去做一个所谓的filtering,这就是它说的这个filter的意思,虽然来说,我个人不太赞成,什么都叫做filtering,它实际上就求了一个平均,就这么一个意思。
那么它是怎么样运作的,对吧,然后咱们马上就会说,然后在这里,我要先区分一下这么一个概念,第一,PCF它的这部分filtering,指的不是说我最后得到的那么张图,OK,指的不是说我最后得到那么一张图。
就是相当于刚才大家看到的,那么一个,那忍者的那么一个阴影,在那张图上做一个不是这么做,OK,它是在你做阴影判断的时候,然后做filtering,它并不是在最后的最后生成,这个阴影的结果,上面做,这是一。
而这点怎么理解,这跟我们之前所说的,怎么样去做反走样完全一样,对吧,我们不能说先得到一个走样的结果,再在最后的走样结果上面做一个模糊,不是这么做,这个意思,好。
然后它也不是再去filter这个shadowmap,你filter shadowmap什么意思,咱们之前说过,filter就是等于模糊,对吧,咱们在GAMES101里面提过,那么shadowmap原本。
大家还记得刚刚给大家展示过,对吧,从那light出发,我看到的那么一个带深度的一个东西,它有着明显锐利的边界,对于这些球什么的,对吧,那我如果把这张图给糊了的话,我就问,在在这个球的边界,这个这一圈。
它可不是被糊掉了吗,对那个地方它表示了什么,它深度竟然表示了一种平均,对吧,它肯定是背景和这个球的边界,这个位置上,它的中间的一些什么,平均的一些深度,这个东西毫无物理意义,对不对。
然后我得到了一个平均的深度,我再用这个深度去做,其他的深度测试,对吧,我在做第二个pass的时候,我有任何一个shading point,我和那么一种模糊了的深度,做一个深度测试,得到的结果。
还是非零集一的,对吧,所以说那是不是等于说,我什么都没做,对不对,所以说它也不是去filter shadowmap,这就是他所做的,这么两个事情,咱们先说清楚,filtering第一。
不是对最后已经有聚成阴影,进行filter,第二,它不是对shadowmap进行filter,这么个意思,那么他做了件什么事,我们就先从他的做法上,然后跟大家来说一说,他是怎么做的,它是这么一个意思。
就是说,我之前在做阴影,或者就是任何一个点,在不在阴影里,这么一个判断的时候,我怎么做的,把shading point,连向light,我来跟shadowmap上,对应的这点来做比较,深度进行比较。
对不对,我做几次比较,一次,是不是,这里面它做的一个区别是什么,就是说我对于shading point,我还是要看,它是不是落在了阴影里,但是我把它投影到light之后,我不是去找它对应的,那一个像素。
我去找shadowmap上,它对应的投影出来,找的方向对应的像素,也就是大家看这蓝点,这就是他原本该找的这么个像素,他不只找这个像素,他在shadowmap上,找他们周围一圈的像素,比如说找个7x7。
好吧,找个7x7,他把这7x7里面每一个像素,这不是shadowmap,每一个像素,是不是都有个深度,对不对,他把每一个深度,都跟我实际的这个点,shading point,它的深度,去做一个比较。
做完了比较之后,然后我在把这些做完的比较的值,都给平均起来,大家知道我每次做一个比较,我得到的结果,只是非零及一,对不对,就是这么个意思,那么大家可以看这样一个例子,这个例子是一个简化了的例子。
咱们假设这有一个point p,这个点p,然后我原本投影到light上面去,我知道shadowmap上,它对应这么一个点,但是我不只看这个点,我看周围一个3x3的一个区域,大家实际平常中不会用那么小。
就是说3x3是为了这里,给大家解释一下,比如说3x3这么一个区域,它有9个像素,对不对,9个像素,每一个像素都是shadowmap上的像素,所以都有深度,对吧,我跟shading point的深度。
我做一个比较,我肯定会得到要么1,要么0的值,对吧,要么能看见,就是挡得住,挡不住,对吧,要么是看不见,那也就是说,light看不到它,那意思就是挡住了,对吧,那要么1 0,就是1,像这得出来结果。
比如1 0 1 1 1 1 0,得到9个数,得到9个数之后怎么办,我取一个平均值,我取个平均值之后,我就知道这一点,它的一个,最后我得到了这么一个,所谓visibility,这么一个值。
它不再是一个非零集一的数了,它是一个介于0到1之间的一个数,好吧,有同学问是不是要加权,可以加权,没问题,可以加权,那么大家看到这里面做了一件什么事,这里咱们说清楚,它filter的是什么。
它过滤的是什么,或者它平均的是什么,它平均的是任意一个shading point,做的很多次不同的阴影的比较,的一个结果,对吗,是这么个意思,然后所以说,它既不是对最后有据耻的,那么样图做一个模糊。
最后现场出来的结果,也不是对shadow map做一个,模糊操作,shadow map还是这样的,大家看到没问题,它是对shadow map上面一个区域,那每一个点。
都和shading point比较了,是不是遮挡这么一个结果,做一个所谓的filter,很有意思的事情。
那么这里就是一个例子了,就是说如果你真的就对,所谓有据耻的阴影,这么一个结果上面做一个filter,是一点用也没有的,对吧,这跟咱们之前所说的抗据耻,一个道理,如果能这么做的话,咱们之前就不用讲那么多。
这就像腰上的氪了,对吧,这个意思,好。
这就是percentage closer,说起来,大家还没看到效果,对吧,大家可以看到这里,大家可以看到阴影,这里就不再有什么据耻,这说的对吧,当然这里的具体参数,我不太清楚,另外这个车是标准的。
NVIDIA他们早期很喜欢用的一个例子,就是这小车,因为它非常复杂,大家可以看到,各种各样的这些不同的结构,投影出来阴影都混在一块,然后这里大家会发现,如果你不做PCF,对吧。
不做percentage closer filtering,那你得到的结果,肯定是有据耻的,那特别是在什么地方,在比较远的地方,对不对,然后你会看到有据耻,但是这样一做,它就没有据耻了,没有据耻了。
至于它用了多少,7乘7,还是9乘9,还是多少,不知道,对吧,然后但是不管怎么样,它就是这么做的,然后大家可以看到,这个结果非常不错,对吧,不过话说回来,对,有同学已经问了,对吧,有同学已经问了。
这得多大开销,是不是,比如说我原本一个shading point,我只需要取shadowmap上的一个像素,也就是说,我要查一次texture,对不对,查一次shadowmap对应的texture。
这个位置上,然后现在我不要查一次了,我要查多少,我要查七七四十九次,对吗,或者九九八十一次,对吧,就像这种情况,这种情况,每一个shading point,我都要这么去计算,这还得了,对不对。
所以说它会非常慢的,对吧,但是没关系,然后具体怎么样继续解决,咱们会放在PCSS里面一块讲,就是这么个意思,但不管怎么样,首先大家咱们都可以接受,说这么做肯定是可以的,对吧,它会很慢,但是肯定是可以的。
对,那么没问题,咱们就开始下一步,下一步,就是有人在这个中间,就会看到一些事情,还是刚才那车子,刚才那车子的话,我如果用一个比较小的filter size,我要真的取一个,比如说,极端的情况下。
一乘一等于什么也没做,对吧,那就一点锯齿也没有,但是它看起来很锐利,对吧,然后不是一点锯齿也没有,一点抗锯齿都没做,这么个意思,如果我取一个非常大的,比如说九乘九或者更大,比如十七乘十七,像这种大小。
这种大小的情况下,我肯定最后阴影的锯齿都没了,但阴影也糊了,是不是这意思,对吧,所以说像这种情况下,我要怎么办,它不是一个,怎么说,就是取决于你filter多大,然后它会让阴影。
出现硬或者软的不同表现吗,是不是这个意思,也就相当于是,你的filter的区域的大小,它就决定了阴影,是不是硬还是软,这是非常有意思的一件事情,就是说,于是就有人想到说,那软阴影,我是不是可以理解成。
就是硬阴影,我做一个非常大的,一个这边filter,然后我是不是就可以得到软阴影了,答案是是的,就是这么回事,然后所以说人们,就是说我们在学,实时渲染的过程中,也要着重去体会这个事情,对吧。
人们是非常聪明的,人们看到PCF,它有这么一个问题,对吧,你本来是一个,我需要去调一个参数,使得它看起来比较好,但是偏偏就有人发现,这个参数,如果我取得很小,跟取得很大,特别是取得很大的时候。
我可以用它来去近似一些,类似软阴影的一个效果,那就非常好,对吧,然后所以说,沿着这么一个思路,咱们往后去思考,我先生成硬阴影,然后我在不同的位置上,我能不能给它一个,某一种filter。
把它给变成软阴影,对吧,我应该给它多大的filter,然后让它多软,是不是这意思,然后是不是各个不同的位置上,我都要给它一个相同大小的filter,或者说软阴影的程度,各处都是一样软的,那答案是不是。
人们发现了这么一个事情,特别是咱们看这幅图,这幅图,我非常喜欢的一个例子,大家可以看到这个钢笔,它在写字,然后它投射出来一个,非常明显的一个软阴影,大家可以看到,对吧,然后这里面,大家可以看到一个事情。
我问阴影在什么地方,它是硬的,什么时候它是软的,咱们在Games 101,其实已经提过了这么一件事情,对吧,大家可以看到在笔尖的地方,这里它非常锐利,它就很像是硬阴影了,已经,那么在远的地方。
它就会变得非常虚,对吧,这个意思,我们想一想,我们刚才说近和远,说谁,对吧,我们肯定是说,这个阴影它所在的位置,也就是纸上,对吧,阴影的接收物的某个位置,到阴影的投射物,也就是笔的某个位置,上面。
它的距离是近还是远,是不是,咱们这么想一想,是不是这么个道理,就比如说我那笔尖,为什么,因为它投射出笔尖那里的阴影的部分,就是笔尖的部分,那个笔尖离阴影它非常近,是不是,所以它就非常。
它就应该filter的,叫什么,它就非常硬,然后远处也是一样,那个阴影是由谁投出来的,是由笔杆投出来的,所以笔杆和你的,这叫什么,就是阴影的部分,这块距离它离得远,OK,所以有同学说。
是不是和公园距离有关,不是,是和遮挡物的距离有关,这么个意思,大家再仔细想想,是不是这么个意思,对吧,我们说远和近,咱们得讲个道理,到底是谁跟谁的距离远还是近,对吧,这么个意思,好勒。
那么这就是说大家的一个,非常有用的一个观察,那么这个观察就告诉了我们,好,那么如果我想做一个软阴影的效果,我应该给这个硬阴影的,各处不同的位置上,有一个不同大小的filter,对吧。
不同大小的filter size,就是这么个意思,那么我这个filter size,应该是和谁有关系,应该是所谓,咱们定义一个距离,叫blocker distance,所谓遮挡物和阴影的接收物。
这么一个距离,这个意思,好,那么一个更准确的说法叫什么,就是说,咱们说清楚,一个相对的,平均的,投射的,遮挡物的深度,这么个意思。
那怎么理解,咱们看这幅图,这是也是经典的PCSS的一个图,那么什么意思,大家可以看到这里,这里有一个light,对吧,大家看到在上面,右上方的一个,黄颜色的一个线段,然后这里就表示一个light。
然后中间假如说有一个叫做,blocker的一个东西,然后底下这是你的阴影的接收的平面,那么我们会看到说,一个light,然后和blocker的某一个位置,然后我如果连到接收物,大家会发现有一个很明显的。
一个相似三角形的一个关系,对不对,是吧,OK,然后大家就可以看到这么一个关系,什么,就是说我一个阴影,它是它的软的什么程度,是不是就是类似w这么一个范围,对吧,w这个范围,不就是所谓阴影。
到底软还是不软,比如说我们如果有一个点光源,大家可以看到这么一个相似三角形,我还是指出来,这里light也看到这里,然后假如说这个blocker是一个点在这里,然后它在这里面会有一个相似三角形过来。
它有一个这么大的一个宽度,这么个意思,然后如果说大家想,这light是一个点光源,那到这里也是个点,那任意一个,就是所有的这些阴影过来,它都不会有一个,某一个什么filter的一个大小。
如果light非常大,当然这里的大小对应的投影到平面上,这么一个大小也就会非常大,也就告诉你,这个阴影应该filter的更大一些,是不是这意思,然后同样道理,大家可以看,这样一个相似三角形。
也可以解释这么一个问题,如果说我把blocker,就所谓阴影遮挡物给拿的非常近,拿的更靠近接收物,就是平面了,那会发生什么,那会发生还是根据相似三角形,你会发现如果light的距离大小不变。
然后我的block的位置,它更接近接收的平面,我会发现它相似三角形对过来之后,这块的范围还是要更小,是不是这意思,没问题吧,所以说 blocker的距离,它会非常影响这么一个小的范围,这个小的范围。
我们就认为所谓半影范围,或者说我们要filter的范围,没问题,同样道理,如果你把blocker给拿高,blocker拿高的话,就和light非常近,和light非常近,和接收物非常远。
你会发现底下投射出来,对应的相似三角形,告诉你这段是不是非常大,对吧,告诉你非常大的情况下,你这时候就意味着,你这里要filter的更大,也就是阴影会更软,没有问题,和我们刚才的观察是完全一样的。
那么现在咱们就来看,对于刚才所说的这么一些分析来说,这相似三角形,能不能用数学的形式来描述,对,刚才有同学问,w越大越软,对,就是这么个意思,这个w一定程度上,就可以表示阴影的软的程度。
咱们刚才分析的就是这么个意思,对吧,那么它要怎么算呢,就比如说它肯定跟light的大小有关,咱们刚才说了,对吧,然后,它肯定又跟blocker的,和light或者说,和receiver的相对距离有关。
对吧,然后这么个意思,那么它们之间什么个关系,自然根据相似三角形,light的大小,比上你要filter的大小,这里大小,等于什么,就得等于是,等于什么,等于light到receiver的距离,减去。
blocker到receiver的距离,然后也就是相当于是这段距离,去比上底下这段距离,没错吧,就这段绿色的距离是谁,是dblocker,就是绿色这段,blocker的,到light的距离。
叫dblocker,这里它的这个式子写的很奇怪,它干嘛要跟light比垂直距离,但没关系,就这段绿线,比上蓝线减绿线,没错吧,咱们这样说,蓝线不是整个的长度吗,对吧,蓝线减绿线就是底下这个长度。
所以绿线比上底下这长度,那就是light比上well filter的大小,对吧,这就很明白了,ok,那么不管他最后用的这些距离,表示的到底是距离light的,还是距离receiver的。
只要这张图能够理解,之后计算箱三角形挺容易的事情。
好吧,这么个意思,好勒,这就是所谓,PCSS我们分析对吧,我们刚才说到哪了,我们要算的就是一个最重要的概念,就是该filter多大,那么该filter多大,就取决于light的size,对吧。
light本身的大小,假设咱们知道,那么也取决于所谓blocker的距离,那么blocker,他也许他不是像刚才就是那么个点,或者就那么一条线,他blocker可能中间是个球,或者一个什么东西,对吧。
他可能有很多不同的这些东西都有可能,比如说刚才的笔感也是,笔感它有一定深度区别的,对不对,然后他肯定会有一定的范围,所以说我们平常考虑的所谓blocker depth。
指的是所谓average blocker depth,意思就是什么,咱们翻译一下,就是说对于一个shading point来说,然后我要看在一定的范围内,有多少这些能够挡住他的。
在shadow map上记录的这些像素,这些像素记录的深度的平均值都是什么,对吧,是这么一个意思,所谓average blocker depth,好,那么这样一来。
人们就可以用percentage closer filtering,也就是PCF的思想,用在percentage closer shadow上面去,OK,那就是说把这个PCSS的算法,就可以做出来了。
那么核心咱们刚才说了,按照这个逻辑来,我得知道要各处filter要filter多大,为了知道各处filter多大,我得知道blocker到我这shading point的,距离大概是多少,对吧。
那么我肯定得这么做,我第一步我就在任何一个shading point,然后我还是一样,按刚才的shadow map的做法,我连向light的,这里中间我忽略了一个事情,就是这样,对于面光源来说。
你原本是不可能生成一个shadow map的,这个意思,然后正常情况下,人们所说,为了去模拟面光源的软阴影,它其实就相当于是,用一个点光源的方式,来生成一个shadow map,就意思就是说。
我可以认为说,我把camera放在light的中间,我看向一个场景,然后生成一张shadow map,就是这么个意思,那么咱们回到这一步来,PCSS第一步干什么,从shading point。
然后我连向点光源,然后我找到一个点,我取周围的某一个区域,我来判断,还是一样,像刚才判断,是不是在阴影里,如果说我判断说,它在阴影里,就意味着,那个像素,我找到的像素,它就一定是一个blocker。
我把它的记下来,然后我把所有的这些都走一遍,对吧,我把所有的blocker的深度,都给记下来,然后我取一个平均,如果说我取的那些,shadow map上的这些像素,它本身并不能遮挡住这个物体,那没关系。
咱们不考虑它,对吧,它不是blocker的深度了,我们要考虑的是,平均的blocker的深度,对不对,好,第一步就做这么一件事,第二步,第三步是没有任何这些特殊之处的,相比于PCS来说,它就完全一样了。
相当于是,为什么,因为第一步,你既然知道了,所谓blocker的距离,你就可以去计算,一个filter多大,这么一个范围,你既然知道各处filter多大,那不就跟之前的,PCF做的完全一样,是不是。
哈哈,这么个意思,对吧,好,所以说这就是PCSS的一个思想,就是人们在无意中,PCF的这么一个,一个问题中,发现了一个,还能解决另外一个问题的方法,非常不错的事情,那么这里面,大家肯定会注意到。
我这里面标注了一个事情,就是说所谓我在第一步,所谓做blocker search的时候,我应该在一个多大范围内,去做search,这不是一个机生蛋,诞生机的问题吗,大家听我说这么一个逻辑。
在shading point,我原本就是为了决定,我应该在一个shadow map,它周围的多少范围,不是7成机,还是9成机,有多大的一个范围内做PCF,对吧,我为了知道这个信息,我就首先得知道。
Average blocker depth是多少,我要知道Average blocker depth是多少,我也得先取一个区域,最起码,对吧,取一个某一个区域,我要找它的Average blocker。
再把它们depth平均起来,是这个意思,这一步我就已经是需要一个范围去找了,对吧,这个范围取多大,平常人们会认为两种方法都可以,第一我取一个,某一个,某一个什么,某一个固定大小的范围,比如说就5*5。
好吧,然后还有一个更好的方法,什么更好的方法。
那就是这里,大家看这幅图,大家会看到说,对于这幅图来说,你看到了一个shading point,可不是吗,你在这shading point里面,你想要去找shadow map上的某一个区域。
在第一步用来做,Occluder或者说,Blocker depth estimation,对吧,你要去估计这个范围内,也就是红色的这么个区域里面,所有的能挡住shading point的这些点。
它们对应的深度的平均是多少,对吧,你想做这么一个事情,那么现在问题就是红色的区域取多大,不过这里,这张图,它就给了你一个非常不错的,一个启发式的方法,什么方法,你就认为说,这个shadow map。
假如说我之前,我说我就把light当点光源,在light中心,然后看向这个场景,你肯定得设置一个所谓的,视坠对吗,凭接头体还记得吗,near plane,far plane,对吧,近平面远平面。
我就认为,这shadow map是放在某个位置的,假如就在近平面上,好吧,然后我现在在这一步里面,我要是我要想确定,我在一个多大的范围内里面,做所谓blocker search。
那我就在这个shading point,我连向light,我来看,它在shadow map上,覆盖了一个多大区域,这是非常有道理的一件事情,因为比如说light离你非常远,离你非常远的时候。
你本来你就一开始就可以,找这些所谓的,blocker,你肯定就是说会找,在你的shading point,和light形成的这么一个锥里面,对吧,这些地方你才要找,也就意味着。
如果light离你非常远的话,你其实在shadow map上,应该找一个比较小的范围,去找它的所谓blocker,然后如果说light离得比较近,那就说明你应该在一个,相对比较大的一个范围。
或者light比较大的情况下,对吧,你应该在一个更大一点的范围内,去找哪些是blocker,并且他们的这些平均的,这些大小都是多少,深度都是多少,这么个意思,好吧,这样的话,我们就相对圆满的解决了。
这么一个,这个机生弹诞生机的问题,对吧,咱们回顾一下,在任何一个shading point,我们通过这种方式,可以找到,我在shadow map上的,某一片区域里,我应该去找哪些像素,可能遮挡这个点。
对吧,哪些像素,可能遮挡这个点,并且这样的像素,就被制成所谓的blocker,然后我把他们的深度,全部都平均起来,如果说你遇到了像素,不能遮挡这个点,咱们不管它,因为他们并不是blocker。
然后我把所有的blocker的,平均的位置,或者深度都记录下来之后,我就可以用咱们前面的公式,去给我们一个,对于硬阴影,应该去filter多大,这么一个信息,那么既然知道这个信息之后。
问题完全转化成PCS问题,对吧,好嘞,那么这里大家会看到,什么问题,有同学正好说了,对吧,开销是非常恐怖的,这是真的,没问题,大家想一想,我在做blocker search的时候。
我是不是要对这个范围里面的,所有的text都要考虑一遍,对吧,我要有那么多访问,访问这个文理的次数,在这摆着,对吧,然后这步完成了之后,我在PCS里面还是一样的,我在PCS里面。
我算是得到了一个PCS对应的范围了,对应这个范围,我还得做PCS,对这个范围里面的这些,text,我又都得走一遍,是不是,所以说这是一个非常慢的一个过程,对吧,这要怎么办,所以说这里就是工业界。
提供了各种各样不同的方法,咱们留到下一节可能说,好吧,然后,但是基本上思路就是这样的,这是没有问题的,然后这就是percentage closer soft shadows,就是用PCF去做。
run in叫PCSS,行。
这样一来,我们就差不多就说完了,咱们今天的内容,最后给大家看一个例子,这是什么,这个场景是,dying light这个游戏里面的一个场景,然后完了,dying light的中文翻译叫什么来着。
真的就消失了光芒吗,我忘了,是这么回事,就是说我个人,平常个人喜好,我不太喜欢,不太喜欢第一人称加开放世界,我说清楚,不是不喜欢第一人称,也不是不喜欢开放世界,我自己不喜欢第一人称。
和开放世界结合在一块,结合在一块,也因此我错过了很多好游戏,我知道dying light是一个神作,非常好的游戏,然后我也知道,比如说像辐射,什么fire cry,什么上古卷轴这些,就是第一人称。
开放世界有很多好游戏,我就是打不下去,个人喜好,但是不耽误,不耽误什么,不耽误,咱们看它的效果,做得非常好的,没什么问题,大家可以看这里,这里大家可以看到这么些树,这些树很明显。
它是很符合咱们刚才所说的,这么一个阴影的性质的,对吧,在这个树根,它离地面比较近的情况下,它这里基本上就filter了少,然后在这些树叶,大家知道这些阴影,如果从树叶投射下来的话,对吧,这种情况下。
它的所谓blocker depth是有多大,对吧,这个算出来之后,就告诉大家,这块应该filter的非常大,所以说这就会造成说,树叶投影出来的这些阴影,就会非常软,这就非常好,对不对。
大家可以看一看这些,这个效果就非常不错,对吧,所以说,这也是为什么说,percentage closer soft shadows,它会广泛应用,在实时渲染里面,这么一个理由,当然了。
大家还是有这个疑问,对吧,它照刚才咱们说这个算法,这么慢,这么慢,怎么会,怎么会,还会被用到实时里面,那答案是,大家之后会有办法,能够让它变得快,咱们下节课开始说,这节课咱们就说到这,好吧,这是,行。
目前为止,这样我先停一下,我来看看有同学有什么问题吗,这样大家一边说着问题,一边我来,我要说一下,咱们下节课讲什么,咱们下节会会课,会给大家讲滤波的基本知识,那大家从这个上面来看,标题上面来看。
基本上就会明白了,对吧,大家会通过一些,减少采样的数字,并且增加,一个额外的一个滤波的一个方式,然后把这些,把速度提上去,并且让它没有什么这些,噪声,这么个意思,然后后面我们会给大家说一些。
其他的一些方法,特别是什么,特别是variance subshadow mapping,这一个新的产生软阴影的方法,然后又不用这么采样的,然后还有一个,就是。
之后的这些moment shadow mapping,咱们看时间,好吧,有同学问多光源怎么处理,问得非常好,咱们之前一直忽略这么一个问题,多光源只能,如果说你用shadow mapping的方法。
目前来说是只能一个一个处理的,也就是说,你如果有n个光源的话,它的速度就会降到n之一,这是真的,就你得要n个shadow map,并且你在每一个shading point,你要对每一个light。
做一个shading,但是这中间,它是有很多,文章可以做的,就比如说,咱们下节课,开头提到filtering,既然提到,那就肯定中间是要采样,既然提到采样,我相信同学,你已经可以想到一些什么方法,可以。
可以考虑,可以不去,把所有的这些light,都给处理一遍,对不对,哈哈哈哈,对吧,就是真的,多光源确实不好处理,就是说,这也是为什么,大家看到平常游戏里面,基本上来说,很少会用很多的光源,大家看到。
即便是大家用环境光照,去照亮一个整个场景,然后大家会看到,比如说主人公身上,还是只会有一个,非常主要的阴影出现,其他的阴影,咱们就忽略不计了,通常都会这么处理,ok,好,然后有同学问,我说的积分的近似。
有推荐阅读材料吗,没有,真的没有,这些都是算是学术界,大家在主要用的一些东西,我做一个总结,这个意思,ok,点光源和directional,怎么做pcs,这些同学前提不对,前提不对。
点光源和directional,本身,他们就应该产生硬阴影,他们干嘛要pcss,ss不是软阴影,对吧,运动物体没关系,就是说shadow mapping的一个好处,就是说你任何一帧,你知道那个物体在哪。
它反正阴影都是重新算的,对吧,shadow map也是重新算的,然后真正阴影也是重新算的,也就是说,跟运动的物体没有关系,好吧,ok,好吧,那会有走样,什么会有走样,没听明白,有同学问我。
4月初的出差能不能不录播,然后之后推迟,是吧,是这样,我先说一下,这怎么办,就是说我其实挺想录播的,为什么,是因为我,如果说真的往后拖一周的话,我们这课的截课时间,很可能会和siggraphasia的。
截稿时间冲突,到时候我怕我忙不过来,忙不过来的话,到时候还影响课程质量,对吧,我这么想的,就是说,这样再给我点时间,我想想,好吧,就是说,我觉得录播还好吧,行,之后要是还有什么问题的话。
我可以比如说再之后我回来,然后我再早一点来,早来个15分钟,20分钟这样,对吧,但有问题,我们都可以再讨论,对吧,好吧,ok,所以有同学说PCSS的核心,就是一个适应性的filter size,太对了。
说的非常对,很好,课后的大一,有同学问到说,我能不能有课后的大一,我得看时间,同学,我这确实是,最近超级忙,我也,我也不想,但是好像没什么特别多办法,大家尽量先在群里面,或者是BBS里面问。
我们的助教同学是非常厉害的,应该有绝大多数问题,都可以回答,如果回答不了的话,我也会让他们收集上来,然后我到时候会看,好吧,这么来安排,ok,所以这位同学说的,其实是我应该有一个office hour。
对吧,这个意思,我该有,确实该有,但是,真的同学们,忙的不可开交了,这件事情,哎,行吧,我是先这么着,咱们,这就差不多了,这节课,工业界的图形学技术,哪能学到工业界,真的,在学术界。
你是学不到工业界的东西的,大家不知道,我这边为了学这些工业界知识,和很多朋友,我们都也讨论过,就是这些东西,中间是挺割裂的,咱们头一节课说的,对吧,哈哈哈哈,行吧,同学们,这是今天算是跟大家。
说一些比较困难一点的东西,稍微困难一点,这是真的,花点时间好好看一看,下节课也得不那么容易,但是不管怎么样,这就算是平常,咱们说实时现场的一些难度了,好吧,其实还好,对吧,ok。
好嘞,咱们今天就讲到这儿,然后我就下播了,好吧,来看看,ok,行,我就这样了,谢谢各位同学大力支持,咱们今天到这儿,然后咱们大家周六见,拜拜,謝謝您的觀看。
GAMES202-高质量实时渲染 - P4:Lecture4 Real-time Shadows 2 - GAMES-Webinar - BV1YK4y1T7yY
好的各位亲爱的同学们,然后今天呢,我们会尽量把跟这些实时的阴影相关,的话题给说完啊,这么个意思,那么还是一样呃,在课程正式开始之前,我们先说一个事儿,什么呢,就是我们的作业一,我们作业一。
我们的助教同学们正在积极的筹备中,然后还需要一点点时间,请大家稍微耐心一点,好吧啊,然后呃尽量今天国内的今天可以呃,呃可以发布,如果不行的话,那就是明天了,好吧啊,然后正常情况下呢,我们这几次作业。
应该每一次作业都有1。5个星期,就按十天来算吧,差不多是有那么长时间可以做的,应该是没有问题的好吧,那么作业一虽然还没有发布,但这里已经有一位大佬同学已经哈哈哈呃,这自己把它给实现出来了,我的天。
这实在是非常夸张的一件事情啊,啊我们这个好好表扬一下maxwell同学,听一下这名字,max思维就非常厉害对吧,ok啊大佬工业界大佬啊,非常厉害,然后大家看这个渲染的效果非常的好啊。
然后大家可以看到这些阴影对吧,特别是202酱的手投影出来的这个阴影,这是很明显的软阴影对吧,然后呢,右边我和我一位朋友来聊着这样一个结果,然后他告诉我说,他以为这是这是照片,他以为这是我新买的手办。
他觉得这个做得非常和谐,然后说我这个呃教教实时的,这做的已经非常像离线了啊,非常好,然后说这位确实是大了,那么这是谁评论的呢,那当然这是另一位大佬,这就是传说中的文刀秋二。
哈哈这是edward流啊啊dlss的创始人之一吧,啊nvidia的超级大佬啊,大家可以看到啊,他都对这么一个结果做出了这么高的评价啊,非常好啊,提出表扬是这样啊,我这正好趁这个事情我多多说一句。
多说一句什么呢,然后我知道max well大佬是在在工业界的,然后就是工业界,大家可以从这幅图就可以看到,有着极其强大的工程知识动手能力,对不对,然后呢呃学术界这边呢,当然大家之后再上这门课。
或者是反正对学术界的正常理解吧,完整的知识体系与解决新问题,甚至发现新问题的研究能力,那会是一个非常相得益彰的事情啊,这更进一步印证的说确实没有问题啊,然后咱们这个课上把这个科学给说清楚。
然后技术上大家可以继续呃,然后把这个呃之后的技术都给锻炼好啊,非常好好的,那这就是咱们这课前表扬。
ok那么这节课呢啊,我原本说我砍掉了一些内容哈,但这一次呃突然今天发生了一些意外的事件啊,然后导致说我们这节课呢,有很多东西需要跟大家去讨论,那是什么事儿呢,唉这里大家可以猜一猜对吧哈,好吧啊。
不过没关系吧,我来说啊是这么回事,正常情况下呢,呃作为图形学上这所谓最高级别的会议哈,大家都知道叫srah ciraph的投稿时间是1月底,然后出review的时间是3月初,然后出结果的时间是3月底。
那么今天正好赶上他出结果,然后呢,我呃之前上个月这个时候就已经坐不住了,我想着哎review要出了嘛,然后我就觉得非常的这个坐立不安,于是我就去看节目啊,看各种各样的节目,于是我就去看了星际的一场比赛。
大家可以看到这是马路对solar的比赛,然后如果有同学看过的话呢,哈哈哈大家就会发现啊,为什么呢,是因为在这场比赛中,老仙又发功了哈哈,然后他再这幅截图的前一秒说了六个字,不可能中的呀哈哈。
然后大家的下一秒就可以看到这个sa的大部队,被马入的原子弹给打中了,诶好吧,于是呢诶当时呃我这看了之后,我觉得好嗯嗯这回sirrah应该是稳了,因为他说不可能中的,对不对,所以呢今天得到了好消息。
那么那么在这次的craft中,就我和合作伙伴嘛,然后总共有四篇paper被收录到siggraph 2021中,好吧嗯然后这里特别感谢呃,我的是全明星的同学们和合作伙伴们啊,非常感谢大家。
然后呢呃作为四篇paper的话,在渲染领域哈,今年很有可能就是今年siggraph最多的paper了,因为每1年siggraph渲染的paper非常少嘛,十篇出头吧,然后如果有四篇的话。
那应该是呃最多了好吧,然后呢由于这四篇siggraph呃中了,然后这同时造成了一个事情,那就是我的职业生涯中cirh呃,这个期刊啊,这些都是就是最顶级的了啊,加起来论文已经达到了20篇啊。
然后这是一个非常里程碑的一件事情啊,是这样啊,就是说啊咱们的不同领域不应该呢过去呃,各种各样的去比较啊,甚至子领域,就是说大家平常很难见到,说我去跟比如说什么呃simulation啊,或者是做几何的呀。
就是都是空军学内部,咱们说谁siggraph paper多,因为这个领域是相差的特别多,那么20篇呃rendering的paper,那算是非常多了,呃到一个什么程度了呢。
但我觉得吧如果我现在跟我的系主任说,我要退休,应该是可以的啊,这个意思好吧,嗯然后差不多是这么个意思啊,这就是说一下啊,炫耀一下,当然我今天非常高兴,然后我才会这么说。
大家知道我平常还是店里稍微低调一点啊,这个意思行吧,嗯然后呢嗯借这个机会呢跟大家说一说,这这这这个事儿对吧,就是关于siggraph嗯,大家有同学会说我不是已经有很多的paper了吗。
干嘛还要发那么多paper呢,那这里是一个我很想跟大家探讨的一个问题,好吧,那这这怎么说呢,就是说学术上大家平常都会关注一个啊,这个所谓数量跟质量,就是多还是基因这么一个呃权衡嘛。
这么个意思就是说有不同的啊组研究的组,不同的人不同的方向啊,大家都选择了不同的这些这些啊,这些嗯怎么说呢,方式去推动他们各自的这些科研,我自己当然也是这样,不过呢咱们从第一节课啊。
咱们从这门课的第一节课,应该跟大家说了一下这个事儿对吧啊,嗯什么呢,就是说呃实时现场对吧,我们要做到什么呢,我们要做到高质量,我们也希望他能够能够快,我们不希望权衡,我们希望我全都要对吗。
那么在这个啊科研很少,唉我其实胃口是非常大的对吧,就是说我是希望说又可以有多的paper,又可以把他们都给做得好,那这当然是目标了,是这么个意思,那么为什么我一定要这么做呢。
这其实是一个很心酸的一个背后的一件事情呢,啊那么这这这这啊说来是这样哈,就是说我在博士毕业的时候,然后当时呢我人还在berkeley啊,我和berkeley的任ng老师啊,大家还记得他对吧。
说了他好多次了,呃,和他探讨过很多,这些我要怎么样找工作的这么一个事情啊,就是在学术界转一圈,我应该怎么样去好好去面试啊,或者干什么,然后呢他当时跟我说一个事情啊。
当时算是第一个人跟我呃好好说的这么一个啊,一定是需要注意的一个事情啊,很有哲理的一个事情,什么呢,原话我不记得了,但是我可以简单说一下,嗯大概是这么个意思啊。
lji you’re not just going to sell yourself,as a superstar,you’re also going to sell the sports。
ok大家能听得明白这个意思吧,就是说你如果去找工作,你要做的事情不只是说把自己给推出去,作为一个超级巨星这么一个意思哈,你还得把你所做的这项工作也得把它给说出去,让别人能够接受,言下之意。
就是大家都知道rendering这个领域是非常难的,它难在很多不同的方面,它难在首先idea非常的难想,很多人就会说rendering呢这个领域大概做不动了,这么个意思。
很多的这些这些想法呢都之前都被解决掉了,或者是剩下来的都是很难的想法,那么我的一个嗯嗯感觉就是什么呢,一方面说的是对的,另一方面我不希望承认这个事情对吧,我有我自己自负的地方,这是没有问题的。
ok然后这里呢就是说嗯,嗯就是说不管在呃之前找工作吧,这些所谓cd sport的这么一个工作,所以从这个角度上来说呢,就是说哎确实从发paper的角度上来说,又得发很多的paper。
然后呢又得把这些paper的质量给做好,然后这样的话才能为别人所承认,才能让别人认为说,或者说给热爱rendering的同学们,老师们提供一个信号,说rendering还是有东西可以做的。
然后我虽不才对吧,但是这是我希望能够带给大家的一件事情好吧,那么哎我之前说我平常没事看一看nba对吧,然后大家知道我最喜欢的球星是谁吗,他是呃就是库里啊,然后就是说哎为什么我喜欢他呢。
因为一定程度上有很多东西是挺相似的对吧,大家知道库里呢,他作为一个nba的球星,他是没少啊,这是呵呵很严重的一个事情,然后呢如果他希望联盟能够认可自己的话,他就得投402个三分,他就得过了。
中场就顶着人头才会有人承认好吧,所以说一定程度上来说,然后希望能真正能够把rendering作为一个呃,呃非常不错的领域,然后这个嗯嗯带给大家rendering之后,更多的可能性吧,这么个意思好吧。
那简单跟大家说一说这背后的一个思想,就是说我又要做多又要做精,这是我一定要做到的事情,好吧好吧嗯就是这么一个事情了啊,ok啊简单说一说,这次因为这个sirh呢,然后想到了一些事跟大家分享一下。
大家不只是说从课也要学一些什么,这些基础知识,大家还得意识到说啊,这个呃各行各业工作都不太容易的,对吧啊,ok好嘞,咱们再回到刚才说的事,我说什么来着,我说我这啊,我因为这次sp了。
导致说我现在啊论文啊,这个系列的论文啊攒够到了20篇,那攒够了20篇到底有什么好事情呢,大家可以看到这是greater news,greater news是什么呢。
就是说我终于把我的ps four赎回来了,诶这是什么意思呢,啊那所以说跟大家简单说一说,我的这个故事啊,这么个意思,就是说呢,然后当时就买了,买了之后呢,哎这没打多少东西,打了些这个美国末日。
然后呢打了gta 5,然后就被领导给拿去了,家里领导哈,这这被领导拿去征用了,那这我就没办法了,那就那就给他了,然后我说那我什么时候才能把ps four赎回来呢,那领导就想问一下,领导告诉我说呃。
说等你攒够20天cig rap的时候,你就可以把它给赎回来了,然后那么今天就是这么一个历史性的时刻,哈哈我终于把ps four赎回来了好吧,然后我就可以嘿嘿嘿之后可以愉快的玩耍了。
这是非常开心的一件一件事情好吧,然后呢那肯定有同学会说这个意思,你为什么不给他买一个chrome cast,或者拿任何什么盒子,是不是这个意思吧对吧,然后呢那这么说的同学,那么非常抱歉。
看来你还没意识到你为什么单身,对不对,这领导做出的决定,你都可以质疑是吧,嘿嘿嘿嘿嘿嘿嘿诶好吧好吧好吧嗯,所以说呢就是呃这么个少啊,那么嗯哎呀还我那么那么在这之后呢,我当然还有下一步的目标。
下一步的目标是什么呢,也是领导给定好的,定好的是什么呢,就是哎我需要30篇啊,总共啊攒够30篇zoe,我就可以解锁ps 5啊,这是非常开心的一件事情,然后如果顺利的话,看看明年年底能不能完成这个任务。
如果不行的话,后年也可以啊,到时候嗯反正不区分pro,到时候也可以买,好吧啊,这么个事儿,到时候看30篇啊,希望能够做到,那么呃跟这个同时还有另外一个上,顺便跟大家说一说,就是说我在家里面。
大家可以看到我在games 101里面发了番外对吧,这个games 101做的就是就是就是弹段琴,然后现在再弹一个电子钢琴,然后我觉得我想换一个换一个真的钢琴,我就跟领导商量,哎我跟领导商量呢。
那领导领导说那行吧,你要是想换钢琴的话,那你就去你就去把激流给练了,哈哈是吧,然后我我说好啊,这个问题不大,但是我说我想换一个好点琴,我想换一个施坦威的琴,那领导想了想说,那不行。
那你就得把李斯特的钟给练好,然后我那行吧,所以说这就变成了我的下一步目标,那那那那我就练着呗,反正这个这个钟它不是一般人练的真的,然后他有个俗名叫我还能大跳,可能大家去随便看一看任何的什么视频。
大家就知道为什么会有这么个俗名了,好吧,夸张无比的唉行吧,不知道这跟30篇zh或者说ps 5,什么时候哪一个能够先到了再说吧好吧,反正就是说这是这么个事,ok嗯行吧,那这就是这一个更好的消息。
那么是这样哈,就是说我说今天呃就正好借这个机会吧,然后我顺便我一定要做一个广告呃,为什么要这么做呢,唉是因为生活所迫呀,没办法呀,我原本想着说我们找一个什么其他时间啊。
或者这课的最后能想着不趁着cirh这波,我顺便把这东西东西都给说完之后,就没什么机会了,对吧啊,哈哈哈哈好吧,然后呢嗯那这要我在说什么呢,我在说这个事儿,就是呃大家都知道了,这正常情况下。
不管看电视剧或者干什么,第二季要干什么呢,第二季肯定要用来植入广告,对不对,那所以说我在这个嗯第二节课上,我也植入一下广告,那么呃我是要干什么呢,是这样的哈,就是说啊说句非常现实的一个呃一句话哈。
就是说我现在呃这是非常非常缺银子的,那我缺银子是怎么回事,我说清楚,不是我个人缺银子,我说我缺银子,使,是没有这个对应的资金去支持我的博士生们啊,或者说去招更多的博士生们,这么个意思啊,不是个人的。
就是说嗯怎么回事呢,就是我被招到这边啊,呃来开始当这个所谓assistant professor之后,到目前为止,这个方定的是哎,就是这资金是非常非常非常呃怎么说呢,不成功的,这已经2年多了。
戏里面给的快要被我用完了,然后呢之后再没有更多的资金支持的话,就实在是养不了我的这些博士生梦啊,那我这些这些同学们就得被迫过去当助教,是不是非常惨的一件事情,对不对,所以说啊救救孩子。
这个我的工业界的伙伴们,真的我现在立刻马上真的就需要大家的支援啊,然后养一个博士生是非常非常非常便宜的,对工业界来说,真的每1年只需要5万刀左右啊,这么个意思,然后如果你有意向的话,然后请联系我。
然后嗯不管是通过什么样的形式,比如说大家可以看,通常呢工业界和这个嗯,和和和学术界的合作方式,最简单就是给学生发奖学金,然后或者说发所谓gift founding,直接发到戏里面。
然后呢或者是如果公司有一些跟rendering相关的,呃这些要求的话,然后又觉得我能力是可以的,那么我是非常开心,可以去给给大家当顾问的,那么国内呢这个合作与这边的合作是,几乎所有的公司都是可以的。
只有一个公司,you know who,我就不再说了,这是确实是不行的,这不怪我好吗,这真的不怪我,这确实不行,其他的公司都可以,欢迎联系我好吗,然后然后真的是这样,然后我希望能够用这个诶。
我的知识能够帮到大家一点,然后也希望大家能够帮到我一点,能够嗯让我能够比如说嘛招更多的学生,然后让学生们呢能够少做一些助教工作,能够更多地集中精力到呵这个科研中去好吗,然后至于我科研做的怎么样对吧。
这个没必要再说了对吧,好的那么呃一个立刻可以做的事情是什么呢,就是说这个siggraph呢,我既然知道刚刚有一些paper中了,那么paper中了之后有一个重要的事情就是要写。
致谢致谢里面呢大家可以看到啊,一个我之前写的致谢,就会把就会把啊日支持了这工作的啊,这些这些政府啊公司啊,写上名字啊,然后所以说如果你立刻联系我的话,是非常有希望可以感觉到你的。
大家可以知道我的这个不管怎么样,论文吧,他是肯定可以嗯有着不错的曝光度的对吧,然后论文呢这个东西是永久的,然后只要写在这里,那是很多年他都会一直在这里的对吧,然后所以说在这里呢可以出现贵公司的名字。
那我是非常开心的好吧,那我就说到这里,然后我另外说两件事,第一绝对不会通过任何个人的渠道,问大家收取任何费用,所以这课对同学们来说百分之百免费,绝对不会是任何问题的啊。
另外一点我需要的银子是给到戏里面的,并且写清楚是用来支援学生的,我一分都不要啊,我说清楚我自己不缺啊好吧,然后呢唉另外有同学说说老师,啊然后我跟同学们说是完全没问题,致谢就是用来做这个的。
我把你加上作者,那是绝对绝对绝对不可能的事情啊,就是说如果你给我银子,我是一定应该把你写到这个致谢里面去的,这是没有任何问题的对吧,并且我不止可以说这个对吧,以后有哎有人在问我说呀。
是您最喜欢的这什么呢,呃最喜欢的游戏角色是谁,我就我就不再说是a2 了对吧,我就说我是我最喜欢月清书对吧,鹿鸣对吧,唉这都可以呃,嗯800比丘尼,哈哈哈哈对啊,然后还能想到什么,反正很多吧啊没关系啊。
这么个意思啊啊行,对同学们来说没有任何的关系啊,是这个就是就是这么回事了,另外最后再说一句哈,那诶大家看到这个标题啊,food for thought啊,food for thought,其实是啊。
这里算是直接字面上用它了,然后呢嗯呃呃呃如果你还知道啊,food for thought alt曾经是一个密码,那恭喜你,你跟我一样年龄大了,哈哈哈哈哈哈好吧行吧行吧,那同学们今天我就说嘛。
我花点时间专门说一下这个事情,也是也是因为啊今天cirh非常开心,然后跟大家呃多讨论一些这些跟课程内容呃,不是特别相关的东西,但是呢有一点可以保证,绝对不会因此少了课程的内容哈,肯定是可以。
哈哈哈哈哈哈呃行吧啊,那咱们这就算是进入到这正常的课程中来了,好吧,那咱们上节课讲了什么呢,咱们上节课讲了shadow mapping的一些问题对吧,也基本做法,基本问题基本解决方式。
然后呢我们着重分析了一下,就是我随手写的一个什么样的一个一个公式啊,然后再在呃在呃整个实时渲染里面,大家是管这种方式叫做split sum,然后这块之后再给大家正式的引入,这么一个概念啊。
之后再说嗯然后呢给大家说到了啊,作为percentage closer soft shadow啊,这块基本上来说tcs s从tcf开始对吧,然后到这块各个不同的地方,应该飞不同大的这种大小的区域啊。
这块啊这么说清楚这个意思好,那差不多就是上节课说的这些内容,那么今天我们说什么呢,今天我们把这个啊pcf呃,和pcs s的这个内容在加强一下,我们在说的更加深入一点好吧,然后呢同时我们再引入呃。
这节课要讲的一个新话题叫variance soft shadow map,作为vs s m啊,当然也有人管它叫vance shadow mapping,叫vs m问题不大啊,这个意思好嘞,那嗯行吧。
嗯之后呢,在这在这个过程中,再跟大家说一下它的具体的一些实现方式,然后以及一个比它更高端一点的东西,叫moment shadow mapping,这样的话呢,我们差不多关于主流的阴影的技术就提到了。
然后嗯这节课肯定讲不到,那么下节课给大家多少提一下基于距离场的呃,关于shadow mapping的技术,好吧,我们这个意思行,那这样的话啊,我们就开始第一个话题啊。
咱们沿着之前上节课说的这个percentage,closer filtering对吧,大家看percentage closer filter做了什么事呢,大家还记得对吧。
那就是说对于我实际渲染的任何一个点,大家可以从这幅图里面看到x,这部x呢我知道它投影到对应的shadow map上,应该是哪个像素,只不过呢我不只考虑这么一个角色,我考虑一下周围的一圈这些像素。
甚至这些像素,它们的各自的贡献都可以加全的,它不一定是一个box,大家从这看可以有,比如说靠近这个p点的呃,他贡献多一点,远离他的少一点,没有关系,这属于取一个呃某种区域或者加权的区域。
那在这个区域里面的其他的这些点,他们各自也都会在shadowmap上,记录着他们之前记录的最小深度,然后用这个深度同样跟x它的实际深度去比,然后我来判断这整个区域内到底有多少啊,这些嗯这text对吧。
或者说fragment啊,挡住了这么个x这么一个点,对吧啊,然后这样一来呢,我就可以算出来,他们平均的这么一个visibility对吧,然后这样一来,我就可以把整个阴影给变得比较模糊。
而这个过程正是我们在数学上直接说的,叫做filter或者convolution这么一个过程,好吧啊,那么这里呢就是差不多就是说这么个意思啊,然后大家看这个看这个公式,这个公式呢就算是一种简写。
就是说如果我要对某一个函数,然后做一个convolution,我可以把它记住哦,用一个convolution w,然后打一个这个卷积,这个符号和f放在一块哦,把它定义成一个呃filter过来的。
或者卷积过了的函数啊,这么个意思,然后呢呃那他实际上做了什么事呢,实际上就是相当于啊对任意一个呃像素p,我都取它的周围的一圈啊,这这呃淋浴啊,就是大家看这个nt就是他的淋浴。
淋浴中间呢我去取一个啊嗯这个点点q啊,然后他的所有这些点q我都把它这么考虑下来,并且呢把这些所有的这些点q的值,然后按照根据啊,根据这个点q和点p,比如说他们之间的距离,然后做个加权。
然后我把它最后的值给呃,重新写回这个点p的值,那说白了就是我们在电子101之前曾经提过,对吧,就是filter嘛,它其实就是加权平均,也就是convolution,我们并不怎么特别去区分它。
那么在p c s s里面,我们到底做了一件什么事呢,那就是这样的,就是说我所谓filter的是什么,同学还记得吗,就是说对于任何一个神灵point x这里,然后呢我们都要去啊。
考虑他在shadow map上这个某一个位置对吧,考虑到某一个位置,它周围的一圈啊这么个意思,然后他在shadow map上对应,那就是x那投影到shadow map上变成点p。
那在点p的周围的一个区域,然后我们找它里面的这些所有这些点,考虑这些其他的点点q,任意一个点q是不是点q能够遮挡住x,那哪一个函数能够告诉我们,点q是不是能呃遮挡住呃这个x呢,哎那咱们就看这里就好了。
那么这里是指什么意思啊,大家看这呃,不管怎么样,它是一个经典的一个filter的这么一个过程对吧,它是一个这是全这右边那自然就是直喽,那这个值自然就是阴影比较的结果咯对吧,我们之前说呃。
我看这个点q能不能挡到x挡到的话,那这个visibility就是零嘛对吧,挡不到的话,visibility就是一嘛,所以这个函数它的值只有两个,对不对,只要么一要么是零,所以我们用这么一个函数。
这个叫做k啊,这个函数念法,他在这个ltg里面打法就叫杠c h i啊,他念作k k这个函数,我们我们定义这个函数,叫做一个所谓的符号函数,符号函数是什么意思啊,就是说嗯嗯嗯这块在微积分里面其实也定义过。
但是也非常简单,什么呢,它就是一个阶梯函数啊这么一个意思,然后他呢呃在呃,如果他的嗯变量就是整个它里面这个东西呃,就是就是它这个变量如果是呃大于零的,那我最后这个函数值k这个k函数的值呃。
它就是一如果说它是小于零的,就是它里面的变量啊,嗯它的值小于零呢,最后结果就是零啊,这么个意思明白了啊,所以说那那这不就正是阴影比较的结果吗,对吧,我每一个点q它对应的深度和x的深度,我们比较了之后。
然后我就呃我就可以知道哦,这个k这个函数告诉我们的到底是invisibility,是零还是一哦,那我把所有的这些点q它对应的visibility是零,还是一,按照某种形式加权平均起来。
或者说我不加权对吧,然后那我得到的最后结果是不是,就是我这个x这么一个点,他的呃最后的这个p c s s之后的结果对吧,那就是这就是它背后的这么一个数学的公式,那么从这个数学的公式上。
我们就可以看到说为什么我们说pcf这种方法,然后它并不是在filter shadow map,那filter shadow map是什么意思呢,那自然就是说。
shadow map上记录了这么一个任何一个点,它对应的深度的值,那就是说在shadow map上记录的这个深度,在这q位置上对吗,那shadow map被模糊了。
意思就是说我其实是相当于是呃profiltering,或者叫呃convolve呃,这样一个shadow map上面的一个图,就相当于我并不是这么做的,可以看到这里是一个不等号对吧。
我其实做的是上面什么公式,我做的根本就不是说我先把shadow map做个模糊嘛,另外其实你如果做了shadow map的模糊之后,你再去做比较,不管你跟什么值比较,最后比较出来的值也是非零即一啊。
对不对,那也就是说这样的话它并不能给你任意,那么另外一方面通过这种方式,你也可以直接就看到哦,我并不是说呃这个p c f呀,它并不是说在图像上去做一个啊,这么一个所谓的filter。
咱们上一节课给大家提到的,对不对,就是说我最后啊,我已经得到了一个有锯齿的硬阴影了,然后我在这个一有锯齿的硬硬营商,我去做一个模糊,试图去解决抗锯齿的问题,那这种做法,那实际上就是在所谓。
呃这么一个图像空间上来做哈,就是这么个意思啊,哎呀这里面有一个地方写错了哈,然后中间选一个y吧,咱们就不是p和q好吧,x的领域中选一个y,然后它的贡献就是x和y之间的某种距离。
然后它的值就是之前在y这个点上,它对应的visibility啊,这么个意思好嘞,那行吧,嗯这就是在这个pcf嗯,它背后的这些知识啊,ok那这样一来的话呢,我们就说完了关于这块的pcf。
然后呢咱们现在再回到说我们应用嗯,pcf去做啊,软硬影是怎么样去做的对吧,大家还记得这个事情好,然后呢嗯大家可以看一下,就是说我们上一节课已经说到了三分三步,对不对。
分三步就是首先呢我要做一个所谓blocker search,这么一步,那么这block search是在干什么的对吧,他就是说啊他首先他的目的是为了决定说哦,如果我呃在呃shadow map周围。
取悦某一个呃大小的区域啊,那么这个区域里面大概呃有多少是呃,这个呃所谓的blocker就是遮挡物,并且我算出来这么一个遮挡物的平均距离,我算这个遮挡物平均深度吧,这么说平均深度啊。
average blocker depth,遮挡物的平均深度,虽然这个东西是干什么的,是为了第二步用的,第二步就是说我用这个遮挡物的平均深度,我就可以估算出我在第三部。
应该在这个shading point周围,filter多大对吧,那咱们之前所说的就是这么一个逻辑了,只不过上一节课咱们是倒着说的对吧,然后呃那行啊,ok没问题哦。
有同学说我之前slide有一个呃写错了是吧,p cf简称pcs s好吧,之后我看看你慢慢改,有同学问啊,为什么空间域的卷积就是加权平均呢,啊卷积实则就是差不多是呃家卷平均分,你可以试着把卷积写成什么呢。
写成一两个函数乘起来,对应指相乘,然后再做积分这么一个形式,如果你把它写成离散化的形式,那就会变成了两个函数乘起来呃,然后并且外面把积分号改成求和号,而求和里面两个函数相乘。
这不正是呃所谓加权平均的这么一种表达式嘛,对吧,这么个意思好吧,那咱们回到pcs s上来,他分这么三步,那么我现在问一个问题对吧,咱们上节课其实提了这三步中,哪些步骤是可能会比较慢的对吧。
这是一个比较严肃的一个问题对吧,因为我们想着这p c s s呢,它可能会跑的比较慢,是因为什么呢,在这里写,原因,就是说我在第一步和第三步里面,都需要做这样一个操作,就是在整个一个区域内。
我要看他所有的这些呃,呃这个区域里面的所有的所谓taxi,它上面记录的这个深度,并且跟某个深度相比是吧,第一步我肯定也要这么做,第三步我肯定也要这么做,如果我这这两步是这样的哈,这两步如果我不采样。
那我取这么大一个区域哦,我知道他在texture上占据多少乘多少,这么一个格子,我不采用的办法,那就只能我每一个格子我都看一遍,是不是这个意思,那就是说呃这是一个非常缓慢的过程,那如果说好。
我觉得这个区域太大了,然后呢唉我不想把里面的所有的text都看一遍,然后我想在中间随机取一些样本啊,这也是咱们的作业的一个实现方式啊,在这么一个区域内,我去随机的取一些样本,那这样的话。
我就我我我也一样可以得到一个结果,只不过这个结果呢那自然就是近似的了,对不对,那就是这么一个一个思路,而这个近似会造成的结果就是所谓noise,就是最后的得得到结果,看起来就是噪声会很多。
是这么个意思好吧,然后呢那同样它还有呃另外一个问题,就是说如果我之前不采样,那我最后我得出来哦,我应该filter一个巨大的区域,64x64,那我是不是说这整个64x64个txt,我都得走一遍对吧。
那那这就会比较慢呀,那对于比较大的filter的范围,那么肯定就会比较慢,那如果说呃我去采样,那64x64原本那么大的范围,那我中间采样某个固定数量的三倍数,可以啊,当然可以。
但是呢它造成的结果就是noise呗,之前我们说过对不对,那所以说呢这是一个比较啊严重的一个问题哈,那么嗯但是正常情况下大家所做的做法啊,我说一下工业界的正常的处理方案。
就是这两部都是可以用我刚才所说的方式,去稀疏的进行一些采样的,就是说我确实可以去只看这一个区域里面的,某些txt啊,就是就是这么个意思,只看其中的若干个,然后呢。
我自然就可以降低我访问这个text的这次数,对不对,那我两部都吸收采样的,我得到的结果那肯定都是有噪声的,对不对,那最后得到的结果,也就是说我就算做完了pcs的最后一部pcf,我最后得到的结果。
那张图visibility,那么一张图仍然还是有这个噪声的,那么我们再怎么样处理呢,那这是一个自然而然的想法了,那我就做一遍所谓图像空间的一个降噪啊,这么个意思对吧。
那这样的话这样的话是不是问题就可以解决,那么呃是是这样哈,就是说关于这块降噪,我原本安排的呢是这里来说,我们把它给拿到啊,real time retracing的时候再单独讲好吧。
然后并且呢我会我会说这么一个事情,就是说呃关于降噪,它是时间和空间上,就是说关于图像域上可以直接去做滤波可以,然后还可以通过时间的累积来做这块,在之后都会说好吧,那也就是说关于怎么降噪,咱们就不再说了。
嗯这次的作业也就是大家用足够数量的sample,虽然慢一点,但得到的结果是非常干净的,还是挺好的好吧,那咱们就先这么说着啊,ok那不管怎么样,咱们回到这么一个分析上来,哪些步骤可能会变得很慢呢对吧。
那就是第一步跟第三步,所谓blocker search和这percentage closer filter filtering对吧,这会比较慢,于是呢我们嗯就想解决这两个呃很难的步骤啊。
于是就有人提出了所谓various soft shadow mapping,一种新的思路好吧,大家从这个过程中就可以看到啊,大家还会再进一步体会到这么一个事情啊,就是说很多方法,就是说发现前面这些方法。
在实际中有一个什么样什么问题,并且这问题在哪,然后我针对性的提出了一些解决方案,那这种v s s m自然就可以解决这个问题,好吧,那么讲之前,我看又有同学说边缘会不会flaker啊,那我先简单说一下。
所谓flake呢,那就是说在不同的这些针,然后你每一帧可能会取的随机数不一样,那么也就是说你每一帧呢它的这些noise呢,它长得都不一样,然后如果你每一帧都是noisy的。
然后你每一帧又连在一块很快的速度播放,你就会感觉他特别抖,这个就叫flaky啊,然后他会啊,我直接说他确实会出现这么一个问题啊,好的嗯,ok嗯这样有同学顺便问说多光源阴影会讲吧,不是特别会讲。
可能会和那个和什么呢,和多光源的直接光照这块儿啊,放在一块讲吧,多少会提一下好吧,有一些游戏是会闪,就是说temporal就所谓在时间上,如果真的就是比较noisy的话,他就是会出现这个问题。
以及我们之后还会说在dnoise的过程中,还会说就dnoisy啊,其实相当于是我们平常说的都是低通滤波,低通滤波就意味着低频的噪声也能通,那低频的噪声通了之后,然后你再哈哈你在做这个呃。
比如说把很多帧都通过低通滤波呃,滤波过去了之后,然后直接在播放会产生一个叫做所谓boiling,artifact的东西,叫做呃沸腾的一个现象,然后所以有很多游戏,确实现在还会出现什么问题啊。
ok那这是题外话,咱们就不再多说了,那咱们刚才所说的是什么呢,是嗯有人发现了pcs s啊,他在第一部跟第三部是有比较大的一些所谓,performance问题的对吧,那要是这样的话,那怎么样去处理呢。
那就有人发明了这种东西叫v s s m,然后啊这是怎么做的哈,然后就首先它针对性的解决第一步跟第三步,在pcs中慢的问题,那咱们把它做的事说清楚好吧,然后呢那咱们怎么样去考虑它呢,怎么理解它呢。
那咱们还是得从percentage closer来开始看,那么我们来看什么,我们看这么一件事情,就是嗯比如说啊咱们就说p cf也就是第三部吧,第三部我到底在干什么呢,第三部我是说啊。
在shadow map上记录了这么一个区域内,我把他们每一个点或者每个text,它的深度我都拿到我来看,有百分之多少的这些txt,它的深度其实要比我的shading point要浅。
我是不是想想问这么一个问题对吧,就是大家想一想,这是完全等价的嘛,哎我在这个区域内,我每一个点深度都拿到,然后跟我要比较的那个shading point的深度,我去比一下,得到一个结果。
然后我再把这个这这要么1万嘛,我把所有比较的结果都给平均起来,假如说咱不加群啊,假如说不加群,那不就是意思在说哦,我想看这么一个区域里面,它有百分之多少的text,它对应的深度。
其实是比我们的shading point要浅的嘛,对不对,这是完全相同的一件事,那他所说的是什么事情呢,咱们进一步理解,那意思就是说哦,在这个呃所谓嗯所要搜索的这么一个区域吧,就第三部pcf对吧。
当我们确定了一个区域,这个区域里面呃,我就直接去找有多少呃,这些这些text,它的深度要比我们当前这个shading point的深度t,要小,就是这么个意思,那么这个问题听起来是不是。
非常像另外一个问题,什么呢,就是说在一场考试中,你知道你自己拿了多少的分数对吧,然后你想问你现在是第几,是不是这个意思完全一样的道理吗,比如说对吧,你你你你就是咱们,比如说考试平均分是60分啊。
然后呢呃你假如说呃考了比如说80分,然后呢你你这个你想知道你排第几,你排第几怎么办呢,那你就把所有的其他同学们的成绩都看一遍,是不是这意思,你看你你能排到百分之多少,这不就ok了嘛,对吧,倒不是第几哈。
就是就是能排百分之几啊,这么个意思,那把所有其他同学的成绩都看一遍,那这正是我们之前percentage,closer filtering所做的一件事,对不对,那我们想避免的就是这么一个事情。
我们不想把所有的这些成绩都看一遍,是不是,那么我们怎么样去解决呢,哎这就是vs s m啊,聪明的地方,那还是同样一个问题,而在一场考试中,有多少同学做的比你好,或者说你是百分之几这么个意思。
那如果说我这场考试,我有一个呃每每个人的成绩,那自然就是刚才那种解决方案,那一个比它稍微不准一点点,但还不错的一个方法是什么呢,如果我知道这个成绩的直方图,这个直方图画的比较细,是不是比较好对吧。
然后我就我就其实就可以知道哦,根据这个直方图呃,然后呢我落在哪,比如大家看看绿的这条嘛对吧,那我就可以知道我排第几了,是不是这么个道理,那么嗯更进一步往后面想,就是说如果你不需要那么准。
甚至你连个直方图都不需要吃吧,那不需要你拿什么呢,哎你把它当成一个正态分布对吧,咱们之前统计上肯定是说过这么一件事情的,对吧,现在呢在这个呃呃就比如说在一个班上的诶,同学们的这些成绩。
他大概都符合这么一种所谓的正态分布,这么一个形状,那如果说我就算知道这么一个正态分布,我别的都不知道,我不知道背后是直方图,我就知道这么一个曲线好吧,然后我同样还可以进四的,根据我实际的成绩。
我在哪对吧,我知道,然后呢我就可以估计出我是前两轮几没问题吧,这肯定是可以的,那所以说这样一个这样一个思路就对了,就是所谓variance soft shadow mapping,意思就在这。
就是说呢我要研究说唉,我大概在整个的这么一个范围内,我大概排百分之几,我其实是不需要知道,整个一个非常精准的一个分布的好吧,我只需要近似的认为哦,这个分布我可以认为是一个正态分布。
那正态分布如果你想定义它,你需要什么呢,同学们可以想一想对吧,之前学呃正态分布的时候对吧,那我需要什么呢,我其实就需要两个事情,第一均值,第二房产对吧,就只要这两个事情,均值决定了它中心在哪对吧。
他那个尖在哪,第二方差只是决定了它有多胖,有有有多瘦,然后由于它是一个概率分布,就是说它本身这个高度什么都是定的啊,它不是一个任意某种函数对吧,我只需要知道他的这个期望和方差,就就就就可以了对吧。
呃均值就是期望哈一回事,然后那么这里v s m vs sm,那提出来的这个这个思路呢,呃就是如此,就是说呢我为了做第三部的pcf哦,我想知道我的这深度,在所有的深度中排百分之几。
那我就把所有的深度的诶平均对吧,和它的方差在某个区域内,如果我可以快速的把这个信息给拿到诶,那我就立刻可以嗯做这个计算了,对不对,那么我们现在想啊,假如说给你一张shadow map。
然后呢我给你框一块区域出来,诶,这块区域我问你这个区域内,它的平均值是多少对吧,哎那平均值是多少,这个听起来是不是非常非常熟悉对吧,诶我给你一张图,我给你签了某一个区域出来,然后呢。
我想快速的知道它的整个这个范围内,的平均值是多少,那就没任何问题了,对所以有同学们就可以立刻想到哦,可以用meat map,对,咱们在这之前的这个呃101里面,我们就说了对吧。
new map它发明来就是用来解决这一个问题的,所谓range average query对吧,然后他能解决这个问题,然后他当然有他的问题,咱们之后再说好吧,那么这里呢就是说啊我就先提一点map。
map呢他毕竟是不准的对吧,它在不同层级中间还要插值,而且他只能做这方形的嘛,咱们之前说过map只能做方形的,然后他要是呃呃正方形的啊,如果说它是个长方形区域,你可怎么办呀,对吧,是这么个意思。
那么一个更精准的能够求一个所谓,所谓任意的矩形的,一个在2d的一个一个表上面啊,给你一个任意的2d的一个矩形,一个更精准的这个数据结构叫做sunera table,简称s a t啊。
ok那么这个东西呢马上我们也会跟大家说,那么这里提到两点意思呢,就是说不管我通过什么方式,我在shadow map上,我给你个区域,我我想知道他们记录的平均的深度是多少,我怎么算都行对吧。
这两种方法都可以,马上我们详细说,但是咱们先这么着,咱们先考虑说哎那我反过来,我如果给你shadow map上一个区域,你你怎么立刻告诉我它里面方差是多少呢,是不是,这是不是一个比它比它的这一个区域内。
平均要更复杂的一个话题,对不对,诶那这个要怎么做呢,那这个时候呢其实咱们这就是这vs s m啊,非常聪明的一点,它用到了一个超级经典的一个公式,什么公式,一个结合了期望与方差之间的关系,的这么一个公式。
如果大家之前去学概率论,这个公式是必定必定是要经过推导的对吧,咱们之前是是要证明说哦,原来呃一个随机变量的方差,它应该等于等于什么呢,等于诶它的平方值呃的期望,或者说我把他所有取得值啊都取个平方。
然后我再求平均啊,这就是平方的值的期望,然后去减去它的期望的平方,是不是,那同学们之前肯定都接触过,这么一个一个公式了,只不过这个公式怎么会突然就用到这里了呢,对吧,那咱们看一眼啊。
我们刚才才说期望不就是算均值吗,没问题吧,那咱们shadow map里面存的是什么呢,存的是depth,就是distance,就是那些就是对应的x咯,那给你某一个区域,你肯定立刻可以得到他们的平均值。
那么平均值的平方也就是后面一项搞定了,已经知道了,那么前面这块怎么办呢,这ex平方,也就是说偶我现在需要另外一张所谓的shadow map,这张shadow map里面。
它的每一个素记录的不是他的深度,而是深度的平方,ok诶是这么个意思,就是说它的他他这么一个shadow map里面,它是它是另外一个东西吧,它不是之前那个shadow map。
它的每一个呃pixel它记录的值,它其实是其实是深度的平方,然后这样一来呢,我就同样还可以再做一个所谓范围的这个,平均查询,那我平均出来的结果呢,自然就是对于这个x平方得到的一个期望,对不对。
哎那也就是说呃我为了算这个所谓的variance啊,或者叫方差呀,就是说我其实要做的是什么事呢,我只需要额外的一张shadow map,也就是说我之前一张shadow map呢。
我记录了呃各个点看到的深度,我顺便我再把他的这个每一个点,看到的深度平方,我再把它升成另外一张shadow map,好吧,这是肯定是可以做得到的,那么在实际的这个操作过程中啊。
在open gl里面大家都知道这texture嘛,一个texture它可能有四个通道,然后正常的你写depth的话,你只需要一个通道对吧,然后你写在比如说红色的通道里面,如果咱们不考虑特别高精度的话。
一个通道够了deth,那我在绿色通道里面我就写上它的值的平方呗,然后这样一来我就根本就不需要用嗯什么呢,我我我根本不需要嗯额外的一个texture,对不对,我直接把它写在另外一个通道里面了。
然后这样的话我也不需要什么所谓multiple render,target啊,这一系列的东西对吧,然后这样的话诶,直接我就可以在生成shadow map的时候。
我想说的事就是这个顺手把这个所谓dex平方,它的这种shadow map也给生成,没问题吧,诶好那就没问题,嗯好那这样的话呃这就是刚才我说的意思了,就是说你在生成shadow map的同时。
这个意思好吧,那也就是说其实你又没什么额外存储开销对吧,然后它生成的话,他你是顺手写的,你知道的depth你算个dex平方,这是个多快的事情啊,是不是,所以说呢咱们再来写进去。
所以嗯呃就是这就能等于是虚,就就就就什么呢,就是说咱们回到刚才的呃,就是就是所谓high level到底我们在干什么对吧,我们其实就是说给你shadow map,周围的某一某一个区域啊,某一个区域。
然后你去呃,能够快速的得到这个区域里面的平均和呃,就均值和方差,现在这两个事都能做到诶,是不是,所以说这是一个非常非常聪明的一件事啊,那沿着这个思路,我得到的均值和方差是要干什么来着。
同学们还记得吧对吧,我是为了把整个这块分布,近似成为一个正态分布呀对吧,那么我自然就知道说哦,我有了均值,有了方差,我就有了正态分布,我有了正态分布之后,我现在再问哦,ok我知道它的深度的平均在哪。
深度的方差是什么样的,然后实际gx的深度是多少,ok那我现在问有多少,这大概百分之多少的这些texo啊,它里面记录深度要比我记录深度小,有多少,要记录深度要比它要比它大呢,诶是吧。
那这样的话其实我要求的是什么呢,我要求的如果大家还记得在概率论里面,大家说的,这就是所谓c d f对吧,cdf我们之前所说的这个分布呢就是pdf,那么咱们就跳过这么一个cdf概念了,咱们不说了。
我们直接说什么呢,我们要的其实就是这个曲线下面的面积,ok对吧,大家看这么一个一个例子啊,假如说你有个正态的分布,正态分布的话,然后你假设你问我有百分之多少的值,是小于一的。
这里哦哦我的鼠标应该在这哎好可以,大家可以看到有百分之多少的,这个值是小于一的呢,那我只需要统计这个面积就好了对吧,哎是这个意思好的,那么就是说如果说我对每一个这个值,我都去回答一下。
有多少有百分之多少的值是小于它的,那么我再把这个函数给显示出来,那这个就是cdf啊,这里我们不不不用多说了,完全不需要多说,就是说呃呃差不多就是这个意思啊,然后就是说给你任何一个正态分布。
给你某一个呃阴影呃,它实际的啊,shading point,他他在的这么一个位置,我立刻我就可以知道诶有多少的这个啊,呃百分之几的这个值要比他小,那么有同学就问了对吧,是说我到底该怎么去算这么一个曲线。
下面的面积对吧,然后这一块儿的话呢,呃我我原本是打算多说一些了,之后再再看后面的应用是不是需要的吧,那这里我就简单跟大家说一下啊,对于一个呃所谓通用的高斯的pdf,就是说它会比那个所谓正态分布。
其实要更那个要更精准一些啊,不是要更精准,更通用一些,它能够表示比它更多的东西,但都是这种形状,然后呢呃对于这一系列的这种pdf来说,然后他是直接可以可以把这个积分的值,给打成一张表的。
而这个这个这积分出来的这么一个值,它其实是有名字,他这个名字叫做呃叫做error function啊,这名字听起来就是就是错误函数啊,就是那个error function这么个概念嗯,这块是这样。
就是我原本呃就就这块,即使是我的离线渲染的这个课需要用到它,我也是把它放在呃一个一个,就所谓给大家参考的一个额外的一个嗯ppt上,那要不这样吧,我这块真的我不多说什么啊,对它叫误差函数对嗯。
然后如果大家想知道的话,我把对应的ppt,到时候连着这个作为补充材料放出来,好了好吧,这里不再多说,然后想跟大家说的事情就是呃,第一这积分没有解析解,它能够能够写得出来,它能够有数值解。
并且这个数值解c加加,还真有大家去找一个叫e2 f的一个函数,它就是所谓error function,然后大家可以在呃,就是任意的c加加的reference上面去找到好吧,叫e2 f这个函数就能做。
这个就是就是所谓cdf,但是呢它能够竖直的帮你解出来,不代表这个呃就是所谓一个高斯的pdf,或者说一个正态分布,他的cdf是有解析解的,这是两码事啊,就是它它有数值解,没有解析解。
那么自然数值解也比达比强嘛对吧,但是他就是说打表的话,你还得额外的存储,但是无论如何还是可以,那但是但是嘛咱们说诶既然是他这么麻烦对吧,那咱们算他肯定也挺麻烦,那所以说呢vs s m他又做了。
另外一件聪明事,他干了什么呢,就是说他不知道从哪儿找到了一个不等式,哎大家还记得咱们上节课刚刚说过不等式,不等式这个东西在在哈,呃咱们这实时渲染中间是非常好用的,对不对,然后他找了一个不等式。
这个不等式叫做什么呢,叫做切比雪夫不等式啊,这么个意思啊,这个切比雪夫他是非常有名的对吧,咱们这微积分里面接触了很多次,那么这里不再多说,多说这个人啊,那咱们说一下这个不等式是干什么。
那这个不等式是这样的,就是说呢他可以告诉你一个,就是说一个随机变量,它取的值超过某一个值的概率,但是呢它又可以不履,不需要知道你这个随机变量,它所满足的具体的是一个什么样的一个分布。
它只需要知道这个分布的期望和方差,ok是这个意思啊,就是说如果你有一个正态分布,确实你知道期望知道方差呃,或者说均值和方差,你是可以定义出一个呃,所谓呃就是就是正态分布的一个函数的对吧。
然后你给你任何一个值,这个t你可以问哦,这整个呃大于t的这个概率到底是多少,也就是说在这个实际曲线下,它的呃就是打的这个这个红色阴影,这个面积对吧,但是切皮学富不等式告诉我们说啊。
我们根本都不需要知道它是个正态分布,还是个别的什么东西,虽然它背后隐含着说,我会认为它是一个比较简单的一个分布,它是一个单峰的一个分布,挺像呃挺像这个呃呃正态分布的好吧,然后他能告诉你什么呢。
他能告诉你说啊,我呃知道了一个函数,咱们看下面这张这张图哈,我知道这个这呃一个变量它的分布,它的均值一定在这,它的方差一定在这,至于它长得是不是这样一个虚线,这么一个所谓这个bell这个形状啊。
呃我不管我不管,但是呢我可以回答这么一个问题,就是说如果我真的给了你某一数这个t,我我会立刻可以知道啊,从这个t开始,一直到这个曲线结束,到这个背后,它对应的面积不会超过什么呢,大家大家听我说。
我说的是这这个面积不是说等于,而是说这面积不会超过这么一个东西啊,o所以说是这么个意思,就是对任意分布它算是的都可以这么这么来解,那么自然而然大家看这个公式好简单啊对吧。
他就不用解什么error function对吧,然后嗯他直接就可以得到一个结果,而且你看他用到什么呢,你当然肯定得跟t相关的对吧,你t不同位置,那肯定是得到的值不一样,t变大的话。
你就得出来的结果肯定越小对吧,这个意思就是有百分之多少的只是超过他了,然后他还用到这个分布的呃,所谓均值呃,缪和它的方差cm平方对吧,那也就是说啊这个公式它其实就可以告诉你哦。
这块面积给你任何一个分布的平均值和方差,它可以告诉你这块面积从t开始到最右啊,它的一个面积的上界对吧,或者说或者说它的概率的一个上界,那但是呢,但是就是说还记得咱们上节课刚刚说的,这事儿对吧。
就是说我们在呃实时渲染里面,我们平常不考虑不等,我们考虑的是约等,也就是说所有的这些啊不等式,基本如果要拿来用哈,都被人们给用来呃,当成一个约等式来看,所以这里呢咱们不考虑升上界。
咱们就考虑这是一个对这个面积的一个,不错的一个估计好吧,那也就是说如果我有一个呃任何一个分布,我知道了,然后呃知道知道它均值方差哈,然后再给你一个范围,然后我就用这个公式吧,当等于。
然后我就可以近似的得到后台,右边这块面积是多少,那这是不是就等于是这cdf我知道了对吧,那c d f是什么,不是从最左击到这块吗,就是左边这块面积,那自然就是一减去右边这个面积对吧。
所以两边的这块我都知道好吧,那这块呢就是说这个切里雪夫不等式,他到底在说什么,他说的意思其实就是非常简单,给你均值给你方差,你不必知道它是一个呃,高斯的或者是正态的分布。
那我还是可以近似的得到一个嗯它的cdf的值,虽然他是这是一减cdf这么个意思行吧,那也就是说大家就拿这个东西过来用,那就比刚才打表要方便很多了好吧那行,那这就是这么一个事情,但是但是啊千里雪夫不等式。
它是有一个非常苛刻的条件,他说啊你要查询的这个呃任意一个变量值,这个t他必须得在均值的右边,他要在均值的左边,他们这么这么一个公式就不准了啊,这么一个意思,然后嗯这是一个非常神奇的一个一个事情吧,对吧。
然后然后正常情况下,虽然他只有这半边是好用的,但是人们平常就一直这么用,然后效果还是可以的,所以大家可以看到在这么一个实时渲染里面,大家做了多少多少的假设对吧,一个是我我不用知道它分布对吧。
这是一个另外一个这块的概率,它对应右边的面积其实只是一个上界,并不是一个真实的值,在最后他不是对所有t都好用的,它只是对这个你的任意一个呃x大于t,这个t他必须得在这个均值的这个右边,才能说这个好用。
如果t在左边,那这个估计就不准了,还是这个意思好吧,那即便在这么多的限制条件下,人们还是用它,因为它太简单了对吧,看这个公式它不是比打表简单多了嘛,对吧好嘞嗯好有同学说卡了啊,我这样我先停一下啊。
呃又有同学说没卡,可可我自己看我自己好像没什么问题啊,ok那我就先继续了好吧,那那行吧,就是这个意思就是说关于切比雪夫不等式,这怎么推的,那就是另外别的事情了对吧,然后就是说哎呀我一下看到了好多弹幕。
好像是真的是会有一点点卡吧,ok啊嗯没关系吧,那我就先继续了好吧,那做了这么多工作之后,那咱们做一个简单总结哈,他要干什么,就vs s m,如果我想用它来提升我的第三步对吧,还记得吧。
第三部p cf就单讲filter,这步我要我要怎么样用它来提升这个filter质量,那我怎么样做呢,那我就诶呃我就需要在生成呃,所谓depth map就是这个shadow map的同时。
我还要把它的平方的值,然后也给写进去,写成另外一张理解成另外一张shadow map啊,然后我要做这么一件事诶那我还要干什么呢,哈哈哈哈对吧,然后这块就是我们刚才所说的,mip map或者s a t。
然后待会儿要说这块,为了让你的嗯就是shadomap或者是平方的shadow map,他们能够支持所有范围的查询,你还要做什么额外工作,咱们待会儿说,那么呃这部自然都是你生成了shadow map之后。
然后你要做的工作,那么我用shadow map的时候,那这就非常方便了,比如说我现在给你任何shading point,然后我给你刚才已经算好了的,各种各样的东西啊,deft deft平方直接map。
然后我现在给你任何一个shadow map上的某个范围,然后我立刻就可以查到它的平均是不是诶,那也就是说这里oe解决问题,甚至它就是一次操作对吧,然后呢,那我这个诶这个平方的这么一个距离啊,或者深度诶。
它这也是一张图嘛,然后我也取它的一个呃呃同样一个范围,然后取它的平均,然后这样的话有这两个信息,那我自然就知道了方差了对吧,所以均值方差就都知道了,然后那我要知道了均值,知道方差就等于知道了分布。
知道了分布,我在嗯根据我这个shading point,他具体的真正的深度,我就可以立刻回答这么一个问题,在这么个范围内有百分之几的嗯,呃text或者说fragment挡住了他,那么挡住了多少。
就意味着说他的visibility是多少啊,不就是说它的呃不可见的地方是多少对吧,比如说有30%的呃,呃东西我算出来,最后告诉我切皮学富告诉我对吧,有30%的text能挡住我这点,那我这点的可可见性。
那可不就是0。7吗,就是visibility,直接就可以得到答案了,对不对,那这样一来哦,我根本不需要在这个范围内做任何的采样,或者是循环,是不是这个意思,所以说这是非常开心的一件事情。
也就是说通过这种方式,我的第三步非常非常圆满的得到了一个解决啊,这么个意思,但是大家看到我这里打了一个问号,哈哈诶有同学问的非常到位啊,就是说如果场景中间有物体移动,你你就一定要更新mirap。
真的是就是得这样,甚至来说啊,你你如果没有物体移动,光源移动也是一样的嘛,嗯对吧,然后就是说甚至在其他东西都是静止的情况下,只要你每一帧你是新生成的shadow map呢,你肯定要做这个呃。
对应的这些mp map的这些这些操作,所以说它本身还是有一定的开销的,这是真的,但是话又说回来哈,是这个意思,就是说关于关于这一系列的这些操作,比如说给你一张图texture。
然后你要生成它的mile map,这些东西呢都是gpu的硬件,支持的非常非常到位的一件事情,你几乎可以认为这些东西不花时间啊,可以这么理解,就是说生成这个实在是太快了,给你一张texture。
然后你立刻生成它的map map,它会非常快,不过s a t会慢一点,咱们待会就会说好吧,那么嗯再说这个具体这块之前,那咱们先想办法把这vs s m啊,把这个事情和啊和什么呢。
和和和咱们之前要解决的这两个问题,咱们这关系都得先说清楚对吧,我们现在说v s s m说到这里,其实要解决的是第三部pcf对吧,可是大家还记得一件事情对吗,就是说有两部都涉及到要采样。
或者要在一个区域里面,我要找到他所有的值,那这也就是说我这第一步什么事情还没解决呢,对吧,那是不是不对,也就是说它只解决第三步的话,它并不能让这个方法变得非常快是吧,那怎么办。
那咱们回到第一步上来看第一步在干什么,大家还记得名字叫blocker search,给你一个shadow map上的一个区域,我要问在这个区域内,它的平均的遮挡物的深度,ok那也,那也就是说。
我要把他的所有的这些texo都走一遍,我要判断是不是这样的,如果是遮挡我,我把它的深度给累加到某一个什么东西上面去,对吧,然后我根据我最后累加了几个遮挡物,我把我这加核的深度除以呃。
比如说呃总共遮挡物的个数啊,这样这不就是遮挡物的平均的深度嘛对吧,就这么一个思路对吧,那这是之前我们做的做法,那当然非常慢了,他就会非常的不高效,那它就会出现呃呃什么呢。
就会出现说比如说这里诶5x5这么格子诶,我都得把它走一遍,是不是不太好对吧,那嗯这里面呢先区分一个概念,就是说我们要说的事情是遮挡物的平均深度,而不是在这整个一个块里的平均深度还是一样。
我们看这个5x5的这么一个呃这个区域吧,那在这个区域里面嗯,假如说假如说我的一个嗯确定point,它对应的深度是七啊,假如说它对应的深度是七,那么只有说这些text就是一些蓝色这些txt啊。
因为它们具能标注的这个呃,之前在shadow map上记录下来的这个距离,它要比这个七要小,它比七要小,所以说他们才是遮挡物,其他这些他们都不是遮挡物对吧,哎我们要算的是遮挡物的平均深度。
是这么写,蓝色的区域,它的平均深度不是整个的平均深度,整个平均深度咱们刚才解决了,是不是给你一个区域,它里面记录的全是深度信息,我反正求个平均,那不就是整个的这个深度,也就是说the average。
咱们假如说啊知道了没问题,那咱们不知道的是蓝色这部分的平均深度,是不是这个意思对吧,那所以说呢咱们要解决的,其实就是所谓的这个呃遮挡物的平均深度,下一步怎么怎么解决对吧。
那这就是呃这块的关键的这么一个想法,嗯咱们做一个定义什么呢,就是说在呃我有一个shading point,它的深度是t那谁是遮挡物呢,那就所有所有它对应的深度小于这个t的,都是遮挡物,那就是蓝色。
他们把它给记成它的平均深度啊,他们的平均深度虽然我不知道,我先把它记成z a clue呃,呃cluded啊,这么个意思,z o c c啊,然后呢,那同样道理,那不是遮挡物,谁不是遮挡物呢。
如果这个z啊它实际深呃,这个shadow map上记录的深度它是要大于呃,我的仙灵矿泉深度,那它就不是遮挡物,那它不是遮挡物,它也可以有个平均深度吧,就是这些红色的这些颜色呃,这些text它的平均深度。
我可以把它记成哎z ana cluded哎,这也没问题对吧,那所以说这样一来,咱们是不是有三个概念,整个的平均深度咱们知道早就知道了,整个这一块直接取一个就是mmap也好,s a t也好。
取平均就得到了,那么我要求的z a clude,然后我不我我这the cluded,可惜不知道,然后呢,我这zana glude,an an accluded吧,就这样说,这块区域的平均是多少呢。
呃我也不知道,但我也不关心,不是这个意思吗,对吧,然后所以说我最后要的就是遮挡物的平均深度,那么这就是这vs s m在这第一步所谓block search中,他做了一个聪明的一个做法,那那还是一样。
照我们刚才整理的这么一个思路啊,我们要计算的就是遮挡物,也是蓝色的这块平均深度,然后呢哎我们这这也有另外一方面的呃,这块不是遮挡,我们平均是我们不管,但是他们总归得满足这么一个关系吧,这是什么关系呢。
诶大家看啊,也就是说啊,比如说我有n一个呃,非遮挡物总共是n个,然后非遮挡物的平均值是这么写,然后我n2 个这个遮挡物,然后总共也是n个,然后这是遮挡物的平均深度,哎我这是在干什么。
我这不正是在做这个事情呢,就是说哦这里是一个比例,对不对,n一除以n就表示说诶,非遮挡物占据的比例是多少,然后他们的平均深度是多少,然后遮挡物它整个在这个里面占据的比例,大概百分之几都是遮挡物对吧。
然后它的平均深度是多少,那我自然而然诶,我把他们这按照这个百分比给平均加圆起来,他们肯定就得等于总共的呃,嗯这整个一二块他们所有的这个深度的平均了,那肯定是这样的,只有这两种呗。
只有这两种平均的这个深度嘛对吧,每一种平均深度是这些,然后每一种各自占的比例是多少,他们把加起来肯定就是总共的平均了,这是一个非常直观的一个呃观察,但是它非常有用,什么呢,就是说啊大家看这个事情。
就是说n一除以n对吧,n一除以n是什么,就是说嗯没有被遮挡住呃,就是说不会是能够遮挡住我,shading point的这么写txt,它到底有占了多大比例,那这是什么意思呢,对应到切比雪夫上。
大家想刚才那个分布啊对吧,这这所以有同学问的非常好,对,这不能用之前正态分布,假设正是用它的时候,正是用它的时候,这个嗯这个假设我不管是用正正态分布也好,我用切碧雪肤也好。
唉他都可以告诉我有百分之多少的呃,这这些呃呃txt对吧,有百分之多少的tt,它的值要比我的当前这个深度要大,那这不正是切比雪夫直接告诉我们事情对不对,哎那所以说我就立刻可以得到这么一个百分比。
那我知道这个百分比值了,我我另外一个百分比,那不肯定是一减它嘛,对不对,他俩加起来是百分之百嘛对吧,就是说比如说我有百分之呃,30的都不是遮挡物,那另外70%肯定就是啊这个意思,那这样一来的话。
哎我这两块的比例我知道啊,那咱们看一看啊,我们要求的什么来着,我们要求的是这个呃,they are cluded,对吧嗯,那那我们知道它整个一大块中间平均是什么,我想知道它的诶遮挡物的平均深度诶。
可是我偏偏我不知道这个东西怎么办对吧,我不知道说非遮挡物的平均深度我不知道,不知道怎么办呢,那这个时候就是他的一个更大胆的一个假设,不知道是吧,好没关系,我就认为你的非遮挡物的深度。
都跟我当前的shading point的深度一模一样,也就是说比如说我的那个shading point,那块的深度是七啊,那这些全部都是七啊,这么个意思好吧,哈哈哈哈哈哈啊行吧。
所以说啊这是一个不得已的一个假设哈,但是我觉得这么假设的问题不大,为什么呢,因为绝大多数的阴影的接收的东西是个平面,想一想这个事情对不对,绝大多数阴影的接收者是个平面,如果真的是个平面的话。
你就这么假设问题不大对吧,那所以说这其实它背后有一点点它的道理,那么这样一来的话呢,哎大家看average的话,唉我一次呃这个所谓范围查询就查出来了哦,这n一除以n切比雪夫。
n2 除以n一减切比切比雪夫对吧,然后z n a cluded,就是当前那么一个值是神经控制,剩下什么z o cc啊,解决了哈哈哈哈对吧,就是通过这种方式哎直接就可以解决了,让大家看他做了件什么事对吧。
他同样就是为了解决他的第一步,所谓呃呃呃这叫什么来着,block search对block search,然后这一步他用到的一个核心的,就是这么一个观察,就是这样一个公式了对吧。
这个公式是肯定百分之百对的,然后呢他就是说这些比例的什么东西,他就用这个借比雪夫来告诉我们,然后他这总共平均呢直接通过范围查询呃,然后再做一个假设,哎,我最后可以把遮挡物的平均深度就拿下了对吧。
所以说唉这是一个非常非常聪明的一个做法。
那这里就是呃v s s m能够做到的一个效果,那大家可以明显从这个图上来看,这是两个光源对吧,大家看到两个阴影交叠在一块,然后呢看起来真的是不错对吧,然后嗯当然了,他有他的问题。
咱们待会儿就会说啊,嗯不过呢到这里这样哈,我先放到这一页呃,现在同学们可以问一下问题,然后呢我我先说一下,就是说vs n s m,他确实那这这这些做法他实在是太聪明了。
就是说我每次我觉得我是嗯再思考一遍,他到底是怎么做的,我觉得有很多很多很多超级大胆的假设,然后但是同时他也有很多非常这些,很精髓的一些观察,对不对,就像刚才那么一个按按照比例去加强。
他们的平均深度这么一块,然后我就觉得,虽然啊咱们先说清楚,虽然在实际的操作当中,就是人们现在,现在更多的会去用pcss来做阴影了,为什么呢,这里说一下,就是说人们现在对噪声的容忍度,现在是越来越高。
而为什么是这样,正是因为现在对呃图像空间做降噪的这个手段,现在是做得越来越好,特别是有了这个空间和时间,这么两个东西结合在一块儿做降噪,效果就会特别的好,而这个整个这些东西都应该归功于。
一系列的这些所谓temple的方法,比如ta咱们之后还会再说好吧,然后就是说现在人们说,你能够比较快的得出一些有噪声的结果,我觉得问题不大,之后,一定是有办法可以把这个噪声干掉,好吧,咱们这么说清楚。
这就是为什么现在渐渐的pcs s要压过vs呃,呃v s s m里头啊,这么个意思好,那诶我来看看啊,同学们说嗯接收平面要是曲面怎么办,诶这是说的非常好,不只是曲面,甚至跟光源不平行的时候。
就已经会出问题了对吧,然后就是说确实是会出问题啊,然后这些就是所谓的这些,我就说嘛咱们在做呃实时渲染的过程中,有很多这些理论说的挺挺挺明白,但是在实际操作过程中就会出现一些问题,确实是会出问题。
大家可以自己试一试,artifact啊,挺明显的,做作业难吗,作业不难啊,作业嗯就是简单的p c s s没让大家写vs m吧,啊这个意思啊,好吧哦,v s s m是p c s s的快速版本的。
可以这么理解吧好吧,可以这么理解,然后就是说他嗯但是你不能替换tcs s,我觉得p c s s可以作为一个所谓的baseline啊,可以作为一个可参考的一个标准,然后目前来说反正大家就用它效果挺好的。
我们这里有,我刚才不是说了嘛对吧,我们我为什么要讲这vs vs s m,因为他实在太聪明了,这个中间这块,而且呢确实它可以做得非常非常的快啊,而且他是没有任何噪声的对吧,那这多好呢对吧。
然后如果他要写的话,其实我挺建议,那这个同学们自己没事写一写这个v s s m,然后它中间涉及到很多技巧的,特别之后我们要说的这些算法啊,这个事情啊,好哦,我再强调一下。
vs s m并没有用正态分布去估计,他用的是切比雪夫,然后就是说我说正态分布,只是为了方便大家理解一下,就切比雪夫根本连正态分布这么一部都都不用,不用经过他就已经可以得到他的c d f呃,有意思啊。
ok嗯好吧嗯噪声我其实之前说了,我就不再多说了,好吧,这这这那那现在我把这剩下来的这些这些嗯,内容呃,我快速过一遍吧,好吧啊行,那咱们下一步说什么,咱们下一步说一个遗留问题,在v s s m中间啊。
嗯嗯就是说他的一个具体的实现什么,具体的实现是一个为了让所谓shadow map,或者说嗯嗯就是记录了深度平方的那么一种,shadow map,能够支持范围查询,我们还要做一个事情对吧。
我们毕竟要生成这个呃milk map或者是sa table,然后嗯这块之前nvidia的一个经典做法,就是它引入了一个呃这个sound era table,这么一个概念,所以说咱们把这整个这块给说清楚。
这样算说完好吧,然后呃还是一样啊,为什么要说他是因为咱们之前说了,给你一个范围,你要快速的得到它的均值和方差,然后为了快速得到均值和方差,我其实要快速得到这个范围内的深度平均和,深度平方的平均对吗。
那么呃这两个其实咱们就把它当成一回事吧,那咱们就现在假设呃把它给抽象出来,变成一个更通用的情况,现在就给你一张图,给你一张图,我现在要问呃,给你这张图上的任何一块区域。
然后这块区域我应当如何去快速的得到它的呃,一个平均值,这么个意思啊,并且呢这块区域我保证它一定是一个矩形,好吧,这么个意思嗯好那么呃最简单的做法,那肯定就是mip map,咱们之前说过对吗。
map map如果大家还记得咱们在game z101 里面,map map做的是什么,做的是快速的近似的方形的范围查询,没错吧,然后就是说即便是方形,它也不见得就是说可以做到呃百分之百精确,为什么呢。
因为它有差值,一个典型的例子是这样的,就是说比如说咱们这一块,大家看到这个level 5对吧,这milk map不就是一张图,我可以生成它的这每一次减小一大分辨率,然后生成另外一张图啊对吧,这个意思。
然后现在如果我想求原图上对应这么一个哦,我的天我的鼠标不在这,ok原图上对应这么一个区域哈,啊呃这块它的值是多少呢,哎那我直接到level 5上去取这个像素,它对应的值是非常精确的一个值对吧。
那如果说我是原图上,这个我稍微把那个正方形啊往右下偏那么点,但是又没偏到这个位置,我偏到天道这中间某一个位置怎么办呢,那我是不是要对这四个地方进行一个差值对吗,插值出我的鼠标现在悬停的这么一个位置。
它的值到底是多少,而这个差值就不怎么准嘛对吧,只要涉及到差值,差值肯定是猜出来的吧,而且这还不是关键,关键是如果说我有一个查询的范围,它不是比如说二的多少次方,那么大小边长的一个正方形,它是个正方形。
但是它的边长比如说它是六,那你可怎么办呢,那你是不是要到,比如说第二点多少层去找他对吧,二点多少层找他怎么做呢,还记得吧,三线性差值就是层与层之间,我还要再做一次差值,那这样不是更不准吗。
意思就是说啊mip map能不能做范围差距,能但是不准啊,这么个意思,而且咱们刚才所说的都是说关于这个方形,正方形这的这样一个查询都已经不准了啊,更不用说哦,我如果还有个长方形,那不就是不好做了吗。
各项异性过滤能解决这个问题啊,ok那但是咱们在这里要说一个,百分之百准确的一个方式来实现它,那这怎么做呢,这就是大家引入的这么一个数据结构啊,叫做some area table。
然后同样这个sama table呢,它是紧密的和一个什么东西概念呢,和一个算法的概念叫做前缀,和这么一个概念结合起来的,那么他是做了件什么事啊,其实他做的事情挺简单的啊。
别忘了他的最早他要解决什么问题来着,他要解决范围查询对吗,范围查询意思就给你一片区域,你立刻能得到它平均,那么我现在来说这么一个事情啊,就是说他其实啊范围内求平均,跟你范围内求总和是不是完全有概念吗。
没问题吧,你得到平均之后,你反正你知道范围多大,你去乘以这个范围内的这些素个数,它不就是总和了吗,对吧,你知道总和之后,除以这个素个数不就是平均的吗,所以这是一回事啊。
就是范围内求和跟范围内求平均一模一样概念,那么咱们现在假设看这么一个事情,就看这个input啊,大家看一个数组一维情况下,一个数组那一维情况下范围查询是什么意思,给你一个连续的某一段对吧。
告诉你这一段它里面的值到底是平均是多少,或者总和是多少,那么总和是多少呢,那比如说咱们以刚才呃这个为例啊,以以这样一个一维的数组为例,那么我需要把三把七把一给加起来,总共11,是不是这个意思。
这没问题吧,对那我就说呃我为了算它它的复杂度是多少呢,他肯定是o n的呀,因为说你这个范围如果给的非常大,咱们给一个巨大无比的从头到尾的,那你是不是要所有东西都给加一遍。
那你现在就是不想要把它给加一遍了,对不对,那这个时候人们就提出了一种数据结构,叫做some area table,那么对于一维的这个退化情况,我不知道应该管它叫什么,咱们还管它叫s a t好吧。
s a t干什么呢,对一维的情况它非常简单,他做了一件什么事,做了件预处理的事,玉书里你拿到这么一个呃这个啊这叫什么呢,呃数组啊,一维的数组,我先花o n的时间,我从左到右走一遍,我走一遍的时候。
我就把它对应的这每一步的累加的和我给加上,比如说我一开始在一,那么它从最左加到这个的值,它就是一,然后我往右走一格走到三,那我原本已经得到了一了,我把三给加上,得到了四,然后我再往右走一格。
然后呢我就我就会算哦,我刚才已经得到了40这个核了,那我要是走到这个点的话,从左到右总共加起来是多少,那就4+5,那就是九,然后每次我就把这些每次拿到数看见没,每次拿到一个数。
就把它加到这个前面一个值上去,那我最后得到结果,那可不就是这41就是总共的总和对吧,然后那这样说,咱们的一个精准的定义就是sat上任何一个素,它表示的都是原本的你这个一维的数组。
从最左边的这个素加到这个素,它的和是多少啊,这没问题对吧,那这样一来的话,他有什么好的办法能够方便我来做这个查询呢,那就是说啊大家看这个查询,他可以做到这么一个事情,就是说我不是要求这么一段呃。
这三这七是一吗,然后然后他加起来等于多少,这里有一个经典的一个思维方式,这一段加起来等于多少,那就好像是说我这这个整个的前六个数,形成了这么一段,它的和减去我这前三个数的这一段,它的和看见没。
我中间的任意一段,我都可以把它给描述成前面多少遍,这是前六项呃,德和减去前三项的和,那可不就是剩下456的嘛,对吧,哎那这里面那我问前六项加起来的和是多少呢,我刚才已经算了s a t比20。
然后前三项加起来和是多少九,那我只需要我为了回答这三个呃,值加起来是多少,我只需要找到哦,它对应的这个终点,找到它起点前面一个啊,然后前面起点前面一个,那他们一减哎,20-9多少十。
一正21 3+7+1嘛对吧,就是这么一个一个嗯很简单的一个思想,那他做的一个事情是什么呢,就是预计算的,就是他虽然这个o n呢他还是要花的这个世界,但但是呢他是你,反正这个数组它本身他他就是那么些数。
然后你要知道这些数也是欧文对吧,你要你后他就开了一个额外的欧文那个空间,然后呢他又花了欧文的时间把数组走,那边就做了这么一个事,哈哈就这么一个事情,这个算法也太过简单哈。
就是不叫太过吧啊确实可以这么说吧,就是说这个算法是嗯,就属于说就算在面试中,也算是相对低端一点的题目,就是说这块来说啊,嗯确实挺容易啊,前缀和思路,那么到二维的情况下,唉二维的情况下是什么样子呢。
唉那这是我们要解决的问题是吧,二维的情况下就看这张图就好了好吧,这是什么意思呢,二维的情况下,你有一个任意矩形,而任意矩形啊,但这算是所谓axis aligned的矩形,我们不让它能旋转啊,不不不行。
那不行,就是它必须横平竖直的矩形,那这个矩形里面的所有核啊,大家看看这个矩形里面所有的和,咱们是不是可以理解成,诶这个绿色的这么一个矩形,从左上角开始的啊,看一下啊,从左上角开始的这么一个绿色的矩形诶。
我先减去左半边,减去左半边这个黄颜色,这个矩形看见没,然后呢我再减去上面这这这半边黄颜色矩形,然后你会发现不对劲对吧,我我这是不是多剪了一个,这最上面这么一个小的矩形对吧,我再把它加回来。
这是最简单的容斥原理啊对吧,然后就是说嗯大家可以体会一下对吧,这个绿色减掉左边一半嗯,就剩右边一把又减去上面一半,你就上面左上角有多减了,把它加回来,那可能就最后变成你你就要的蓝色这块了吗。
那么这四个矩形,这四个矩形在这四步操作中,它都有一个明显的特点,什么呢,这些矩形的起点都是左上角,看见没有,都是左上角,那同样道理,我们用刚才的所谓some area table sat的这样一个道理。
我可以预计算一张表,这张表里面任何一个素,它所表示的都是从左上角加到这个素,这整个一个矩形里面的值对吧,那这样的话我我这所有这四个这四个矩形,我都可以通过查s a t对应的这么一个素啊。
对应这么一个素,白色的看见没,我就可以在sat中求这么一个值啊,然然后我只需要查四次这个表,大家可以看很明显,查四次,我得出来的s a t,我立刻就可以得到这么里面的一个精准的一个,呃求和对吧。
是这个意思,好啊,哦我倒是有同学说这个图应该以右下角为坐标,可能好一点哦,有道理,但是这样哈,反正就是说呃他就把这个箭头给忽略了好吧,就算是这些所有东西都是从,都是从左上左上角开始,那么同样道理哈。
那在二维的情况下,你如何去建立这么一张s a t呢,那那这个其实是很好做的,什么呢,每一行不都是一个一维的意味的一个数组嘛,你都这么做是吧,每一行都这么做,然后做完了之后,你是不是每一行的一个呃。
每一个点都表示哦这一行从左加到右,加到我这个当前这一点它对应的值,然后呢我每一行都这么做,做一遍之后,我再把每每一个列就竖直着,我再做一遍,就是这样的话,我是不是就就可以得到任何一个这点。
就现在s a t中间这么一个白色的一个点,它描述的就是哎这么从左上角开始,一直加到它的值是多少对吧,那所以说只用横着做一遍,竖着做一遍,那么横着做一遍,每一个呃行我都是o n的。
那么整个算起来那就是m乘n了对吧,然后呃就是行和列的这个呃呃个数各是多少啊,嗯就是就是这么说,就多少行多少列嘛,假设说m行n列,那就是mn这么个时间,那么水平一遍竖直竖直一遍,它还是mn这么个时间。
但是同学们肯定会想起上一节课我就说了对吧,就是说嗯,那咱们图形学中,关于这个复杂度的这么一个事情啊,是一个非常不认同的一件事情,对不对,哈哈哈哈啊,ok哦是这样哈,就是说我这里写o n。
这个n指的是指的是所有的这些素的个数啊,如果这样理解的话,那它就是就是o n的哈,然后呢如果准确来说,那就是o m乘n了啊,没问题啊,都是对的,好的,那么这里呢那哦有同学问他s a t会不会溢出。
就是说分辨率很高的时候,那这位同学问的,肯定就是说是他的数值精度的问题,是会不会溢出对吧,他肯定不是说存储,因为存储来说,它的s a t的存储,跟你原图的存储是一模一样的,这是没有问题的对吧。
然后所以原图存得下你s a t,你就可以认为存得下就是o n的时间,o n的存储没问题,然后呢嗯就是说呃呃关于数值精度累加,它总归是会损失数值精度的,这是肯定的,所以说它确实是会有这样一个问题啊。
嗯但是问题不是特别大,那么这里面我想说的一个问题是什么呢,就是s a t,大家看起来这个复杂度是o n的对吧,然后我刚才提到这么一个做法啊,如果你横着做一遍呃,竖着做一遍,那你横着做一遍的时候。
就说每一行可以单独呃进行,就是我在算第一行的时候,跟第二行一点关系没有对吧,也就是说行与行之间是可以并行的对吧,然后这种情况下,就是就是说呃它的并行度还是有的,没什么,没什么特别大的问题啊。
也就是说你可以通过gpu,然后可以让它变得比较快,但是这个我之前说过这么一件事对吧,gpu的并行度是远远比这个行数要高很多的,然后这样一来的话就会嗯,就是就是说如果你这个算法写得不好的话。
呃就这个病情很可能还是会有点慢啊,这么个意思啊,这就是为什么我如果我没记错的话,我记我记得我记得呃,我记得nvidia放出来过一个什么样的实践,来来做这么一个s a t就直接把它给写出来。
然后我自己年轻时候我还写过一个,然后嗯就是这么个意思吧,就假如说你已经有shadow map了,就是open gl生成的open gl生成的呢shadow map,它肯定是个texture。
它肯定在gpu里,然后呢,我把它给当成一个呃coda的某一块的这块内存,我可以去访问它,然后用库大去呃,呃这还是可以的,但是如果我没记错,当时写的还是很不是很快的啊,这么个意思啊,然后呢呃这么个意思吧。
也就是说呃这里虽然都是o n,还是回到咱们之前实时渲染考虑的问题,我不管是不是o n,我只管它实际上跑的是不是足够快,这么个意思好吧,嗯行吧,那差不多就是这么个意思吧。
就是s a t嗯这块的构建以及它的使用,那咱们就都说清楚了,这样的话vs s m这块应该没什么死角了,应该都已经呃覆盖到了,我来看看同学们还有什么其他问题,不就是说我们其实现在还差最后那么一点点啊。
最后那么一点我也就那就这样哈,反正今天啊这这这这因为sirup这个事情了,多耽误时间,然后所以说今天是真没办法了,我待会花几分钟把它给说完好吧,嗯有同学问我为什么要用q弹,当然用shader也可以写了。
问题不大,就是说嗯sat就确实是不怎么特别好用的啊,不是不怎么特别好用,就是说它本身呢它还是有一定的开销,可以这样说啊,就是说嗯mip map的话,这里我再多说一句,就是说大家看mip map。
它我刚才不是说是近似的嘛对吧,然后他在这个阴影比较小的情况下,也不是阴影,就是软硬的,你要过滤的范围比较小的情况下呃,还是可以的,但一旦大了之后,大家会看到明显的一些artifact啊,这个意思好嘞。
哈哈哈哈哈好,ok那行s a t不是前缀和啊,sa t是一个数据结构,它对应的这个算法叫前缀和算法啊,这个意思啊啊不过没关系了,区分这个干嘛呀,嗯反正一个意思哦。
用computer sciator也可以呀,对呀肯定是可以的,对嗯,就是就是说怎么样去算这个s a t,这个问题不大,但是呢,确实刚才就之前有个同学提到这个事情了,就是说我每次生成shadow map。
我肯定就要重新算一遍mile map,或者是或者是它的对应的at对吧,然后这肯定是要花时间的,这是真的啊,ok所以说这部分得要足够的快,k s t横向二维的c e f是挺像的,哈哈哈哈是挺像的啊。
ok好那那行吧,那这样的话,那我就顺便把这最后这么一点给给说完啊,嗯就是说最后我们要提到,一个非常前沿的一个东西,叫做moment shmap,不是不算特别前沿的,但是就是说中间呃应该是1度有人用。
然后后来就还是一样嘛,就是因为所谓temple filter的方法,现在变得越来越流行,所以让之前的pcs s,所谓这个啊重新焕发升级啊,这么个意思。
所以moment gle mapping渐渐的没有人,没有特别多人用啊,他确实实现起来有点麻烦,这是真的,那么他到底在干什么对吧,咱们还是按之前的经典思路来,就是说,那么我们既然提到诶。
v s s m发明了,是为了解决这么一些哈哈,这个呃tcs s的问题对吧,那他自己会不会有问题呢,呵呵有对吧,他的问题是什么呢,那咱们刚才说了哎正好有同学问对吧,就是说v s s m的问题是什么呢。
那咱们从这幅图就可以看出来了,正是因为他是做了很多假设嘛,对不对,那他的假设不对的时候,那不就出了问题了吗,那他假设什么时候不对呢,那我这里咱们先看左边这幅图,看左边这幅图呢。
它这里有一个shading point,shing point呢,它比如说光源在这边对吧,光源应该在这投影嘛,然后我会看到哦,他这里有这么这么些可以遮挡住他的东西嘛,对吧。
因为你想这个点可能对应的就是shadow,shadow map上的某一个pixel,然后shadow map这个pixel周围的那些pixel,记录的可不就是这些数值这些东西,他们的这些深度这些分布吗。
这些是树枝什么东西这么这么复杂,呃,我把它当成一个正态分布,好像并没有什么问题对吧,那所以说我就可以得到这么一个结果啊,ok那这里呢问题就不大,那么什么时候会有问题呢。
那自然就是说我不能认为在这个范围内,他的这些呃集合就是它的fragment或者text,它的分布还是一个正态分布对吧,或者说一个光滑的一个呃,一个所谓single logo的一个分布,不能这么假设。
什么时候不能这么假设呢,其实有一些简单情况反而你不能这么假设,比如这个时候,假如说你这个shading point还是shading point,我往某个方向看,我会发现他正好穿过就这三个片好吧。
就正好穿过这三个片儿某一个位置,然后呢,那这里实际上来说它对应的这个呃分布啊,就是遮挡物,它们的分布就是也不是说这一根光线穿过啊,就整个这一片吧,这一片它的分布很明显,它应该是会集中在这三个这个呃。
深度的附近对吧,也就是说它不一定是这么三个delta,他应该是很明显的三个呃不同的峰值,就是说如果说你往这个方向去找到它对应的,shadow map的pixel,取它周围的一片。
你肯定会看到那么一个分布,而那个分布三个峰值的,你怎么可能拿一个呃高斯来描述它呢,哎这时候就说明你描述的不准对吧,哎描述的不准会出什么问题吗,那这是我们要关心的事情对吧,那描述的不准会出问题。
会出问题出在哪儿呢,那是描述的不准,那可不就是说你最后算那个百分比算的不准吗,咱们就假设先不考虑是什么blocker search内部吧,那咱们就只考虑最后的p cf这一步。
那我p cf最后就是为了告诉我一个百分比呃,多少挡住他,然后我那我那我这一减多少呢,自然就是我最后的visibility了,对不对,那那像这种情况,如果你不准,那你得到的结果要么大,要么小呗。
就是这个意思,那如果说你得到的呃,说你原本啊应该实际上有个30%的,这些呃taxi能够挡住你当前的shading point,但是呢呃您用那么一个不准的分布,然后你估计出了50%。
那这就说明他会偏黑了对吧,你得到结果就会偏黑了,偏黑了怎么办呀,那就偏黑了呗,通常情况下人们是能忍的,就是结果就是有一些地方他不该那么黑,就是他反正阴影了对吧,他黑了就黑了,那么但是有一个问题。
人们非常不希望在这个阴影的某一些地方,突然变白了,这是一个非常严重的问题,ok那么这个问题怎么样去理解呢,咱们就看下面这幅图,这幅图就比较清楚,大家可以看到,比如说实际的一个遮挡物的分布。
它其实这么一个非常不规则的一个东西来看啊,大概是这么回事对吧,然后呢诶我不管三七二十一,我用的还是这么一个正态分布去描述它,那我我我们之前刚刚说这个不管是什么,真的用正态分布还是切力雪佛。
他都会假设大概有一个那么样的一个分布,然后那这时候我会估计出什么来诶,我会估计出哦有百分之这么个红色面积,它算是能挡能挡住我这个shading point,然后实则是呢,这个呃。
呃不是不是不是他的深度会比这个shading point,他要大,就意味挡不住啊,挡不住,然后它实际上来说只有那么小的一部分,蓝色的阴影面积是深度要大的,也就是挡不住的,那也就是说你这会造成的一个结果。
就是假如说他实际只有20%都挡不住,然后你先告诉他,这有有50%的都挡不住,那就得到结果呢不就会变白吗,就是说这两种情况肯定都会发生的对吧。
诶变白了会出现一个什么情况,就好像会出现这么一个情况一样,大家看这个车子哈,大家看这车子,看这车子有没有感觉哪个地方特别奇怪,哪儿呢,这儿大家看见没来看这块,就正常情况下,这个车子底下得有底板的。
没问题吧,对他肯定不可能光直接照到它,那为什么这里面它突然会变白了一下呢,哎那这里大家就可以可以解释了,就是说啊,这车大家看起来是一个非常镂空的一个情况,对不对。
也就是说如果我这个shading point,往light那个方向上去看,我会看到哦,有一部分这些呃text哦,就是就是说对它的深度就集中在这个附近,还有一些零零散散的深度集中在这个附近。
就是它不是一个镂空的吗,还是车子上面有个夹子嘛,对不对,然后就是说底板上这是一块,然后这个这个天窗上这这边又是一块,然后它很明显它不是一个正态分布吧对吧,它不是个正态分布,你强行拿正态分布去描述。
它肯定会变得有的地方暗,有的地方亮对吧,有的地方暗的地方你看不出来,有的地方亮你就会看出问题了,就好像是这light会渗过去对吧,就是说这个就是管它叫做light leaking,没问题吧。
这就是我们怎么样解释的对嗯,然后呢呃这里面呢我我再说一个概念吧,就是说呃工业界上有很多啊,这怎么说呢,嗯很很很多说法管它叫light bleeding啊,这块我不不建议这么用。
因为这样的话和全局光照里面的那个所谓,color bleeding这概念就有点有点混淆这个意思,所以我更愿意管它叫light leaking,就是漏漏光嘛,这是挺正常的一件一件事情对吧。
那那就是说呃这肯定是不好的对吧,那么另外一些不好的地方,那如果你的接收物咱们刚才才说嘛,接收物不是一个平面的话,它就会出现一些问题,那这这这些地方大家可以看到,有一些这些明显是rtfx这阴影断了对吧。
然后呢呃切比雪夫不等式这边自己也有问题,咱们之前说过切比雪夫不等式,它只有在这个呃你你要查询的那个深度,他是在超过平均值的情况下才是准的,否则它不准对吧,然后这里也可能会造成问题。
那么这些很多这些东西呢它都都会造成问题,那么这时候呃就是说人们就想了。
我能不能避免vs s m的其中一个问题,那就是描述分布描述的不准啊,ok就是说就是说他解决不了什么什么,我就说moment shadow mapping,他他确实这样说吧。
不是用来解决什么非平面接收物或者什么,它解决的问题很清楚,就是说我的vs s m里面,我描述一个分布深度的一个分布,我现在希望他描述的更准,我就想解决这么一个问题好吧,那么它怎么样去解决,它。
引入了一个方法,就是使用更高阶的moments,moments是什么东西呢,中文的翻译叫做矩矩阵的矩啊,就是就是这一个字,它不是矩阵矩啊,就是就是高阶的矩去描述一个呃一个分布啊,这这是是什么鬼对吧。
那那举是什么呢,这举这个概念啊,在在这个啊各种各样的数学资料里面,它定义的是非常非常五花八门的,就是是各种什么什么什么中心举什么杂七杂八,各种各样还是什么sin cosin的,是什么三角举啊,都非常多。
但是呢嗯最简单的一系列的定义的举,它是怎么定义的呢,就是说哦我我我就我就直接可以用这个什么呢,就是用某一个数,某一个数,我去我去记录这个数,我记录这个数的平方,记录这个数的三次方,记录这个数的四次方。
然后然后就一直这么这么记录下来就ok了,然后就是说我记录多少次方,那就是保留前多少阶的局啊,这么个意思好吧,那从这嗯,这个最最最直观的这么这么一个结论上来看,大家就可以看到哦。
那v s s m做了件什么事对吧,那它其实就等于用了前两阶的局嘛,因为前两阶的局呢就是就是任何一个点嗯,就是shadow map上面任何一个像素,它对应的x和x的平方嘛,就是深度和深度的平方吗。
还记得吧,而用这两个两个像在一块儿一倒腾,我就可以倒腾出来一个呃,virus就是它的分差对吗,就这个意思,那么我自然而然可以想象,那如果我多记录几阶呢,那它记录它的三次方,记录它的四次方。
那我是不是对这个分布,对这个分布,它的它的这样一种一种估计就更准了呢,诶答案是的,然后但是这里呢我并不打算跟大家说,为什么是的好吧,因为这个过程实在是太复杂了,就是说我直接给大家到结论这里什么呢。
就是说如果你保留前m阶的局,那么它嗯就是用这几阶的局啊,它就可以表示一个函数,一个什么函数,一个由一系列的这些接节约函数,堆起来的一个函数,并且它能表示几个台阶呢,它能表示二分之m个台阶啊。
这么有意思啊,这直接讲着这个听起来有点难懂,但是呢很简单,看图就可以看出来了,我们要表示的什么呀,还记得吗,要么是pdf,要么是cdf对吧,就是说pdf的话就是正态分布。
cdf呢就是一个就一直往上升的一个函数嘛,这两个呃一样的,最后我们肯定要用的是cdf吗,那这里面呢咱们就假设哦,这里我可以用前m结局去描述这个呃这个函数,一维的一个cdf。
那这个cdf呢哎大家可以看到呃,哪一个是用前四阶局描述的函数啊,这个绿色的线啊,深绿的一条线,这这里一个光滑的深绿的线,然后说清诶我的鼠标真糟糕,我老是想着我鼠标在那啊,这里啊深绿的这么一条线。
ok大家可以看哎,ok所以大家可以看,这里面很明显有两个台阶嘛对吧,有两个台阶,那这就意味着说哦这个函数我用四个呃,前四阶局就是z z平方,z3 次方,z4 次方诶,我就可以描述这个函数。
也就是说给我这四个数啊,我立刻就可以恢复出这么一个cdf来,我有这cdf之后,那可就为所欲为了,对不对,那不是所有的这些这些查询,有百分之多少的东西比他比他大,这个cdf立刻就可以告诉我了对吧。
那所以说嘛这就是呃这个举这么一个概念,说白了什么,刚才有同学说的太对了,就等于某种展开没问题,就跟什么泰勒展开啊,跟那些什么什么傅里叶展开都是一个道理的,就是说我就把它展开成前多少项,那我这前多少项。
那我有可能不能恢复完整我之前的函数,但是我至少可以做到一,恢复成一个什么样的函数,那对于举来说就是这样的,我保证前呃呃保留前m阶局,我就可以描述一个由由m除以二个台阶,的一个函数。
这是非常方便的一件事情对吧,那所以说呢诶呃嗯就是说呃我之前说过对吧,他这个作者就是crystal peters,他算是我朋友啊,然后他这个啊呃他做的这么一个呃呃工作,然后他发现正常情况下。
咱们用四阶举购这些举,也就是说表示两个台阶已经足够了,然后呢他还这个唉跟pcf做了一个比较啊,pcf那得到的一个结果就是哎类似这样的,那它四阶的矩a挺相似的,非常不错。
那p c f们就可以认为是挺准的了对吧,就是除了有一点噪声之外,那么大家会看到,但是像这种三阶三阶,你算什么一个半台阶嘛,就是说它会比这个呃四阶要差一些,比两阶的好一些啊,只能这么说啊,这么个意思好吧。
然后呢哎他如果用前两节,那这就是virus shadow map嘛,对不对,然后呢大家可以看到,那这恢复出来的cdf和实际的是分布的cdf,就差了好多了对吧,诶那所以说嘛就是就是这么一个思路啊。
那当然大家可以想象到,我用的举当然越多越好咯,越多就越准呢对吧,而我们想要什么呃,这这里有同学说的呃不完全正确哈,就是说展开了会过拟合,我们要的就是过拟合没问题吧,我要的是真实的分布呀对吧。
他越真实越好呀,所以当然是越多越好,但是呢越多越好,他肯定他他不能无限多,多了都要存储的对吧,大家想一想,我每一个pixel我都要存储,原来是深度,然后用vs s m的话可以深度平方。
那现在用举的话和三次方四次方我都要存的,是不是存储就往上要涨了,对不对,那呃但是没关系,就是说反正就是说呢,这个思路就跟v s s m就非常像了,我用motlemap无非就是增加了这么两项,然后呢。
让他能够对这个分布有一个更精准的一个估计,那那vs sm做的是两部block search和pc f他都可以做,没有问题对吧,然后呢嗯哦这里顺便多说一句吧,就是说像这种数字挺多的,如果说不考虑精度的话。
工业界有一个常见的做法叫做packing,and i’m packing,意思就是相当于是我有两个,比如说呃float 32位的两个数吧,我可以把它给表示成半精度的,就float 16星。
然后把两个float 16给拼在一块,还作为一个float 32的channel去存,那不是省一半存储吗,哎这些都是一些常用技巧,甚至有一些划分到那个具体多少位的啊,这么个意思。
然后就是说这块肯定是嗯有很多工作在做的啊,我就说一点,这这这什么呢,你如果这样做了之后,你就不能插值了哈,如果差值的话,那这个就没意义了吗,你两个16位的东西拼在一块,然后得到一个32位的。
你又重新解释这32位的,某是某一个其他什么数,你在差值的时候把它当成一个32位的数,这差值中间值就全乱了,这么个意思啊,说一下,这就是工业界的一个做法,packing and packing啊。
这两个小小的一个事情啊,然后呢呃就是说总结一下moon channel mapping,那当然他能得到非常好的结果,那咱们看vs s m,或者说他这里就管它直接叫vance shadomapping了。
无所谓,vs m也是他,那么这里大家看到哦,这里light leaking非常严重的现象,对不对,然后但是在moon shadow map里面是非常非常干净的。
他就说这边完全不会有shadow shadow呃,不是light leaking对吧,这个意思,那么问题咱们刚才说了,存储存储也许不是什么问题对吧,也许说我这啊我就这挤一挤对吧。
就是总归总归我用刚才我说的这么这么些呃,什么方法,然后我可以节省一些存储,甚至存储都不是什么问题,但问题更多的是什么,这是我刚才没说的,给你前四结局,你怎么得到那么一个有两个台阶的函数哈。
这个事情是一直没说的,对不对,而算这个东西是非常非常复杂的,然后这块来说,如果大家要看的话,就只能是从呃从peter的这个啊,呃ristopher的这个paper里面看了,好吧。
然后然后就是这么一篇paper就叫moment channel mapping,然后这块的话嗯,而平常大家如果初学这块的话也用不着啊,而且确实paper写的也比较难懂一点。
然后但是嗯就有用的东西还是挺多,我觉得工业界的朋友们倒是可以多了解一下,好吧,这是我个人建议了嗯,到此为止,今天的内容就讲完了好吧,然后欢迎同学们呃再问一些问题哦,我再停一下好吧,那同学问题的时候。
我再简单说一下,下节课我打算这样,如果有时间的话,先讲这个所谓distance field呃,这个这个这个软件到底怎么回事啊,然后就是说为什么这个现在大家开始在用,我也不知道之后会不会用的更多啊。
还是怎么着,这是一个,然后另外一个就是说,我们要开始进入到下一个话题了,我们要开始说环境光环境光照了好吧,阴影差不多了,嗯大概就是这么个意思啊,我来看看啊,目前我没见到有同学有什么其他问题。
当然有可能是因为我卡了呗,哈哈那我就先这样吧,今天确实是因为sirh的事情嘛,挺开心,然后跟大家聊的东西也比较多,哈哈呃行啊,这个非常感谢大家理解,然后以及大家能够听我在这说这些事儿呃,行吧啊。
然后希望大家这个能够跟我一样开心啊,这是好东西,大家分享啊,好心情,大家分享这个意思好嘞。
那嗯咱们今天就到这儿啊,哦作业一的话,我刚刚说今天如果不行的话,就看明天吧,好吧好了,sdf的梯度对,打扫时看吧,好吧行吧,感谢同学们,我下播了哈啊给同学们赶紧吃饭吧。
GAMES202-高质量实时渲染 - P5:Lecture5 Real-time Environment Mapping - GAMES-Webinar - BV1YK4y1T7yY
哦亲爱的同学们大家好,欢迎来到我们的games 202的第五讲啊,今天我们会讲一个新话题啊,这个新话题是关于说实时的,这叫什么呢,环境光照应该怎么样去处理好吧,嗯然后呢在今天的课程之前。
咱们还是说几件事情,第一呢就是作业一啊,我我以为已经发布了哈,行就算是没发布,今天肯定会发布,然后呢差不多呃有一个半星期可以做呃,这个作业啊差不多呃十天吧,这样嗯然后这次作业呢就是关于pcs的。
然后大家要去实现一个正确的pcs s,在这之前还会先实现shadow mapping,这么个意思,就是差不多就是阴影的主流的思路,那么呃另外一件事情是这样的,就是我之前不是说关于4月1号的那个星期。
也就是下个星期了,下个星期呃我这课要怎么个安排法呢,我之前想的是说我先录播,然后录下来,然后播出呃,但是后来呢嗯一方面有同学反映说,希望还是能够直播,另外一方面是我自己发现。
我好像没什么时间在下周之前先把它给制作好,录好,所以呢那咱们就这么打算吧,那就是说呃嗯下周我们就不安排课程了,也就是说下周没有直播,也没有录播啊,下周我自己的这些呃出差的事情,等我回来回来之后。
也就在下下周呃,我们会继续呃恢复我们的直播好吧,这么安排,至于说这课会不会往后再拖一个星期,会影响到siggraph asia,我之后再安排吧好吧,因为我之前嗯认为说呃,五一的那一周我是不播的。
但是五一那一周我是可以录播下来对吧,嗯所以说这样的话感觉又可以省出来一个星期,所以好像还行啊,那暂时咱们就这么安排啊,下周没课,也就是说呃今天第五讲对吧,第六讲讲完,第七,第八讲将会在下下周来讲好吧。
ok那这是这事儿,然后呢关于之前同学们问的,关于gains 101作业重新提交呀,重新批改呀,最后重新发证书呀,啊这个事情也是一样,等我回来之后,我就会开始启动这么一个过程。
那就是呃games 101的grader,我需要去呃呃面向大家去征集一下,然后如果有同学是呃有意向来呃,就是帮后续的电上电子101的同学们,去批改作业的话啊,这块嘿嘿嘿呃呃尽早联系我吧。
虽然咱们现在还没有开始发布这个,正式的正式的消息哦,对不是联系我,应该是联系到技术秘书同学,这样吧,大家稍等啊,然后等我到时候发布这个正式的消息,然后嗯大家再踊跃报名好吧,那咱们这么安排ok啊。
至于什么要求什么东西,哎这之后再说吧好吧,咱们暂时现在先这么打算着好,那这就是呃课前咱们要说的事,那么上一节课咱们说了什么呢,咱们上一节课主要是说了一些关于呃。
嗯就是pcs s的一些更深层次的一些理解对吧,一个非常聪明的做法,就是vs s m啊,然后也有人说是vs m一回事啊,vance soft gentlemapping,然后他呢就是针对性的去解决。
pcs中第一步跟第三步,这两步呃的比较慢的这么一个问题,然后呢他非常聪明地使用了这种范围查询,然后呃就因此去避免了采样嘛,就是这么一个思路啊,然后我们又提到他的一个相当于延伸版本,对不对。
然后呃引入更多的呃,就是更高阶的所谓moments这么个意思,那这就是上节课所说的内容,基本上来说啊,咱们上节课做过这个总结对吧,就是说vs s m在最近特别是在这个temporal呃。
dnoisy这么一系列的方法提出之后,呃,可能用的渐渐的就没有pcs用的多,但是为什么咱们要学呢,就是说v s s m,是一个非常非常非常聪明的做法,咱们学的可以让我们更聪明,对不对。
体会一下为什么别人可以想到这么精妙的算法,这个非常有趣的一件事情,好吧嗯那差不多就是这么个事情,那么今天呢咱们会先想办法把shadow这块给说完,shadow这块呢我们还缺一块知识啊,这块儿什么呢。
就是说我们呃,我们的这个现在刚刚开始兴起的一种新的呃,呃生成软硬的方式叫做distance field shadow,soft,distance field south shadows啊。
这么一个方式呃,然后这块我们肯定是要说一下的,因为这是我觉得吧,就最近几年内应该会得到更加广泛的一个应用,特别是这个distance field最近研究的人是非常多的,而且是跨各种领域的什么几何呀。
呃渲染呀,都在研究这么一个东西啊,从不同的角度吧,什么个意思好吧,然后所以说咱们一定要说一下,非常有用的一个东西啊,那么另外一个呢就是说我们说完之后,我们就开始来讲另外一个所谓环境。
光照需要解决的一些问题,然后环境光照呢是一个挺困难的一场,然后咱们今天大家会发现,这课的难度好像已经降不下来了,这我在这嗯就准备这些课程内容中,也是发现了这么一个事情啊。
因为没办法像啊实时渲染这么复杂的一个话题,他就首先要求大家对这个渲染领域这就比较熟,然后才会有各种各样的操作,大家会看到这呃,今天要讲的所谓split sum这个方法,然后它是它是非常非常依赖于大家。
对以前知识的理解的好看,那之后我们再继续说,好吧嗯那行,然后呢最后最后最后如果我们有时间提,据说环境光照下的阴影怎么做,哎那咱们先看这个标题哈,这标题可不是打错了,这说的清楚。
就是说我们要解决的今天主要说的环境光照,要解决的是所谓shading问题,是忽略了他的shadow的时候要解决的shading,好吧,这么个意思,然后之前至于这俩什么区别,咱们之前老早就说过了。
赶紧g101 对吧,ok那咱们这就开始吧,在这之前我看哈,诶有同学说我今天会不会讲spherical harmonix呢,答案是不会哈,今天不会讲,很快就会讲到啊,这个意思哈哈哈哈哈哈嗯好吧嗯。
补充材料链接说得好说得好,而且我之前这几节课,是不是就应该把链接放出来了啊,有道理啊,啊这样哈,我记得这事儿,然后助教同学们之后在课后如果我忘了,记得提醒我一下,好吧,ok啊对啊,有同学说的对。
今天要讲的叫做i b l之后,咱们再看具体什么意思吧好吧。
那咱们先进入第一个话题,第一个话题要说什么呢,要说呃distance field of shadow,那么首先还是一样,咱们说一下为什么我们要讲distance field of shadow呢。
因为这个东西可太好了,ok啊,为什么呢,大家可以看到啊,s d f呃,他的呃推特啊,还有twitter,然后说s d f shadow呢,它有什么好处呢,哎说的非常清楚,非常快对吧。
比现在传统的shadow map要快,然后说说为什么堡垒之夜没有百分之百的用它,是因为它的存储是有个问题的对吧,诶那那大家就看到了一个好处又坏处了,已经对吧,首先呢它呃它很快。
然后另外一个它需要大量的存储啊,然后如果说要想结合现在的技术应该怎么用,咱们这个就不多说了,好吧嗯嗯然后后面他就是说吧,就是说这后面的啊,如果有一个非常复杂的这种几何。
然后我其实呢我用sdf shadow可以达到嗯,这是非常复杂的几何才能达到的效果,然后我得用三个shadow map才能做到的效果,哈哈哈说这事儿,所以呢不管怎么样啊,这是非常好的,然后后面总结说。
还不会有这些什么自遮挡问题啊,没有什么呃这些阴影的悬浮的这个问题啊,咱们之前都提过,对不对,ok那这就是为什么我们要说这distance field啊。
然后呃呃然后咱们先看一下效果吧对吧,先看一下distance field soft shadow,那他顾名思义了,他首先他要做的肯定是软硬硬的生成对吧,然后大家看左边这幅呢。
就是用所谓的distance fields来生成的啊,这么一个软阴影,然后大家看效果非常不错嘛对吧,然后比起这个所谓hot shadow效果要好很多,那么它到底是个什么意思对吧。
咱们之前在game 101简单提过呢。
那么distance field或者是distance function,这是一回事,然后他是干什么的呢,它定义了啊,在空间中的任何一个点,空间中的任何一个点,他去定义啊,他到某个物体的表面上呃。
最近的一个点的距离,或者说它到物体表面的最小距离啊,这是完全是一回事,对不对,然后呢这个距离长呃,signed distance function,它有可能把它给定义成一种呃带带正负号的。
带正负号是什么意思呢,就是在物体内部,比如说我规定呃它得是负号,然后在物体外部它得是正号,这样的话呢它不只定义了一个距离,还定义了一个所谓有向距离,所以说嗯通常我们说距离场。
然后我就直接把它给缩写成s d f,它不管它是不是有像哈,然后就是说呃我就这么说了,好吧,sdf我指的就是这么一个距离场,那咱们下面看到有两个这个例子哈,啊就是大家可以从这个图上推断。
就可以看得出这是什么对吧,这这就是字母a哈哈的这么一张图,他的呃距离场,那也就是说啊呃这张呃这a的字母啊,打到了一个图上,然后这个图上的任何一个点呢,我都可以计算这个点到呃,比如说字母a的轮廓上对吧。
在这二维的情况下,我们说物体表面那是什么,那就是物体轮廓对吧,到物体的轮廓上最近的一个距离是多少,那么呃这两种仅仅是不同的可视化方式,左边呢就是把它的值直接给打印出来,大家可以看到在这个a的内部的时候。
它就把它显示成黑的,然后在这个a的外部的情况下,也可以看到,那随着不同的点离这个a字母越来越远,它的值应该越来越小对吧,看起来就像是一个很模糊的一个东西,诶非常有意思的事。
然后呢啊啊右边是另外一种可视化方式,这种可视化方式被广泛应用在地图上啊,这前咱们games 101都说过对吧,这是类似等直线的一种方式,类比于地图的等高线嘛,就是同样的一个颜色表示的值是一样的。
大家可以看到,基本上就是这个呃轮廓往外扩了一圈儿,一圈儿嘛对吧,所以说啊distance function它就是这么定义的啊,这个意思ok嗯好我先看一下啊,嗯嗯有同学说这个符号距离函数嗯行挺好的吧。
我觉得翻译的不错,s d f t度哦,对之前上一次就是同学说了这事,后来想了一想,不讲了,不讲这节课东西有点多啊,sdf梯度不讲啊,说清楚。
ok那咱们啊这就开始吧,ok下一个话题就是什么呢,就是说我为什么要用这sdf呢,因为s d f是非常非常有用的一个东西,然后咱们之前在game 101里面,做过这么一个例子哈,做过什么一个例子。
之前我画的不怎么清楚,于是呢我重置了这么一个这样ppt啊,大家可以看一下我这个例子是想干什么呢,我这个例子是想去呃,所谓去blend一个运动的边界好吧,咱们可以认为这个a和b呢它就是两张图。
然后这张图呢,它左半边它有一个物体刚刚移进了这个图,并且这个物体呢它在从左往右再移动啊,这么个过程好吧,那么假设在这个a所代表这个时刻,而这个物体在这,大家大家可以看到这边界啊。
就是这个黑与白之间的这么一个分界线,这个边界在这,在大概在靠左的这1/3的部分吧,啊这里对吧,然后呢这个物体在另外一个时间诶,它移动到了某个位置在这,然后大家可以看到哦,它的边界呃,移动到了这里好。
那我们这两幅图都可以得到吧,我假设说可以拍这么两张图,对吧好,那我拍下了这两张图之后哦,那我如果可以把这两张图做一个线性的差值,什么线性差值啊,每一个像素咱们说清楚,每一个像素都取在对应的a的位置。
和对应的b的位置,然后它的值,然后中间做一个所谓线性的一个平均,咱们就认为50%,50%的平均好吧,那这样会造成一个什么结果,大家看就得到右边这张图了对吧,线性差值a和b,那这样的话。
大家看到左边这1/3为什么是黑的,因为这是任何一个点,在这a也是黑的,b也是黑的,没错吧,比如说咱们鼠标停的这个位置,这个位置在a之前是黑的,在b之前是黑的,那最右边也好理解,我鼠标停的这个位置呢。
它在呃a之前,他他在这个位置是白的,b这个位置也是白的,然后在这中间坏了,这就出事了对吧,什么时候呢,大家会发现哦,在这里之前在这a的位置上白的,在b的这个位置上黑的,然后他一平均好了,变灰了。
那就变成了这么一张图对吧,哎所以说我我简单地对它得到这么两张图啊,做一个平均,我并不能得到一个移动的呃,一个一个边界,对不对,哎,我得到的这个东西,就看起来就像是它形成了一个灰色的一个。
过渡带了一样对吧,这个意思,所以这自然不是我想要的咯,那我想要的是什么呢,或者说有什么办法可以让我还是做这种呃,线性差值,但是我却可以得到一个在中间的一个边界呢,对不对,那这个时候呢咱们看一下。
如果说我们可以把a给转变成一个呃,所谓它对应的s d f,咱们刚才说了s d f嘛,有有效的距离吗,那么我们定义在物体内部呢,也就是黑的部分,假如说他颜色它都是都是,这叫什么呢,都是是负值啊。
然后在右边都是正的值,然后随着它的值,随着它啊这点的不同位置啊,离边界的不同位置,然后我可以给它一个不同大小对吧,这是没问题的,那所以说a转换成对应的s d f它是长这样,那同样楼里b转换成sdf。
它长什么样的,长这样对吧,然后大家可以看到s d f什么时候是零呢,就在这边界上是零,然后在左边呢它就是负的,再右边就是正诶,那这个时候如果我把sdf啊,这俩s df给重新做一个线性差值,还是一样。
在任何一个点我都计算哦,它在a这个地方sdf的值,然后在b这个地方s d f的值,并且求于平均诶,那这样的话我得到一个什么呢,大家看这条线啊,这条线正好在中间诶,那我之前取呃,在a对应这个中间的位置。
它大于零的,假如说它的值是五,然后呢我去找这个b对应在在这中间这个位置,然后它就值多少,假如他是-5,唉然后我发现它正中间正好应该是零对吧,诶,那所以说我得到了这么一个差值,之后的这么一张图。
然后插值之后,这张图呢之后我再根据他sdf所表示的性质,对sdf什么时候表示的是物体的边界呢,在sdf等于零的时候是物体的边界,在这个时候我就会恢复出这么一幅图来,然后我发现哦,原来如此。
我还是线性去插值哎,对应的s d f,然后我再恢复出来一个结果,那这个时候就反映了阴影在移动啊,非常有意思的一个事情对吧,那也就是说啊它有一个非常不错的性质,它可以表示物体的边界啊。
虽然咱们这节课用不着啊这个意思,然后这就是说人们喜欢这个啊,distance function是因为什么呢。
因为它可以做任意不同形状的一种,一种所谓不ending,而呢你不需要去关注这个哎,你不需要去关注他们之间的所谓拓扑的关系,比如说大家可以看到诶,我有两个不同的s d f,然后大家可以看到很明显的一个球。
在像一个这这正方形去移动对吧,然后如果说我们把他们两个各自都转换成a,distance field,然后我再去blend诶,然后呢,我我就可以把他们最后最后给融合到一块,这是非常有趣的一件事情,对不对。
所以说他可以得到几何上的一个,非常好的一个过渡,那这也是为什么人们会喜欢这个sdf啊,这个意思啊,那么这个时候呢我多说一句吧,既然这是一个提高课,这个sdf呢,它的背后和一个理论是非常非常有关系的。
这个理论叫做optimal transport,叫最优传输这块儿呢,这个顾险峰老师研究得非常透彻了,这是呃应该是能够找到非常不错的一些资料,好吧,然后咱们就简单说一下。
就叫做optimal transport或者叫最优传输啊,这个理论嗯,就是说这块呢也是算是学术前沿,我个我个人来说也是哎非常呃,对这方面也有兴趣,不过呢我是希望把它给弄到。
这是在rendering的层面上能够有一些应用啊,当然也也也在研究中吧,可以这么说好吧,呃咱们回到distance field的这个呃事情上来,那么distance field有了对吧。
然后呢我们怎么用呢对吧,那那首先呢给大家提供一个呃,最简单的一个用法,也是他的第一种用法,第一种用法叫什么呢,大家耳熟能详的呃,ray marching。
ray marching是一个经典的去所谓呃去用光线追踪,然后一去追踪一个距离场,然后看我会打到哪个物体表面这么一个思路哈,然后呢啊这个之前呢咱们101里面并没有说,所以这里面简单提一下呃。
但是我知道201简单提了一下对吧,就是说因为它实在太简单了,这个即便不是running领域,我觉得这块也是非常非常好理解的哈,就假设说啊整个场景的sdf你已经得到了好吧,然后你有这个sdf之后呢。
你现在有一根光线,因为这根光线你试图去嗯做一个事情,就是这个光线和sdf所定义的隐含表面,去做一个求教,这怎么样怎么样去求教呢,那这个时候提供一个方法叫做sphere tracing。
这是一个最最简单的直接的一个方式,那么它的一个最最有意思的一个思想是什么呢,就是说他背后是是用了这么一个规律,什么规律呢,咱们比如说这个这个位置哈,你这个s d f它到底告诉你一个什么样的信息。
那s d f咱们刚才定义什么来着,就是说这点到呃,比如说这个场景中其他的这个物体,它的最小的距离,那那既然是最小距离,那说明什么呢,比如说在这一点,他告诉我哦,这是他到场景中其他物体的最小距离。
并且咱们知道在这儿对吧,但是呢它隐含着告诉我们这么一个事情,也就是说在这么一个最小距离之内,你不管这个这个点它往哪儿去,他无论如何不可能与任何物体相交,否则就意味着,一定有一个物体在这个范围里面了。
所以那这个s d f就就记录的纸质,不对的对吧,就是这个意思,也就是说啊,它任何一个点嗯,上它的sdf的值,就给你定义了一个任意的安全距离,不管你往哪个方向走,你只要走的距离不超过这个距离。
它一定不可能与任何物体发生碰撞,是不是一个非常这个聪明的一个一个想法对吧,哎那就可以利用这么一个思路啊,我们为了去做re s d f tracing对吧,是这么个意思,那我一开始有个光线。
它的起点在这儿,它往这个方向去,那我一开始就看他起点上告诉我s d f是多少,那df告诉我哦,大概是这么大,然后告诉我这么大的话,那我就可以放心的把这个呃,这个点给移到它对应的这个方向。
然后走那么长距离这么个地方,因为我知道这个时候它一定不可能发生任何的,相较对吧,然后在这一点呢,我又可以查到他一个s d f,我又知道他往前面走,那他的s d f的直邮告诉我。
我可以往前走多少的安全距离,是不是这个意思,所以说直到我一往往前走,走到什么时候停呢,那我就走到要么和这个物体足够接近了,也就是说它的sdf小到一定程度对吧,要么我光线已经往前去踹死了非常远的距离了。
我还什么都没踹死到呢,那我就不要了对吧,就扔了,差不多就是这么两种思路对吧,所以说这是非常聪明的一个做法对吧,然后咱们总结一下意思,就是说不管任何时候你在p点啊,假设任何时候你在p点。
然后这个p点你都可以从这个p点,往你给定的方向,还有去嗯,往前走呃,往前走,s d f of p那么个距离对吗,就是这个意思好,那这就是他的啊,就是使用方法一吧啊咱们来看看哈,有同学说什么啊。
哦有同学说算sdf是吗啊,ok那这块是我刚才没说了,就是说我这里是假设说sdf就已经有了吗,那sdf咱们我是想着,咱们在最后它的不足的地方,我们再说他这个事情哈,那现在提一下也可以吧,就是你这样想吧。
sdf它的本身的定义,是不是就定义在空间中任何一个点,然后他要定义到呃,你这比如说场景中任何物体表面的最小距离,对不对,那也就意味着sdf如果在一个三维场景中,sdf可是一个三维的一个值,对不对。
他任何一个点嘛,所以说嗯嗯你要是想表示所有的这些面啊,然后呃他其实是二维的嘛,咱们之前说过对不对,考虑一下texture mapping,那那么你要是sdf的话,那就是这个场景中任何一点。
你首先就得先把他s df给算出来,然后呢你要把它算出来之后,你还要涉及到存储,你要存储一个3d的一个呃巨大无比的格子,要覆盖整个场景,是不是非常大的一件事情对吧,当然这中间有优化了,但不管怎么样。
反正这个存储是非常高的,咱们在一开始这个推特就见到了,对不对,说它的存储是个问题啊,那咱们讲完这块之后,我简单跟大家聊一下,聊一下现在有什么有什么方法再做呃,sdf存储的压缩或者其他东西,好吧。
这个意思呃,运动的物体是实时计算s d f吗,这个问题是非常好的,那么哎也是一样,它其实是s d f的一个局限的东西,就是运动的物体是可以的,s d f是可以用的,没有问题呃,但是形变的物体是不行的。
形变的物体就是说你得保证啊,把这个物体的sdf就得重新算一遍呃,至于说他这重新算一遍呃,需要多大开销,有没有办法能根据它的形变,然后我只需要计算它改变了的部分,那这就是另外的事情了。
那就是几何这边在研究的事情了,好吧,那么刚才我我为什么说,运动的物体其实是可以的,如果是刚体运动的嗯,这这个事情呢其实是一个sdf的一个非常好,非常好的一个性质什么的,比如说你场景中有多个物体。
你每一个物体都单独算了一下他们的s d f,那你现在要做光线和整个场景的求教,你在任何一个点的位置上啊,你其实就只用去呃去取所有这些物体中,s d f最小的那个就可以了,为什么呢。
因为这个道理是显而易见的嘛,就是说嗯大家可以看到每一个物体都告诉你哦,我当前的这个位置,然后离这个物体最小的一个点,那么我如果取所有物体在当前这个点上,它的sdf的值的最小值。
那不就是等于是在这个场景中,我这个点呃离场景中的任何一个物体,它的最小的距离嘛,对不对,这个最小是非常好用的一件事情,所以说呢呃就是多个物体,只要取最小的sdf就好了没,但是话又说回来。
刚才我说的形变的物体确实不好做啊,这是这是这么一个意思吧,好吧啊那行,那咱们回到这个话题上面来,呃刚才提到说呃,它的最直接的应用就是所谓ray marching,那么咱们今天要介绍的就是它的第二个应用。
第二个应用是什么呢,用它来生成呃软阴影,那么用它来生成软阴影是什么意思呢,那咱们之前说最早最早说的时候,game z101 就提了,说软阴影怎么来的呀,是不是就是因为有一个面光源,然后他有很多东西啊。
它有一部分吧被挡住了对吗,然后它被挡住了多少,那自然就是最后的visibility的值是多少,诶我想想一减visibility值是多少对吧,就是这个意思,那么呃所以说呃在这里呢。
我们可以用s d f来近一似的,得到一个大概有多少范围会被挡住,这么一个信息,然后但是它是不准的,咱们先说清楚不准的,但是是挺挺,这个符合咱们的一个一个一个观察的好吧,那这是什么意思呢,这里再看。
这是呃最重要的一个理解是什么呢,就是说啊之前在第一步,他会给你个安全距离吗,这里就往后稍微推一步,这这个理解是这样的,他的sdf他告诉了你一个安全角,都什么安全角度,咱们大家看右边这幅图。
那右边这幅图说明了什么问题呢,诶我有一个假如说我有一个所谓shading point,然后我往往某一个方向去打了一根光线啊,我打了一根光线,然后这个时候沿着光线中间有一个点,大家看到了吗。
这个点上假如说呢他有一个呃s d f的值,它有s d f的值,告诉你哦,这个点周围大概多多远是没有障碍物的,是这意思吧,那么这个时候就可以告诉我们,如果你从这个所谓shading point网。
大概这么一个方向看啊,大家看shading point往这个方向看,那我其实可以稍微偏一点,我再再多偏一点,我一直偏到这个位置上对吧,偏到这个方向上,然后我觉得都不会看到障碍物,没问题。
这还是刚才的所谓安全距离的一个呃,简单的一个延伸,把它变成了一个所谓安全角度对吧,我往左边偏这么些都不会有什么物体挡住,那我再往左边偏一些,那就会呃被挡住了一些了,那就是这么个意思了。
那呃随着刚才这么一个理解呢,我们就可以得到一个非常非常有用的一个观察,什么呢,就是说如果你在呃某个shading point上,往一个方向上去,你得到的这个所谓safe angle。
就是就是这这个角度吧,这个角度越小,就意味着你呃能够看到的东西越少,就是这么意思,或者说你看到的这个阴影就越黑嘛,就是这个意思吧,这没问题对吧,所以说呃这里呢就是相当于是简单的把嗯。
s d f可以给你的一个所谓安全角度,把它给转换成了最后阴影的值啊,就这么一个简单思路哈对吧,咱们再再再回顾一下这个事情啊,如果说你在这一个点,然后它的安全距离告诉你它有很大的圆。
然后就意味着一个很大的安全角度,有很大的安全角度,说明你往这个方向去看过去啊,你看一个呃挺大的一个光源,你可能中间都没有任何遮挡对吗,那就意味着你最后可见性基本就接近一一对吗。
哎那如果说这个范围呢呃它非常小,就像这种情况下,你再往左偏那么一点,那那那就那就会出现一个遮挡的情况了,那就那就说你在这种情况下呃,就是说如果你再trace一个,比如说还是刚才一般大的一个光源吧。
那这里就意味着这个光源,有很多东西要被挡住了,那就意味着说你的vb会减小对吧。
那基本上来说就是这么个思路嘛,那也就是说我们其实要关心的,就是在这个remarching的过程中,然后我如何去得到这么一个所谓安全角度对吧,那这个安全角度大家看这幅图就可以看到了。
嗯就是假设说啊你是从呃这个o点出发,然后呢你每次往前走那么一点,还是刚才的retracing,你沿着某一个方向去这个方向呢,你就给大家可以理解成,好吧,然后往这个方向去看看,这种遮挡情况到底是什么样的。
那么我我往前走,大概走到了p一啊,p一告诉我应该走到p2 ,p2 告诉我应该走到p3 诶,那么在这个过程中诶,我在p一的这个位置上,我是不是可以得到一个圆,得到一个圆,这个是蓝色的对吧。
然后我从这个起点,我可以做一个蓝色的这个圆的切线,我就可以求出来这个蓝色的角度c大一,这就是它的呃这个点上的安全安全角度对吧,然后呢,我在这个p2 这块形成了一个偶红色的这个圆,在这个红色的圆呢。
我一样我可以从起点做一条切线过来,然后诶我是红色的圆呢,这么这这么一想切,我就得到了红色的这么一个角度,呃,这个这个角度哦,那我每一个点我是不是可以这么做,那我这些点都各自可以求出来一个,所谓安全距离。
那总共的安全距离啊,安全距离,安全角度,安全角度是多少呢,那自然就应该是最小的,这个角度才是安全的角度吧对吧,那呃现在就是这么个问题了,就是说我们现在知道哦,我在锤子的过程中。
每一步我都算一个呃它的安全角度,我到时候取最小,这个角度一定上,一定程度上就能给我一个所谓这个阴影,到底是偏黑还是偏白,这么一个估计好吧,那留下来一个问题,什么我们怎么算这个角度对吧。
那么大家从这个图上可以看到,这个角度是挺好算的,为什么呢,因为你就再算一个圆的切线嘛,在空间中就是一个球的切线嘛对吧,然后呃这个切线怎么算呢,大家知道这个s d f的距离,告诉你是这个直角边对吧。
然后这个斜边就是你走的距离,然后所以说你只需要算一个ark sign就可以了,对不对,哈哈哈哈呃然后呃自然是可以这么算,但是呢哎这个时候给大家精神污染一下,ok是这样哈,虽然可以这么算,但是呢。
通常人们在shader里面是很愿意去,避免一些非常复杂的运算,比如说这种反三角函数,它们的运算量就非常的大,大家就非常不喜欢这么一个呃啊这个东西啊,不喜欢这个,那么呵呵呃怎么办呢。
所以呃就呃人们很聪明的提出了这么一个呃,做法,什么做法,咱们先不要管这个minimum。零的问题,咱们就看这中间这块在干什么对吧,然后大家看啊,之前arc sin在干嘛,就刚才那个直角边。
就是s d f长度除以你的斜边长度,就走不多远嘛,t减o嘛,就是这个距离啊,唉等一下啊好吧,这里忘了加这个长度了哈,这不是向量哈,这个向量的长度哈啊距离啊,ok这里也一样,就是两个距离相比吧。
那么一定程度上人们就是这样说,这两个比值就已经可以说明,这个角度到底大还是小了对吧,我干嘛要算那么精确,我算这个2x3 a这个东西对吧,没必要对吧,所以说呢,我这里就是说我完全可以就用这个比值。
就是刚才那个s d f的值,就是安全距离除以我走过了的距离,这就算是一个对这个角度的一个近似,我在上面再乘上一个k就可以了,然后最后呢我为了把它给转换成一个visibility,它不应该能超过一对吧。
就是就是这个意思吧,啊好吧,所以说大家做了一个呃,这种就是说我上面随便乘上某一个k,然后我最后得到最后的值,我再跟一点去比较,取最小就好了,那么这个有什么好处呢,这里就是说大家可以看到。
就是这个k的作用到底是在干什么,这个k的作用是这样的,就是说我既然最后反正要把它砍到一点,如果说我的k的值原本诶他就是一的话,那就什么也不做嘛,那我最后就是用这么一个比值。
然后他大概在01这么一个范围,然后我会得到的最后的结果呃,它的阴影的值诶就是01这么一个范围,这是没有问题的,那么嗯如果我有一个比较大的k,比如说k我取五,那也就是说这个比值呢在0。2的时候。
其实我就认为它的值已经达到一了,再大它也它也还就是一了对吗,也就是说这个比值我就只看0~0点二之间,这么一比值,而这个比值会告诉我哦,呃它的阴影会从零变到一,那如果我k我取100。
那我基本上来说就是就这个这个比值,在00点一之间,然后我就我就认为说呃00点零一之间啊,我就认为哦这块就是它的所谓过渡带对吗,然后它它的阴影值会从0~1,那么大家就发现了一个问题。
就是这个k的作用是在干什么呢,k大的话很小的安全角度也会被你当成是一,那么零和一之间的过渡带自然而然就会少,那那也就是说在一个极端的情况下,k极大的情况下,你就可以认为哦。
这种情况下就是完全是硬阴影了吗,要么零要么一了嘛,它中间过渡非常非常的小嘛,那所以说这种情况下,k呢大家已经可以猜测出来是在干什么了,k就是在控制这个阴影的软硬程度,好吧,哎这是一个非常聪明的做法嘛。
就是说我要通过这个k去决定说到底有多大,一个角度内是这个软阴影的角度嘛,就是这个意思,什么时候是完全在阴影内,和完全不在阴影内的一个过渡,我就这么简单的用一个k来做了,那这是一个非常聪明的一个做法嘛。
然后呃如果是我来做的话啊,如果是我来做,我估计想不到这么一个做法,如果是我来做的话,我为了减少它中间这么一个0~1的,一个过渡带哈,我的想法应该是应用一个所谓,sigmoid一样的函数。
那这款机器人现在很火的对吧,所以sigmmoid我就再也不解释它是什么了,西格诺伊德的作用是什么,大家想象一下,如果我有一个线性的一个函数,我应用了一个sigmoid,我的值会不会被拉到两个极端对吧。
一个是偏零,一个是偏一,这不正是我想要的吗,不是正正是想把中间的这个过渡带,尽可能的把它给缩小嘛,只不过呢sigmoid的计算它是非常非常麻烦的,然后他肯定不如说你就乘上那么一个k。
然后取一个这个和一点取最小对吧,不管怎么样,这里哈大家知道这个k的作用就好了,这个k的作用就是为了减少这个扮演的一个呃,可可能产生外形的一个区域,那这个区域被减少的越厉害,那阴影就越硬嘛对吧。
那所以说咱们就是这么一个解释方法,那么现在我看又有同学啊,这样吧,这样吧,我先把这块说完好吧。
那么说这么半天的话,就是说呃这个distance field到底应该长什么样对吧,咱们可以看一下,对于这个场景来说,大家可以看到这个场景,每一个物体应该都是有一个distance field的。
然后这些distance field就可以合在一块儿,咱们刚才说的对吧,都取最小就可以形成整个一个场景的distance field,那么这distance field大概就是一个。
看起来像是物体描了边一样的对吧,呃咱们刚才说了,为什么对吧,它基本上就是沿着轮廓往外面长嘛,然后越来越小嘛,这个值呃,唉然后大家看到的就是这么一个东西啊。
ok啊那么这里基本上就是说呃关于这个distance,field shadow是什么意思哈,好,然后呢,有同学说,这里是不是应该应该有两个安全角度对吧,刚才咱们画了这半边,另外半边对吧。
所以说这是一个非常非常大胆的近似嘛,对吧哈哈哈哈,基本上来说,就是随着刚才那么一个观察来来说的,就是呃如果说你在某一边。
而i s d f本来就不能告诉你它方向在哪,咱们回回两页吧。
好吧嗯,假设是这样,那你在这里呃,sdf告诉你有个安全角度,你其实真的不知道说阴影会出现在这边,还是出现在右边对吧,那如果是一个3d的情况下,你根本不知道它会出现在哪一个圆环里面去,对吧。
是不是这个意思,它只你只能说呃,我大概知道这个遮挡物,大概是在呃这一圈之外对吧,然后应该是在这个圈上哼,然后你你是不知道他在哪了,你既然不知道的话,那基本上来说你你这张图,它自然你看到的是一边。
那其实你不知道的情况下,你就认为是整个一个情况了对吧,然后所以说这种情况下,不去考虑这个遮挡物的位置,其实是有道理的,没什么问题哈啊ok好,我有同学问,是不是每一个点都要保存一套距离上。
哎这里说的不对吧,每个点会保存一个值,那就是他s d f的值,它既然是一个厂对吧,它在三维空间中任何一个地方都有一个值哦,说起来距离场,距离场其实说的是场是不对的啊,就是说他其实按物理意义上来说。
它只有一个值,它并没有方向啊,它并不应该是一个什么场,诶还是说我理解错了,厂是分所谓什么向量场合和那个厂的标量场的,啊,对他是是他是个标量场啊,那所以说它还是长啊,那是我错了啊,ok也就是随口一说啊。
ok啊嗯为什么面光源一条线就可以算了,不是同学是这样的,就是说这里是假设是这么一个概念,它仅仅是为了告诉你说哦,这个距离场给你定义的安全角度,基本上来说能够告诉你说,如果这有个面光源,大概他是这么大。
然后它大概有百分之多少是挡住,其实我们最后需要的仅仅是说这个角度的大小,本身能决定阴影的软硬啊,这么一个思路就是他并不需要说,我一定得在这儿考虑一个呃,真正的这么大的一个光源。
然后它大概覆盖的角度是多少,然后我这边安全角度是多少,我算一个比值,然后我认为呃,一这些所谓遮挡物会均匀的分布在呃,比如说这左边一列和右边一溜,或者是不需要啊,这么理解一下就可以了。
就是说你的安全角度越大,嗯得到的这个结果就应该会越软嘛,呃就这样说,得到的结果就应该越接近,完全没有被遮挡啊,这个意思得到的结果就是更偏白,然后如果说你这个安全角度非常小的话。
你得到的结果就会越来越偏黑嘛,这样理解好吧行了,那咱们这边呃这个问题就说到这儿。
就大家可以看到,这又是一个非常非常大胆的近似嘛,然后大家更进一步理解到说哈哈哈,实时渲染中间到底有多少各种各样的介词,那咱们总结一下哈,距离场去做呃,软阴影的话,它有很多好处,第一非常快。
这个快呢相相对谁来说呢,相对于说我要直接去啊,怎么说呢,两点吧,第一是这样,如果我我去做remarching,我去求所谓光线和一个隐含的一个表面的焦点,嗯在这个基础上,我是可以自然而然的就引入嗯。
这么一个软阴影的对吧,然后我我同样我可以假设说我有一个所谓shadow ray,然后往光源的中心去打,然后通过这种方式,我可以快速的得到一个呃软阴影,那么这个软阴影呢和硬阴影它的这个复杂程度。
在ray marching的体系下是没有任何区别的,所以我们说它非常的快,这是没有问题的,那么另外一点是有人说啊,这里啊嗯他这个快其实它是不是一个公平比较,为什么呢,刚才我们看那个推特啊。
不是说呃它会比真正的shadow map要快嘛,但其实嗯其实在这里的比较是忽略了,说呃呃就是距离场的生成的时间的啊,然后你如果只去用它的话,那只需要做remarching,那是非常快的,没问题。
在shader里面就可以写remarching,但是呢shadow map通常大家跟shadow map比较的时候,我生成shadow map,这个时间才是大头对嘛,就是说我查询的map。
大家知道就是一次texture query嘛,非常快的嘛,啊如果说我要做软阴影的,就是若干次也不慢的对吧,然后但是呢大家想如果我要去做ram marching,也就是几次去查询sdf而已。
所以说sdf非常快,然后呢他如果呃跟这个呃嗯shadow map,在不考虑生成他们的情况下,那这是差不多快的,应该这么理解啊,但是shadow map主要花时间是花,花在生成学都买不上。
因为你要把整个场景在rua一遍吧,这么个意思好吧,那么这就是呃这个事儿,然后之前我说了,就是呃嗯叫什么呢,就是说他也有他的问题吧,就是嗯大家可以看一下sdf的话,如果我去生成阴影的话。
那首先就是咱们刚才说的,那它生成s d f,这本身是一个预计算的过程嘛,然后呢生成了之后,我又要把它给嗯给给存下来对吗,然后我把它存下来,对于静态的场景,静态的或者刚体这些都是可以的,没问题。
然后对于动态的物体还不行,我这计算还得所谓嗯,就是说如果有一些形变的话,就得重新算它的距离场,这是非常麻烦的一件事情对吧,然后呢我距离场的存储,不管是对于什么样的物体,我算出来之后,这可是三维的。
三维这个东西存储就非常的麻烦,对不对,那差不多就是呃这么个意思,然后呢实际上它还会有一些artifact,不过我这里就不再多说了,s d f有一些什么在接缝处,各种各样的artifact的情况。
嗯这里是工业界比较关心的一个事情,当然不影响说我s d f能够给我,一个非常不错的一个高质量的一个软硬啊,这么个意思好,然后这里这里这样吧,我再多说一句吧,好吧,那就是说呃我们之前就说这sdf呀。
它生成之后是一个三维的一个一个啊长,然后它在三维空间中,任何一个点都要记录一个值,然后这不是非常非常麻烦的吗,如果我要存的话,我把把整个场景,然后我给非常密集的踩很多的点对吧。
然后这些点上它的sdf的值到底应该是多少,然后我把它存下来,我要等于存一个三维纹理嘛,非常非常大的一个存储,那么人们自然不想通过这种方式来存储,那么现在的一些方法在研究吧,有一些是这样的,就是对于场景。
类似呃hierarchy的一个东西啊,之前咱们都说过,像什么kdj啊,像什么呃,嗯这些任何空间划分的八叉树呀,像什么别的一些什么书都可以嗯,不同树形结构,然后我在不断往下划分的过程中,有一些这些格子啊。
基本上来说离这场景中绝大多数物体都非常远,既然离得非常远,但我根本就没必要计算或者没必要存了对吧,它呃这个值就可以认为是非常大啊,就是就是这样的话,整个一个点啊,整个一个节点。
它表示一个范围内我都没必要算的非常准,那按照这种方式,我继续往下划分,直到划分到我在物体的边缘那些地方啊,就是说distance field,它的值可能在一个node里面,变化非常剧烈的情况下。
我就划分的非常厉害,那这样的话我就最后形成了也一棵树嘛对吧,然后我就只需要把这复杂的这些嗯,呃s d f的值存在这些说的叶子节点上,以及说我要认为说如果啊在一个非叶子节点上。
它是嗯一个常数的一个s d f,那也是可以的,没有问题,就是说我可以定义一种hierarchy,自然是这样的,办法吧,这个事情啊毫无意义啊,这个意思,这我相信没问题,但通过这种方式只会增加他的。
就是所谓解压缩的时候的负担,就是你到时候要查询sdf,而且是要频繁查询,而每一次查询需要过一遍神经网络的话,那这个方法就不会不可能再有人用了,这么个意思哈,嗯差不多。
这是我的一个理解啊啊ok然后我看看哈,有同学有什么问题啊,这,这这,我先把这最后一个有趣的一个东西告诉大家哈,我发现了一个github的一个项目,我不知道大家是不是这个项目已经非常有名了,还是怎么说。
诶,但是这个项目是说你可以去在啊,实时渲染中间去做一个啊,做什么呢,做一个完全没有锯齿的,或者说完全无限分辨率的字符,大家都知道,如果我要在嗯,比如说一个场景里面3d的场景里面。
我在墙上我要显示一个字符怎么办,我要贴图对吧,我要用texture,texture肯定是要有分辨率限制的嘛,那如果说我可以把之前的一些字母,什么都转换成sdf的话,s df我如果在嗯比较精细的层级。
我还可以用一些什么曲线,什么东西去拟合它,然后我就等于说,我可以得到一个非常非常不错的一个嗯,就是抗锯齿轮的啊,这种呃就是在实时渲染中间的字符吧,这么个意思啊,我刚才说的不对哈,不是拿什么曲线去拟合。
而是去插值,做一个类似于平滑的一种过渡,比如什么三线性差值之类的东西啊,这样的话就不管怎么样,任何的分辨率离得远,离得近哈,都可以看到非常清晰的字体边界,挺有意思的一个项目啊,简单的大家说一说。
那么ok这里我来回头看看,有同学们嗯问了什么问题吗,ok哦有同学说计算空间中某个点的距离,尝试要遍历所有物体吗,而不需要吧,对就是说嗯就完全可以每个物体单独算,然后最后按照任何一个点。
都是所有物体距离场的最小值嘛,咱们这么来算,然后我有同学说这几节课来下来感觉全是近似,没问题,同学这一直到这这门课的结束都全是近似,但是哈是这样,就是说近似的目的,那肯定就是为了让他快嘛。
但是近似首先不会牺牲特别大的质量,另外这些近似都非常的聪明,对不对,ok sdf到底好不好用,sdf在做阴影的时候非常好用啊,没问题啊,嗯至于在其他的方面上有没有什么问题。
就就是说sdf生成的这个物体表面,非常不好贴纹理啊,就是它的uv或者说它的参数化是不好得到的,这块来说,现在大家在积极的研究中啊,呃s d f其他的东西好吧,其他东西我就不再说了啊,咱们就简单说一下。
他对这块这块儿实时渲染中的,软阴影的一点帮助吧,这么个意思,因为因为sdf它是确实是一个跨领域的东西嘛,就是说呃单独讲,我我自己来说也不可能知道的这么多啊,我就简单说到这儿吧。
至于它的生成真的s d f的生成,s d f的其他应用,确实都是其他领域在研究的东西了,我们就假设说呃在running这边,我就认为他是直接可以拿到的一个信息,好吧好嘞嗯行吧,嗯那那就这样吧。
好吧嗯这块咱们就说到这儿,那因为后面还有一个非常重要的一块,诶刚才有同学说sdf得到是真的阴影吗,并不是吧,s df得到的阴影会更加的虚假的,哈哈这个意思吧,呃因为从刚才的近似上来看。
大家可以看到这个近似比之前的我们做了什么,tcs要更大胆多了吧,嗯ok嗯行,那咱们这里嗯就继续下一个话题了,那就是环境光照,那是这样哈,大家看到现在才开始进展这么一个话题有点晚,诶嗯这样吧。
很有可能我我讲这块就讲一半吧,因为后面来说,行那这块儿呃,大家从标题上可以看到我们来说什么呢,哎我们要说环境光照的下,我怎么样做任何一个点,它的shading,也就是说不考虑shadow的情况下。
假设这个点,它从四面八方都是可以接收到光照的好吗,嘿嘿嘿嘿,环境光照到底是干什么的呢,对吧,那么大家看到环境光照嗯,咱们之前在电子101提到过这个事情啊,它其实呢就是说我可以用一张图来记录,在场景中。
我往任何一个方向看,可以看到的光照对吧,这样就没问题了,那这个中间呢它就隐含着一个概念,认为这个光照都是无限远的,来自于无限远的好吧,然后就是说它并不能帮助大家定义一个,我放置两个不同的物体。
这俩物体放置的位置不一样,但是他们接收到的环境光照却是完全相同的,因为这个环境光照,我们认为它是从无穷远处来啊,这么个意思,这也就意味着如果你有一个环境嗯,这个所谓贴图吧,然后他中间有有一个桌子。
然后你是不可能把一个什么东西给放在,这桌子上的,你要因为他会认为这桌子离呃,这个物体不管你放在哪儿,它都是无限远的,所以看不管是任何的环境,光照去渲染任何的物体,你看看着总是一种漂浮的一种现象啊。
咱们之前说过,就是说所谓怎么理解这种distant lighting啊,这么个意思,假设无限远好,那么它的两种存储方式,主流的存储方式,一个叫做spherical map,一个叫cube map。
各自的优缺点咱们就不再多说了啊,因为咱们这个课上就认为说好我不同的方向上,我能得到不同的这些光照就好了行吗行,那这样一来呢,我们要研究的问题也就出来了,那给你一个环境光照呃。
我现在我要放一个物体在这个场景中间,那我不考虑遮挡的情况下,这些阴影的情况下,我如何去把它的shading给算出来呢,这种这种呃操作啊,在工业界被叫做i b l。
也就是image base lighting啊,不怎么证实这种说法,其实嗯略大了一点哈,我个人来说,并不是百分之百能够接受这种命名方式,但是这毕竟大家就这么用了哈。
i b l或者就是environment lighting的意思啊,那么呃就是说我们现在要解决的,自然就是我刚才问的这个问题吗,就是说给了你i b l了,或者环境光照了,然后你任何一个物体。
或者说吧任何物体上的任何一个shading point,你如何去把它的shading的值给拿到啊,这么个意思,那自然而然对吧,自然而然大家就知道我肯定是要解running equation。
running equation,咱们之前在忘了第三节课的第二节课,咱们提到过这事儿对吧,render equation在实时渲染中间,我们通常会愿意把这个visibility像拆出来,然后这样的话呢。
这个lighting就表示发光的这个lighting,而不是实际到达的lighting,那么这里我既然又不考虑visibility,那这里就等于是环境光照,它来自四面八方的光照li对吧,呃就是这一项。
然后呢呃他是任何一个方向都有可能有光照的,但是呢由于我们的这个呃,running in quin的定义对吧,任何一个shading point,我当时只是考虑它的来自它的正的半球,它的光照了对吧。
这就是之前咱们说过什么call 3项,前面要加一个max 0嘛对吧,大家还记得这事,或者说我定义它的积分域在上半球,这上半球不上半球,定义是由这个学龄point的法间定义的啊,就是合法线呃。
点乘是正的这个方向啊,那咱们把这个说清楚,那么这样一来的话,基本上来说就是我要解决,从所有的方向都有可能有光照对吧,这个这个光照是多少呢,i b l已经定义了,我要把这个式子解出来,就那么多少,对不对。
ok那这里呢就是就是我要解决的一个问题,那那么这问题怎么解对吧,这问题咱们之前在game 101就说过怎么解对吧,是一个通用的解法,那就是用蒙特卡洛积分的方式来做,蒙特卡罗怎么做,我这里不再赘述好吗。
就是说对于任何的一个积分,你都可以拿任何的满足任何分布的呃,任何pdf的呃一些样本,然后我来对它做一个数值上的一个一个呃近似,并且这个近似啊,我们之前没引入过这个概念对吧,叫做无偏的。
我们就说它是对的吧,好吧对的,那么呃蒙特卡罗方法大家之前做过101,就会知道它需要大量的样本,然后才能让这个结果,最后收敛到他的所谓期望的值对吗,呃就是接近它的,实际上接近他的期望的值。
那么这里自然就会引入说我如果真的这么去做,那大家想一想整个一个场景,那里面任何的物体或者说任何物体的顶点,或者说任何像素我都要做一遍这个解,这么一个来自四面八方的光照,这么一个渲染方程。
那是不是非常麻烦呀对吧,我任何一个shading point,或者说任何一个fragment我都要做一遍,蒙德卡罗,那还得了啊,那得有多少个sample对吗,那自然而然造成的结果就会非常的慢对吧。
那哈哈,所以说呢通常我们会认为只要是在shader里面,如果大家平常写这些shader的话,写的特别是fragment shader,这里面一旦出现了三link,那么这个方法就很可能会不能被。
用在实时渲染中,但是诶大家看到我这里又加了个新号,这就是为了跟大家说一下,因为最近几年内我之前说过,就是说关于这块嗯,整个temporal的这一系列东西的进展啊,就是嗯呃时间和空间的这些滤波的方式。
使得越来越多的这种基于sampling的方法,可以得到在实时渲染中的应用了,是这么个意思,所以说这里跟大家说清楚,这只是大家以前会这么认为,现在不一定啊,不过我们在这里呃肯定有一点是这么说的。
就是说那我能不采样,那当然那是最好对吧,那所以说呢咱们呃不管说现在呃,这三个是不是真的能做,那我们还是希望能够避免它,那这就是我们要问的一个核心问题好吧,在i b l的情况下。
任何一个点的shading,我能不能不通过采样来算啊,行那么这样一来呢,我们来说一下,就是说啊一个基本的思路是什么好吧,那这个基本思路从什么开始呢,是要从一个最最简单的一个观察上来看。
咱们刚才看什么来着,刚才那个公式啊,咱们再回到刚才那样的,刚才在这个rendering equation里面,我们看到在积分里面是不是有两项对吧,诶等一下不是这样哈,唉真糟糕出来了,好嘞哎。
ok大家看这个公式里面哈,嗯既然不考虑visibility,那么这里面它是不是两个函数相乘,这两个函数就框出来这两块对吧,一个是lighting,一个是b r d f项。
我们之前说过b r d f项有时候就连着cos,那咱们这里就连着cos啊,lighting和b2 d f,那么这两块相乘再积分啊,它是这么一个呃情况,那咱们刚才说这个观察是什么来着,这个观察是这样的。
就是说啊如果说诶我这个这个积分里面,我的b2 d f是一个比较glossy的b2 d f,然后我现在在渲染一幅图,相当于我固定了我看的这个视角相当于incident,这块呃就是确定了嘛。
哦另外一点是这样的,在实时渲染中啊,大家通常说这incident,incident的时候没有那么严格,大家不会认为说是一定得是这个光照的方向,才叫incident,如果说我去看一个什么东西的话。
那我这个目光这块也算是incident了,基本上来说这块用的比较混乱吧,这样说,但是咱们就这么说吧,就是至少咱们在不引起这些呃混淆的情况下,咱们就这么理解,没有问题啊,我们看的这个方向。
假如说这是incident啊,然后唉这种情况下,那b2 d f这个logo,如果他是gloy的b r d f,那大家看左边这幅示意图,那如果他是glc的情况下,就意味着说啊。
他其实覆盖了球面上的这个范围,覆盖挺小的吧对吧,然后呢嗯如果说这个b2 d f呢是diffuse,diffub 2 d f什么特性啊,如果你有入射光影,你看过来对吧,然后他们往四面八方反射,那也就是说。
它其实在球面上会覆盖整个半球的区域,那它覆盖的区域非常大,但是呢虽然它覆盖整个区域非常大,但是他却非常smooth,咱们之前说过了对吧,它非常smooth,就意味着它的值的变化不大。
而它的值的变化真的不大,因为它的它的值是常数对吗,就算是我们连上这个cos一项对吧,那也它也仅仅是一个cos,这样一个相对平滑的一种过渡,所以说哎我们看这两个情况,如果b2 d f是停gloy的情况。
那他support就行,如果b d f是diffuse,它就smooth诶,这个事情是不是大家听起来非常熟悉对吧。
哎,所以说这个时候呢,我们又要提之前提到的这么一个经典的一个,近似方案了,但是大家看这个呃公式咱们之前不是提到过嘛,对不对,然后这里注意一点哈,就是说咱们显示的把这个所谓的support给写出来了。
就是说我不是要把两个函数的乘积积分出来吗,我可以把其中一个拿到外面去,就是这里把f拿到外面去,那我把f拿到外面去呢,诶呃我这里就是说我要对f进行一个积分,并且除以说他的这个这个积分线的这个空积分。
之前咱们都解释过说为什么对吧,然后诶这里我把f拿出去之后,我这个积分线其实应该写作对这个这个g函数,它对应的这么一个support的范围啊,这么个意思就是说如果它范围很小的话,我不需要记整个这个范围。
我只需要记这个在这个g函数有值的地方,它的这个范围就好了,那这里算是一个一点点的不一样,那么为什么要提这个事情呢,是因为刚才问了大家这个问题对吧,刚才大家发现这b2 d f的这么两个性质,是不是非常像。
我们之前说这个公式什么时候会比较准确对吧,诶刚那之前说这个这个公式什么时候比较准呢,这个g s的support比较小的情况下,或者呢是在是在啊,这个g的值比较smooth的情况下,让我们发现这种情况下。
对于b2 d f来说,b2 d f非常满足这个性质,那也就是说我们是可以做一个拆分的,大家来看b r d f正是能满足这两个呃,这这两个函数的乘积,并且积分他们拆出来的一个条件对吧,然后呢唉这种情况下。
我就可以把除了b r d f以外的,另外一项给拿出来,还记得吧对吧,b r d f类比于这里的gx嘛,那拿出来的是fx嘛,那我对应的f是什么呢,那就是这里的光照咯,那这里的光照我就说我把光照拆出来。
是光照在b2 d f范围内的一个积分去除以呃,这个光照的一个在b呃,在这个b2 d f覆盖范围内的一个空的积分,去做这个所谓normalization对吧,所以说我们完全可以这么做呀。
我又把它给拆出来了,是,那么这里面呢跟大家区分一个概念吧,大家还记得之前咱们在解释这阴影的时候对吧,我们解释阴影的时候,我说这里拆出来的是什么东西啊,这里拆出来的是这visibility项哈。
我是把这个lighting和这个b d f都留留在里面,把这个当做记象,所以说啊这个公式是可以根据需要来选用的啊,这么个意思好吧,那这里的应用是不一样的啊,我们这里把light给拆出来。
那我把light拆出来,大家看这个黄色的这个框到底做了件什么事呢,对吧,这个框它貌似是这样的,他和这个b r d f一点关系也没有了,这是他拆出来的好处对吧,我们为什么要把它拆出来啊。
正是因为说他们在一块综合作用,这light的b2 d f综合作用挺难的,我考虑不了,那我现在把light单独拆出来,我发现就是在light所表示的整个一个球上。
哎b r d f这个logo所覆盖的某个区域,我把这个区域的light给积积分起来,并且我把他normalize,其实呢那所说的事情是什么呢,就是说我要把这个idl表示的这张图给模糊了,对不对。
什么叫模糊,任何一个点上,取它周围的一片范围,然后我把这片范围的这个平均值给写回这个点,对吧,咱们之前说过,那所以说呃之前把light拆出来,其实他就定义了一种操作叫做filtering。
我可以去所谓滤波我的环境光,而滤波的和取多大,那这个就是说我的b r d f应该占多大,是不是这意思,这是非常非常有道理的一件事情,而且大家看我这里的用词叫prefiltering。
那么prefiltering是什么意思呢,意思就是说哦我这张图我在渲染之前,我就老早之前我就可以把它给掀filter好,那大家可以看到,比如说我这里这同样的这么一个环境光。
那这个环境光我可以把它任何一个位置,我都取它周围的某一个大小,然后我把它filter,然后得到另外一张新的图,然后呢,我甚至还可以说我我用非常不同的大小的这些,这些呃,呃滤波的这些核。
大家可以看到我用不同的这些滤波的核,去近似它,或者说,也就是说我对这个函数滤波的这么一个区域啊,就是b r d f覆盖的区域啊,呃它越大,那我这个得到的这个filter最后的结果就越糊,但是不管怎么样。
这几张图我都是最早最早在running之前,我只要有了这个环境光之后,我就立刻可以先花点时间生成的对吧,所以说我在渲染的实际过程中,我是不用管它的,那这非常好啊,对不对,然后呢。
那有同学说如果我到时候想去查询,说哦我这样一个呃lighting函数,然后他用某一种这个滤波和,大概呃大概比如说半径是五,然后我应该在哪一张图上去查呢,哎这个时候大家就会发现。
这个概念和那之前我们说的mip map,是非常非常相似的,对不对,我可以先生成几张图,这些图呢他们各自这些呃,filter都各自filter多大呢,比如说filter 1,filter 2。
filter 4,然后filter 8,那我要fter 5的话,哎我就我就在filter 4和filter 8,中间再插插值一下就可以了对吧,非常像这个三线性插值,所以没问题,这也是工业界的常用套路哈。
如果说我需要嗯去这中间查询某一个什么东西,我就是用这种插值方式来做啊,没任何问题呃,那也就是说我的lighting,是可以先去做不同大小的filter,到时候我要用的时候,我到时候去查它就可以了。
而且我查的不只是离散的一些filter,kernel的一些预计算过了的值,我可以去呃,查他任意的一个大小的一个filter之后的值,非常不错啊,这个这么一个思路,所以啊我们刚才说做这个拆分能够干什么呢。
就是能够让你的lighting做一个所谓的prefiltering,那我做这个profiltering干什么。
对不对,诶这里就是哈哈哈哈,这里就是就是说我们为什么要用它了啊,这里就是建立在一个非常非常有意思的,一个观察上,什么观察大家看还是这么一个这手绘的图啊,大家看左边这幅,左边这幅是什么呢。
左边这幅是大家从某个方向看一个shading point,他的dr df呢应该是某种lob对吗,是是某一种logo,然后我们如果要真正精准的把它给算出来,怎么办,我去采样这个b2 d f的logo。
我我在这个b d f logo的周围这一点范围内,根据他的glassness嘛或者ravenous嘛,我在这个周围去分布一些这些呃,采样诶,我采样最后的值,我可以做一个加权的平均。
然后我是不是就可以得到我这个shading point,的值了,对不对,那这个操作是不是,就好像说我把这个嗯这个environlight,大家看右边这幅图,我先做好了一个filtering,是不是。
就好像说我把environment lighting先做好一个filtering,然后大家可以看任何一个点,都是它周围一系列点的加权平均对吧,然后我再直接就去查一次在哪,在哪个方向查呢。
在镜面反射的方向上去查,大家看这两个操作,是不是非常相似的一个操作了,对不对,大家可以看到,如果说我去呃呃看向某个shading point,我认为如果它是镜子,那它镜面反射方向是什么,诶。
我往这个镜面反射方向去,我反射方向去,那我查我只能查一个值,但没关系,我查的只是我之前老早就已经fter好了的值,就好像是我查了他周围的一片纸一样,是不是非常聪明的一个做法,对不对。
那也就是说啊我们呃这样的话,这个lighting这个前面这一部分啊,就是说咱们刚才不是把这个整个一个呃,函数给拆成了,这么这不是函数积分拆成俩积分嘛,那前面这一半咱们解决了前面这一段,对不对。
我我首先我可以我对他做pre filtering,然后这样的话我就理论上我可以查他呃,任何多大的一块区域内,filter出来的结果是多少的对吧,然后呢我在实际用它的时候,我要取它的原本的light上面。
它周围的某一片的值的时候,诶,我就直接可以取它的这个镜面反射方向,我就取一次值,非常好对吧,唉所以说这是这是挺好的一件事情啊,然后呢这里这样吧,我先停一下啊,我看有同学有没有问什么问题的啊。
ok嗯有同学问hdr imap是不是spherical map,是的啊,没问题,然后有同学问spherical map的话,它它每一个像素表示的立体角是不一样,所以你是不是不应该对吧。
不应该对这个图做一个所谓uniform的一个filter,对,没问题哈,我刚才所说的意思,你取多大的filter和这个这个大小多大,其实指的是不同的立体角哈,这么理解。
或者说在球面上的一个filter的某个范围,就是你最后要把它给转换到这个呃,每个像素上,它大概要filter什么样的形状,什么样的大小,那都是不一样的哈,但不管怎么样,这是预计算。
咱们说清楚是在在球面上做一个filter,那当然这个就和你实际上用那多大的图图,这个分辨率不同的位置描述它,那就是那这个就没关系了,好吧,就是说呃,只要保证这个filter是在球面上发生的就好了。
那么呃漫反射是不是全图的平均可以没问题,你也可以用normal方向上的平均呃,就是说是这个意思啊,就是漫反射它不是往各个方向都去嘛对吧,然后这样的话,你就可以认为他的这个中心的方向,或者说对于漫反射。
如果有个镜面反射方向啊,这话说的好矛盾的,没关系,就是说它的logo的中心方向不就是normal吗,你就沿着normal去查就好了,也没有什么问题啊,就是说嗯不管怎么样吧,呃在实时渲染中。
通常人们会认为漫反射,一个是一个挺特殊的一种一种情况啊,就是说呃肯定会有的同学问,那我这个glossy logo我要不断变rap,不断变rap的情况,他不就变成嗯嗯diffuse了吗。
那我其实不是还得沿着他的,然后呃就是就是镜面反射方向去查啊,这个没什么关系啊,通常人们会认为,把diffuse和glc这些东西给拆开了,这么理解好啊,呃程序化的h e r i纹理能不能这么做。
除非它本身支持一个嗯动态的一个范围查询啊,按说按说我之前有些工作可以用在这个上面,再说吧,再说吧啊这算是比较深的一个话题了,ok按照已知的b2 d f来做filter啊,我觉得同学们问得好没错。
这就是说你得按照一系列已知的形状的,b2 d f,但是呢正常b2 d f lob,或者说这种其实是一个反射出来的,这个logo都比较像一个什么高斯嘛,正常有一个近似,差不多了,就ok啊,ok啊。
ok那行吧,差不多呃,这就是同学们的问题哈,ok那咱们继续,哎呀,我想了想该怎么办呢,哎呀哎呀,这下面这一步其实还挺麻烦的,我啊快速的说完吧好吧。
这样嗯破罐破摔了,我来同学们,ok哎行吧,我们刚才做了什么呢,我们刚才把这个嗯呃积分嘛对吧,我们把这个积分拆成了两半诶,并且我们还能把前面一半给完美的解决了,刚才看到了吗,看前面一半已经没有采样了。
是不是前面一半没有采样了,可是这个问题没能完全解决呢,是不是哈哈哈哈,这个问题要想解决的话,我后面这一半的这个积分,是不是也得不采样采集,是不是,这是一个非常非常重大的一件事情。
就是我虽然现在把它拆出来了,但是我后面一半我还不知道要怎么做呢,那么后面一半该怎么做呢,后面一半,大家可以看起来这个事情非常的麻烦呀,这是要对整个一个b2 d f进行一个积分。
那么这块呢呃首先我先跟大家说一下,现在呢是有比这个更好的解决方案啊,比比现在这个呃,就是所谓这里跟大家说的这么一个方法,更好的解决方案,但是咱们现在就先说一下这个方法怎么做好,就是右边这个红框里面。
我怎么样才能把它给解出来,并且我还不能积分呢,诶那这个时候呢我们就说呃,我是可以做一个什么呢,可以做一个所谓,跟刚才的一个完全一样的思想和预计算的啊,这么个意思,就是说。
只不过这里的预计算呢可能就比较麻烦了,因为这里面大家看诶,我要想算这么一个积分,我势必要把这个所有的这些参数的可能性,都可以考虑进去对吧,它是一个通用的一个b2 d f,他b2 d f写进去。
那b2 d f的话,我也许说我可以做一些假设,我假设他是microphy b r d f,如果大家还记得的话,在game 101我提到对吧,嗯microphy b2 df的话。
他唉我就只需要定义基本上最重要的两件事情,第一for now还记得吗,一for now,for now是能够也就是叫什么菲涅尔项嘛,能够决定说他的这个基础反射率,以及在什么grading angle下。
或者换一句话说,它反射出来的这些颜色各不相同对吧,随着你不同的入射角度,这是for now,另外一个它的嗯所谓呃n d f对吧,也就是说他的那些微表面的法线分布,那微表面的法线分布。
它就是一个很简单的一个一维函数,他直接可以拿所谓roughness,就是说它的粗糙度来描述它,所以说如果我假设说嗯,它是一个呃microphy b2 d f,那它能不能让我的计算变得简单一些呢。
呃呃然后答案是还是挺麻烦的,如果我想把这么一个积分啊,在所有可能的参数的不同组合之下,我都要把它的值给算出来,这是一个非常浩大的工程,大家看这个事情啊,就是说咱们说the roughness。
roughness是一个数啊,算是一个一维的一个数,那么feral term这个很麻烦诶,for nim,它本身他得告诉你,你这个比如说基础的这个反射率,然后它本身就有一个某种曲线对吧。
它在不同的入射角度下,所以它还是入射角度的某一个某一个函数,所以这样一数的话,它就是至少是一个五维的,一个非常高的一个参数空间对吧,这样这样说就是参数有多少个对吧,那就表示这个参数空间有多大。
那对于每一组不同的参数的组合,我都要算出这么一个积分的一个值,这不就是我说的所谓暴力的一个预计,算的一个思路嘛,对不对,那诶这块是有点不好的对吧,那这太大了,我要打一个5v的表格还得了啊。
就是大家知道说我们三维的纹理,为什么用那么少,因为三维的纹理已经会产生一个呃,这个组合的爆炸的一个一个存储量呢,那四维五维更是如此了,对不对,那所以我肯定不能这么无脑的这么预计算嘛,对吧。
唉但是我这这就是人们聪明的地方,人们会想出来一些这些更好的方式,来做这个预计算,但在这之前呢,我先跟大家说一下,从这节课开始就有大量的预计算相关的内容了。
甚至是之后要跟大家说的所谓p r t precomputed,radiance transfer,这个预计算什么,辐射传输,可能这么翻译吧,然后就是说这整个预计算它是相当于有一个嗯。
相当于支撑了整个游戏界的发展啊,所以说预计算是一个非常正常的一个做法,只不过人们可能不能承受非常高维度,高这个参数的这个维度的一个呃预计算方式啊,咱们这么说明白,那这里就是它不能预计算对吧。
那不能预计算怎么办呢,我们想办法让它能预计算好吧。
这么一个思路,在这之前呢,先给大家看一下,咱们之前game 101里面的东西啊,gm 101咱们有过这么一样啊,说microfsb 2 d f是干什么的,如果他就忘了。
microfc b d f里面最重要就是这两项吧,就是一个fernal term,决定了说呢哎我这呃如果垂直看向物体表面,它有多多少能量被反射,当然这就决定了颜色对吧。
另外一块呢就是说我如果不垂直会怎么样,它嗯反射的量肯定会各不相同嘛,所以它直接会决定了颜色,这么个意思啊,final term挺复杂的一个函数,然后呢,另外一个重要的东西就是说它的微表面的分布。
微表面啊,微表面的法线分布,如果这个分布比较呃,就是比较开x面八方都有,那这个表面肯定就是diffuse了,那如果说这些法线它都集中在某个方向,那基本上这个就是比较接近镜面了,对不对。
那所以说他就是这么一个思路哈,那么中间shadowing main还是一样,咱们不提,那么为什么这里要说一下这个事,是因为我们之后在那里说所谓p b2 ,physically based on。
诶那叫你这个二是什么,还是rendering呢,但这里难道不应该叫材质吗,啊没关系吧,反正就是说之后再说到这个实时渲染,中间材质的时候,我们还会提,这里就简单回顾一下gg 11啊,这个意思。
那么我们关注的就主要就是ferne,想和这个呃n d f项,就是这个df和d啊,呃其他的我们都不考虑问题,问题不大啊,在这里那么好,那么这两项啊,如果大家还记得这些图的话啊,之前我们说过啊。
有一个能够近似的描述菲涅尔项的一个近似啊,这个近似叫做slex proximation,之前我们曾经在game 101说过这事啊,然后它近似成什么呢,他会发现这个fernal项目。
它在不同的入射角度的情况下,它其实它长得都比较像这么一个诶,往上涨的一个指数函数,所以它就把它给近似成了一个指数函数,定义了一个什么呢,定义了一个初始的反射率二零,然后又定义了一个他怎么往上涨。
就是那一减cos c它的五次方,大家看我故意圈出来这么两个哨哈,这这两个是什么东西,这两个其实就是对于slicks approximation,他认为啊不同的材质呃,它基本就会就就是说呃他的呃。
飞鸟像是这么两个东西的函数,一个是它的基础反射率二零对吧,然后它是一个颜色嘛对吧,另外一个呢就是它的入射角度就是这个thea,然后呢呃在这里再多跟大家说一下,在实时渲染中啊。
通常人们提到这几个角度都是可以互换的啊,非常非常近似什么角度,入射角也就是入射光与法线的夹角,还有出射角也是相当于是出射光和法线的夹角,还有这个半角。
所谓half angle就是入射光和出射光夹角的一半,然后或者说入射光以及出射光各自对,所谓half vector半程向量中间的夹角,这几个夹角大家都可以认为差不多啊。
然后所以说这里我就简单的用一个c塔,来描述了这么个意思好吗,那所以这是我描述不同的材质,不同的microsd的材质想定义它颜色就这两点,第一基础反射率基础颜色吧,可以这么理解r0 。
然后第二就是随着这个c塔这往上涨,你得你得知道他的这个入射角度,否则你得出来对吧,这两个变量,那么另外一点,如果我要在microfit model里面,我要想定义某一种法线分布诶。
那我要定义这种法线分布的话,呃,我就要把这些法线分布的这些什么角度啊,都给描述成为一个分布,那这个分布是一个非常简单的一维的一个分布,大家可以看到基本上就是右边,大家看到一个比较类似于高斯的一个分布。
就是基本上沿着他的这个宏观的法线呃,这个这个周围它分布的比较多,对不对,然后呢他这在其他地方啊,它分布比较少,差不多是这么个意思吧,然后还是一样,它公式挺复杂的,挺复杂的,但是呢大家可以看到。
就比如说对于这种所谓backman的一个分布啊,这有各种各样不同的分布的定义嘛,咱们就以它为例啊,他这里定义了什么呢,大家呃呃不是他这里有什么变量呢,大家可以看到第一有一个变量叫alpha。
可以可以定义所谓roughness,也就是这个分布啊,它的是胖还是瘦啊,就决定了说我这个材质呢它到底是diffuse呢,还是gloy对吧,这肯定要定义的,那么另外一个呢他还需要这个角度。
也就是这个角度呢,差不多就是他那个啊half vector和这个什么呢,和这个呃法线中间这些夹角啊这么个意思,然后这个角度呢大家也可以把它给呃,通过某些近似的什么方式。
把它给描述成跟入射角相关的一个角度,这个角度各自之间都比较好好呃,互换哈,都是这么个意思啊,那那么这里面我就把这些sea什么都给圈出来,当做同一个颜色来把它圈出来啊,这么个意思啊。
ok那这里我为什么圈出来这些颜色呢,大家可以看到哦,就所谓入射角度,我们我们可以认为这是一个变量,然后呢我基础反射率是一个变量呃,这个呃物体的粗糙程度是一个变量,那么这样一来,如果我想还是一样。
预计算刚才的那么一个积分啊,我对于所有可能的这么的参数,这么一个形成一个空间,我的每一个点我都计算出来一个,这个计算出来的值是不是这个意思,那也就是说现在变成了一个三维的一个,预计算了,是吧啊哈哈。
如果这个r我可以认为它是一个灰度的话,这样的话那大家看到不同的颜色,红色的,橙色的和蓝色的,这三个变量各自都可以变化的,然后每一种组合,我都可以计算出来一个预计算结果,那当然好了。
但是呢仍然唉三维的一个计算太麻烦了。
那这里呢就是说关于呃这个人们聪明的地方,人们发现这么一个事情,就是说人们还想更进一步的把这个预计算的,这些参数的维度啊给降了下去,就这么个思路啊,然后呃那这是什么意思呢,基本上来说大家可以看到哈。
就是说呃我的这个呃还用刚才这么一个思路,我现在在这么一个积分里面,这个积分里面有三个变量,我需要考虑,我能不能想办法,把其中一个变量再给拆到这个公式外面去哈,这里数学东西稍微多那么一点点啊。
但是思路是清楚的,没问题吧,如果我想预计算这么一个呃积分的值,它的参数空间非常的高维,我是不是要想办法降维,就是这个意思了,我希望说这个积分的值,它不太依赖于更多的参数,只希望它依赖于一个比较少的数嘛。
这个意思,那么这里呢就是人们聪明的地方,人们发现了这个呃,菲涅尔像这finale term,如果我把它写成用这个呃呃史莱克啊,这个这个这个近似啊,用他这种近似方式,我是可以写出一个诶哈哈哈,大家看哈。
我是可以把它把这个这个积分啊,这也是呃右半边那个积分啊,可以把这个积分给写成这个形式,这个形式大家看起来非常云,没问题没问题哈,但是我想说这个近似是非常简单的一个近似,他做了件什么事啊。
他在这个啊b r d f里面,它显示的把这个菲涅尔项给写出来了,大家看到b2 d f除以f,大家在右边啊,我把鼠标圈一下,大家看b r d f除以f再乘以f,是不是等于完全没变对吗,那么这个f呢。
菲涅尔像咱们刚才说了,又可以写成r0 ,加上什么一减cos i c到呃五次方,再乘以什么东西对吧,然后这样的话呢大家就会发现哦,我把这个f通过呃,fernal term通过呃,我可以把它拆出来啊。
这么写出来写出来这个值肯定是就是近似的嘛,但是差不多嘛对吧,然后呢呃这有什么好处呢,这一个好处,那就是说我可以把这个公式里面,我刚才拆出来之后,我可以把这个公式里面一切跟这些基础反射率。
r0 相关的项目都可以把它拆出来,因为r0 它算是一个常数,这么个意思啊,就是说我对于任何一种b2 d f,我给你了一个r0 ,这个r0 是一样的,所以说我我就直接把刚才的ferno的这个。
这个公式带到b r d f里面,我整理一下,我就可以把这个r0 给拆掉,积分到外面去啊,这么个意思,然后呢,那这样的话大家会看到诶,这个积分现在变成了俩积分对吧,是而零乘某个积分加上另外某个积分。
o是不是听起来变麻烦了呢,答案是并不是这样,反而让结果变简单了,为什么呢,因为他把这个原本的这个积分,对于基础反射率的依赖给消除了,他把这个基础反射率拆出来了,这之后剩下来里面就是两个变量,哪两个呢。
第一是roughness b r d f的roughness,第二就是它的入射角c塔i,或者说cos c塔i没关系,那我如果说我想对第一个拆出来的,这第一部分啊,呃积分呃做一个预计算。
那我只需要对呃两个呃参数形成的一个呃,形成了一个什么呢,形成一张表对吧,我可以写成一张表,rance它的取值啊,这样啊大概是什么意思,然后比如说它的cos c塔i,它的取值00。10。
2,一直到多少,我打了那么一张表出来,这张表上的每一个值,就对应着我这个积分出来的一个值对吗,这不管什么积分再复杂出来,这是一个数啊对吧,还有一个值,那另外这边积分我是不是也能这么算,没问题吧。
哎那也就是说我这两个积分我都可以把它打成,一个二维的一个表格什么呢,大家可以看这里,就是说这两个积分中的任何一个,我都可以做一个roughness和cos theta。
这里大家看到theta v跟si一回事啊,在实时渲染中不怎么区分等这么一个表格哎,作为这么一个表格中任何一个点,它的值就是我算出来的积分的这么一个值,是不是也可以啊,没问题,那么算成积分这个值之后诶。
我有一个二维的一张表格,我是不是可以把它存成一个二维的数组呀,二维的数组,然后它的任何一个位置上都有一个值对吗,哎那反映在实时渲染里面,它不就是一张纹理吗,我把这张纹理就先给预计算出来。
到时候我把他送到shader里面,我该用它的时候,我只管去查,我就立刻可以得到这这个公式啊,和下面这么一个公式,它的值是多少,甚至每个基数还是一个数,我用一张纹理了,前两个通道,一个r通道,一个g通道。
他就可以表示他们了,是不是,然后这样一来的话呢,大家看如果我到时候给你一种b2 df,他的这个基础反射率知道拆出来了,然后我我只需要去查两次这张表,诶,我就立刻可以得到,刚才我们说拆出来的右边的积分了。
诶大家发现什么问题,是不是又没有采样了,对不对,所以说呢这里是这样哈,就是说如果有同学说这块呢呃会觉得有点麻烦,那是因为你对这个之前的这个microphy,可能是忘了,是这么回事啊,就是说呃基本上来说。
他的思路是非常非常清楚的,我就是想预计算这个积分成为一个表格,我又不希望计算出来,也一个就是非常高维的一张表格,然后中间某一个值是多少,然后我就是希望把这些呃变量之间的这些联系,都给拆开。
所以说人们就用了这么一个方式,至于说中间这个数学呢就挺神奇的,对不对,那这也是说这个方法为什么得到广泛应用,因为他确实是对于环境的这个光照来说,如果要算shading,它就再也不需要采样了。
是非常非常厉害的啊,这么个意思好,那么我们这个时候呢总结一下,那通过刚才咱们说的这两种不同的两个部分吧,分别不同的处理,然后我们就可以做到说哦,我我终于就不需要采样了。
我还可以在环境光下渲染这个不同的物体,大家可以看到哦,那他得到了一个非常非常好的一个呃,呃一个什么呢,一个结果对吧,大家看到这个方法,然后呢和所谓的reference reference呢。
咱们就理解成是pasting出来了吧好吧,然后和这个相比,那大家可以看到结果非常非常相似,不管是呃diffuse的情况,还是说呃glossy的一些情况对吧,那那那就说明它非常好了。
那么在最后呢这里呢跟大家说一下,说这个方法是有名字的什么呢,刚才咱们不是说那个积分是拆出来了,变成俩积分嘛,不过在工业界呢,通常人们很少就这么写这些积分什么的,在这个offline那个月。
大家写这些积分什么的,写的多哈,在这实时领域,大家平常就写成求和了,就是大家看这里面呢,这个求和其实就是和这个什么呢,积分呃描述的完全一样的事情啊,这个求和是,那么既然他做了两件事情。
第一他要把这个一个积分给拆拆开,或者说把一个求和式给拆开,然后呢他对两边呢又分别进行,之前咱们说要么filter,要么去查表对吧,然后分别进行求和,于是呢这种方法本身他就有了一个名字。
叫做split sum方式啊,它不叫split integral,也是这么个原因啊,然后split sum呢是大名鼎鼎的,这个按real引擎的这个呃,为什么他的所谓p b2 。
可以做到这么牛的一个基础吧,就是说他这边的这个环境光照,然后在这个split sum下,然后大家可以看到呃,做的是完完全全没有任何noise对吧,他没有采样嘛,当然没有noise。
然后它又可以得到跟这个真实的这个结果,非常非常相近的一个结果,所以非常的厉害o,那这里基本上咱们就把这个所谓split sum,方法就说完了好吧,那行呗,嗯基本上这块儿我来看看吧,有同学有什么问题吗。
好吧哎呀,我看问题挺少,说明什么,说明这块大家不好懂对吧哈哈ok没关系没关系,真的就是把这个呃所谓high level,这个想法可以想清楚就好了行吧,然后嗯然后有同学问菲涅尔像是要去预计算吗,不是同学。
菲涅尔像被我们拆开了呀,正是因为我们把它拆开了,所以说我们才会能够避免说这个啊,就是说它对不同的这些这些变量的这种依赖性,我们也可以把它拆开嘛,这么一个思路,有人说环境光本身怎么计算这块。
我没看没看懂哈,没看懂什么意思,怎么获得一门max吗,那是另外一回事了啊,ok然后啊ok哦我说呃,有同学问刚才讲的更好的方法是什么,我更好的方法其实是这个意思啊,就是它并不是严格意义上来说。
能够直接解决这个问题的哈,是是呃叫做linear cosine transform吗,它跟这个相关,跟这个相关之后,我们再讲的时候,我们再说吧,好吧啊,ltc啊,这块应该大家听过。
ok然后来看看哈啊这张预计算图是不是固定的,是的哎,这就是非常好的事情,它对于任何不同的b2 d f,只要是同一种种类的b2 d f吧对吧,然后这张预算出来的图是一个固定的。
所以说你只需要把这一张图传进去,你对于各种各样这个类型的,microphy的图都可以了对吧,l t c是是可以说的,没问题啊,o l t c不要把它想狭隘了,不是只能算面面光源哈,啊这个之后再说吧。
之后再说吧,好吧嗯ok啊,来看看哈,嗯对b d e f不同,你算出来这个图也不同,确实是这样的,然后microfit在gg x里面会多参数,不会啊,也是这么写参数啊,除了d l s s吧。
其他东西甚至连dnoising,现在大家用的都不太怎么多,目前来说并不怎么成功哈,这个之前我说过这个事情,这个事情是可理解的,实在太慢了,你跑一遍神经网络下来需要几毫秒,这不是已经死了吗。
那怎么怎么用嘛对吧,这就呃呃,特别是说,如果说你要是在比如说shading的层面上,每一个点都要跑一遍神经网络,那就完蛋了,根本不可能的嘛,对吧嗯当然这是我说的,现在不知道以后会不会怎么样哈。
ok其他b2 d f相关资料哎,跟这个暂时关系不大吧,咱们到pb 2的那块再说吧好吧,然后cos和b2 d f连在一起,为什么啊,这是因为咱们在这个课的开头讲过哈,大概不是第二节,第三节我忘了哈。
k i b l适用于什么场景啊,确实有同学已经回答了,适用于你想用的场景啊,没任何问题,任何场景啊,就是用的特别的多啊,i b l有问题,我之前说过,就是因为它会假设所有东西都是无限远的嘛。
对于一定和你的物体有一定的确定距离的,像这种光照,所以不能再这么用了哈,ok我刚才有同学问,求和是分母的p是什么意思啊,那个就是我们在蒙特卡洛积分中间的,pdf那块来说,你就只需要看game 101。
你就知道那是什么意思了,好吧嗯,大概是18讲左右吧,我忘了,ok i b要怎么处理遮挡,问得好,同学看这里哈哈哈,这里就是说关于环境光照,我们的遮挡怎么样去处理啊,这里怎么样去处理,我就不说了。
这节课已经时间挺多的,他然后咱们呃这下节课再给大家说,因为这块其实怎么说啊,直接一个总结,就是没什么好办法啊,ok嗯ok然后积分里分母的f怎么计算,哎同学是这个意思,积分里那个分母啊。
仅仅是为了把它写出来,大家想一想,那个分子上f乘以g乘以d,那再除以f不就消掉了嘛,就是没必要计算嘛,对不对,然后b2 d f本身f乘以g乘以d,你下面又除了个f不就直接消掉了f了吗,对吧。
ok那行diffuse和glossy项目还可以再拆分的,有很多这个后续的处理了,咱们就不再多说了好吧,ok那是这样哈,咱们说一下下节课的话,咱们就要开始说实时的全局光照了哈,关于全局光照。
这块儿是指非常非常复杂的一个话题,它会比阴影这块还要难啊,然后基本上来说我做了一个简单总结,差不多分为三类,一个是在3d的空间中,我怎么样用这些方法,然后一个是在图像空间中,怎么样去引入全局光照。
然后最后一个就是说关于预计预计预计算,然后我想着呢下节课如果没有意外的话,我们会先说这个三维的空间中间的一些方法,比如大家看到这些这些缩写都是什么鬼对吧。
l p v v x g i rtx gi这种东西,哈哈o嗯行吧,然后我就到时候这个嗯资料提前看,其实是好主意,我应该想一想,把资料给放出来,哎这样吧,这样吧,这个这个我看吧,如果我不不忘的话。
下节课我注意一下,我之前把这块需要的资料先给放出来好吧,那今天咱们就到这吧好吧,按说已经说了不少了,嗯ok这节课大家大家体会到了。
对不对,就是之后呃我觉得不会简单的,但是你要说之后会比这节课会难到哪去,应该不会吧,反正差不多就是这个难度了哈,基本上这个意思那行啊,最后呢还是一样,谢谢大家,然后呃记得哈,下周咱们没课啊。
但是这周周六还是有课的啊,就这么安排吧,行没问题啊,ok那就这样了。
GAMES202-高质量实时渲染 - P7:Lecture7 Real-time GLobal Illumination (in 3D) - GAMES-Webinar - BV1YK4y1T7yY
那咱们还是准点开始啊,啊好的,亲爱的同学们,欢迎来到games 202的第七讲,然后今天呢我们给大家讲一个新话题,当然前提是咱们先把之前留下来的嗯,嗯呃预计算的部分给说完好吧,然后从标题上大家可以看到。
今天我们会说实时的全局光照和全局光照,这一部分呢,在实时渲染中是非常非常非常重要的对吧,我之前说嗯怎么样判断呃,实时渲染的质量好坏对吧,一个重要的标准就是看结果是不是按,那如果没有全局光照。
或者全局光照做的不好的话,那得到的结果自然就会比较暗,所以说呃其实全局光照就是扮演着一个,让整个一个图像能够变得比较明亮,并且看起来比较自然的一个重要角色,嗯好吧嗯那行,今天我们就来说这个话题。
那么在课程之前呢,先说呃一点事情,一个是games 101之前有同学问啊,哎我们说清楚啊,james 101的事情啊,之前有同学问去年在games 101开课期间对吧,然后如果嗯同学们没有赶上提交作业。
咱不是作业提交通道就已经截止了嘛对吧,然后呃那么今年我们会重新开放啊,什么时候重新开放呢,就在这个月的下旬,也就是很快了,差不多一两个星期之后吧,啊然后这么安排啊,重新开放了之后。
大家就自然可以去按照自己的节奏去提交作业,然后我在想是不是要给每个作业再安排一个,比如说一周放出一个作业,然后大家有个一周或者一周半的时间来做,呃,这样也行,或者呢一次性放出来所有的提交通道。
大家来提交也可以,那么具体的安排呃,这个交给我,我再思考思考好吧,呃然后同样啊我们我们说清楚,做games 101开放作业,提交通道,那如果说你错过了这个新闻,当你知道可以重新提交的时候。
又已经过了几周,怎么办呢,那games 101重新开放作业,提交也重,也会重新开放他的作业补提交,哈哈没问题啊,总之这是肯定是可以的,然后呢如果大家密切关注games的啊群的话啊。
大家会发现我现在积极的招募,这叫什么呢,grader啊,greater嗯,不知道中文怎么对应啊,就是说不承担什么助教的答疑任务,基本上来说就是就是去呃批改作业哈,我们需要征集同学们来批改作业。
具体的要求什么,这之前已经呃说清楚了好吧,然后在在咱们的广告里面,大家去自行呃查阅,然后如果有兴趣的话,欢迎抓紧报名啊,这个事情grade啊,帮大家批改作业的志愿者同学们啊。
ok那么呃另外一个事情呢是关于咱们这门课,咱们这门课呃,games 202的作业二很快也就要发布了,如果一切顺利的话,差不多是呃这周末来发布啊,然后这次的作业是呃和p r t相关的啊。
然后就是咱们刚刚说过的,和p t相关,然后是在一个场景上面做prt,然后支持旋转试点,当然这个是简单的,然后以及旋转光源啊,差不多是做这么个事情啊,这也就是呃课前要说的哦,对之前有同学提醒我说啊。
呃我们的games,202是不是也应该有作业补提交对吧,那我觉得是应该有,那大概在什么时候呢,应该跟正常的提交,咱们稍微错开点时间,所以咱们等到最二截止的时候,我们在考虑补题教怎么样。
这个应该是没问题的,甚至作业三发布或者中间的时候应该可以哈,然后总之就是说合着正常的提交时间,咱们错开一点,这样来安排啊,那行这就是呃我们课前要说的一点事情,嗯然后呢大家想一想,上一节课呢我们提到说啊。
最重要的概念基本上来说就是prt对,虽然来说我们开始说了这个环境光下的阴影,但是我们得出来的结果是,这种情况下阴影非常的难做,而为什么我们今天要重新提一句,这个事情是,因为大家今天还会发现。
这个事情在全局光照中仍然非常难做,全局光照中怎么算间接光照的阴影,哈哈这个事情啊,那么除此之外,那就是p r t的事情,p r t这边呢,然后我们提到了一些跟这频率相关的事情,以及呃二维的定义。
在球面上的一组呃非常常用的奇函数,叫做spherical harmonics,然后他们是怎么回事对吧,然后以及说用它怎么样去描述2d的函数,比如说环境光照对吧,比如说visibility啊。
或者来transport啊,各种各样的2d的函数都可以用它来描述,没问题啊,那么今天我们先想办法把这块给说完啊,说什么呢,一个是我们上节课提到了s h呃,怎么样去利用它。
然后对diffuse的场景进行预计算,以及在实际的计算中呃,怎么样利用它,能够达到一个非常快速的计算对吧,然后今天呢我们会说对于glossy的物体呃,怎么样来做,那么这有什么问题呢。
为什么要单独拎出来说呢对吧,这就是我们要关注的地方,另外呢给大家介绍一个呃,另外的g函数叫做wave,let叫做小波啊,中文叫做小波,然后这块还是呃就是用的比较多的一些呃好吧,然后这样的话。
我们就算是把这个p r t部分说完呃,然后我们就开始说呃实时的全局光照啊,然后我们今天要讲的主要是在三维空间中的,实时全局光照的一些方法,然后咱们的下一节课会讲,在图像空间上怎么样去做呃。
还是一样实时的全局光照好吧,差不多是这个意思,今天咱们大概能讲两个呃,reflective shadow map,叫rs m和另外一个叫light propagation。
volumes或者叫lpv这两种方法啊,嗯vs g i估计今天讲不了,咱们留到下节课开头再补上好吧,那么咱们先把p r t给完成,那么p r t如果同学们不记得的话,大家回忆一下嗯。
pre compute对吗,他precomputer什么呢,precomputer的两部分对吧,两部分一部分是lighting,然后一部分是所谓除了lighting以外的,其他的在积分中间的部分对吧。
我们管它叫light transport,然后lighting乘上来,transport积分起来,那在任何一个shading point上,那那我得到的结果就是这个shading point。
我能看到的最终的值了,对不对啊,好然后这里呢啊如果我上节课忘了说了的话,呃,我说shading point啊,其实指的就是这个几何形体的顶点,就是vertex啊这么个概念。
然后就是说你的呃like transport,可以每一个顶点计算一份呃,light transport的啊,这个vector向量,然后呢我在实际上运算的时候,我可以每个顶点先运算好。
得到shading result,然后我在在三角形内部差值啊,这个咱们之前说过对吧,这per vertex shading对吧,然后呢我们当然也可以用per嗯。
pixel或者叫profragment shading,我们可以先嗯在三角形内部差值好,它的lighting的向量和light transport对应的向量。
然后在中间的呃任何一个pixel上或者fragment上,我们来算它的一个结果对吧,这都是可以的,但是没关系啊,这就是提一下关于shading point这么一个事情,或者我中间再说说到vertex啊。
那其实都是一回事好吧,所以每一个vertex计算它的light transport,并且投影到s h,然后得到一个呃向量对吧,然后嗯然后lighting的话呢,如果你只用考虑一种lighting。
那就只用投影一次对吧,然后投影到每一个s h的奇函数,得到一个数,那当然最后投影出来就是一个向量,然后在实际运算的过程中,那就是一个向量的点乘,ok那这就是之前的p r t,那么我们还提到了。
说重要的概念就是spherical harmonics,它就是一系列的奇函数,那么这一系列的奇函数呢,呃它有一个不错的性质,咱们之前分析过对吧,它分为不同的阶,或者从这张图上来看呢,那就分成不同的层。
不同的行,对不对,每一行呢表示一个呃固定的频率,那当然随着这个行的数量增加,也就是l的增加,然后它能够表示的频率就越来越高,嗯然后呢每一种频率大概有多少种。
不同类型的spherical harmonix的奇函数啊,这个咱们之前有分析过对吧啊行嗯,然后呢,任何一个二维的函数,都可以投影到s h上面去对吧,然后我们可以用一系列的诶。
这个加权和来描述任何一个二维的函数,然后同样道理啊,这也正是我们如何去啊恢复一个一个函数,就是说如果给定一些s h的basis,比如说我就用前多少阶对吧。
然后前n阶那就总共n平方个呃basis function,然也对应了n平方个呃系数,然后我们就可以恢复出来一个原始的函数,当然这算是一个频率截断的恢复对吧,我们用的呃阶数越高,我越可以恢复出。
又或者说也可以表示出呃这个原始的函数,它的高频率的内容对吧好,那这就是之前的内容了,然后呢今天我们上来先从另外一个角度上啊,我们先重新看一下关于我们上一节课说的,对于呃light或者lighting啊。
和这个light transport,我们怎么样去算这个呃呃呃怎么样去做预计,算对吧,如果大家还记得的话,咱们上一节课的差不多,最后然后说我们从这个rendering question出发。
我们先把这个lighting,然后给写成呃一个呃计函数的描述方法,然后剩下的部分对吧,我们再怎么样去处理,然后剩下的部分看起来就好像是把like transport。
投影到basis function上,这是一种理解好吧,然后呢呃另外一种理解,那就是今天咱们看的思路,咱们现在呢就是不考虑一个先后顺序了,咱们就直接把两部分啊,大家看这个蓝色框。
这不是lighting嘛对吧,然后呃和这个橙色框,这两个分别就是lighting和light transport,那我就按照我之前说的最原始的一个方案啊,我把lighting这他不是二维的一个函数吗。
对吧,各各个不同方向的入射方向,我们要i的,我把它拆成一系列的啊,这种呃求和的形式,那自然就是对s h的前多少个啊,或者前多少阶呃,做个投影对吧,然后这是可以的。
然后呢light transport我当然也可以这么来描述,like transport本身呢,然后咱们之前说过,对于diffuse的b r d f来说。
这个diffuse的b r d f它其实就是一个啊常数,那不用管它,那么我们看就剩下visibility,它还是欧米伽i的一个二维的函数,那么呃这样的话呢。
我就可以把呃a lie transport部分,这这里咱们可以把它简写成t啊t啊,我把鼠标放一下啊,就是这样的啊,这个t指的就是整个橙色框啊,然后我把他也可以投影成呃这个basis function。
那么我两个分别做对吧,然后我不考虑一个先后顺序,那这样的话呢,我既然两部分都已经写成求和形式了,我是不是就可以把他们给在这个积分中展开,没错吧,就是说大家看蓝色的框就展展开成这球和。
橙色的框展开成这个求和,那这样一来的话呢,我就可以变成一个把这这么一个积分了呃,求和和积分交换一下顺序,然后会发现它会变成一个双重求和的一个问题,哎,对p求和,对q求和,这分别是他们的下标啊。
然后每一个球和里面涉及到要乘三样东西,成这什么呢,称这对应的系数以及一个积分的值,这个积分跟实际的场景没关系,大家可以看到是两个呃奇函数的product integral,对不对啊。
ok那我现在有一个问题要问同学们对吧,大家会发现这样推导,跟上一节课推导得出来的东西不太一样,嘿嘿嘿嘿,对不对,因为大家已经可以看到了一个很明显的事情吗。
我们之前说你你把light和light transport都写成呃,都投影到s h各自得到一个向量之后,得到一个结果,它不是一点乘吗,点乘的话,a向量的长度如果是n啊,啊咱们就是向量的长度是n啊。
这里n指的是或者说奇函数的个数,而不是阶数了啊,呃那行,那如果向量长度是n,那我做一个点乘,那不是o n的嘛,对不对,那怎么突然它就变成o n平方的了呢,这是一个非常严重的问题对吧,那为什么我问平方啊。
因为你两个求和嘛对吧,这个比如说嗯t等于一到n,q等于一到n,你这样的话,这不是n平方的一个算法吗,这这这为什么我们上节课推出来是n平方,怎么这里呃呃是o n的,就一点乘这里它不是个点乘呢对吧。
这里是一个呃呃我要问同学们的一个问题啊,嗯然后呢这里当然有一个提示哈,就是大家肯定会知道,这两种推广肯定得到的结果是一样的,对不对,那么呃为什么会出现这呃这个这个情况。
就是说实际上啊大家看这个结果像是n平方,实则其实也是o n的,为什么呢,因为s h它有一个非常好的性质,我们上节课说了对吧,哎这个性质是什么呢,我们来看这个积分是什么,大家就可以知道这个积分呢。
大家看呃这在做什么事情对吧,哎这是product integral对吗,一个呃奇函数和另一个奇函数,这两个奇函数呢呃它各自都有个下标对吧,这两个可能是不同的奇函数乘起来再积分。
product integral,这不就是什么呢,这不就是说我如何把一个呃任意一个函数,对任意一个函数投影到某个basis上面,我可以认为哦,这个bp它就是任意一个二维的函数,它要投影到b q上面。
然后投影出来的那个系数是多少对吧,然后上节课我们才提到spa harmonics呢,本身有正交性,那这个事情要类比如说在三维空间中对吧,我们之前说把x投影到y轴上,你得到的结果是多少零,对不对。
你只有把x轴投影到x轴,这得到结果才不是零,否则其他都是零,那也就是说只有当p和q是相同的情况下啊,也就是说bp和bq就是相同的奇函数的情况下,右边这积分结果才会是一,否则的话结果就是零。
那么大家可以想,你这个虽然看起来是一个2a的,一个一个求和对吧,p等于一到n,q也等于一到n,但只有p等于q的时候,它才有值,其他时候都不是职,所以说白了意思就是说啊,你有一个诶呃一个二维的一个矩阵嘛。
但只有矩阵的对角线上有值,那么你就把矩阵,对角线上的值都给算出来就好了,所以说这还是o n的哈,没有任何问题啊。
这就是回忆一下之前正交性好吗,然后这是我们上节课的一个呃,相当于重新理解嗯,然后我们回到这节课的内容上来,这节课呢我们要说呃diffuse的物体,那咱们之前之前已经处理了。
那么glossy的物体我们怎么处理呢,glossy的物体或者说它又有什么呃新的问题,它有什么和diffuse不一样的地方呢,啊然后咱们想一想diffuse和glossy,首先它们的区别在哪,对嘛。
它们区别就在b2 d f,那b2 d f呢,这diffuse呢它是一个常数对吧,没问题,然后对于glossy来说,它可就不是常数了对吧,他是告诉你从任何一个方向打进来对吧,打到某一个表面。
然后它往哪个方向去,那你换个方向打进来,它往其他的方向反射对吧,是这个意思啊,那所以说呃,这个b2 d f就是一个完整的,4d的b2 d f了,呃对吧,呃两维的呃是输入的方向,两位的输出的方向嘛对吧。
那所以说它是个四维的一个函数,那咱们如果按照之前的一个呃办法,还去做这么一个呃对light啊,做一个,做个什么呢,就是就是投影到s h啊,然后我们这边再把light transport。
投影到s h的时候,我们就会发现有一个问题了对吧,然后呃这个light transport投影到s h呃,为什么有问题呢,这个b2 d f它是个四维的函数,又是i的函数,又是o的函数。
那所以说我当然把整个light transport写出来,我是不是给一个o,我就可以得到一个不一样的哦,呃这个呃b2 df这个roi对吗,也就是说我只要给一个不同的o。
我得出来结果这个row io就不一样,那所以对于任意一个给定的这个o,或者说我观察的方向对吧,然后我的b r d f都不一样,所以给定任何一个观察方向o,然后呃这个b2 d f。
或者是呃不是这个light transport这一部分,然后我都会投影出来一组完全不同的vector对吧,这样想啊对不对,然后然后就是说这就是这就是一个呃,完全不一样的地方了。
就是因为light transport维度是很高的,是四维,它不只是i的函数,也是o的函数,所以对于任意一个o都会嗯,当你把这个呃light transport,投影到2d的一个basis呃。
是在i方向上的对吧,然后投影到basis之后都会得到一个向量,那所以不同的o给你不同的向量,这就麻烦了,所以说呢对于这个向量中间的任何一个素,它都呃现在来说,它不是一个数,不是一个简单的数ti。
而是一个o的函数,这个没问题啊,这个意思嗯行,然后另外一个直观证理解怎么理解啊,因为glossy物体有一个非常非常重要的性质,那就是它是和试点有关的,对不对,然后我们之前说diffuse物体。
你不管视角如何去旋转,你看到的东西,你看同一个shading point,你肯定看到同一个东西,因为整个diffuse shading它和视角是无关的,对不对,然后对于glossy物体。
它和视角是有关的,也就是说你给一个不同的视角,他就应该得出一个不同的结果对吧,是这么一个意思,所以你你最后得出来的这么一个结果,左边这个lo,那肯定是跟o是你你有一个不同的观察方向。
它就有一个不同的l就是这么个意思,那所以说这样也就能解释了,为什么来transport,这里虽然已经把他投影到这个i上,这两位的呃,这个头已经做好了,然后但是这个ti仍然是o的一个函数啊。
这么个意思行吧,那这样说的话就会知道这个问题在哪,那么怎么处理对吧,然后这这这里就是人们聪明的地方,大家看这里,既然你已经把前面拉transport 4 d的,给投影到一个二维的东西上面去了对吧。
然后你剩下来得到的这个呃这个系数,这个ti它虽然是o的函数,但现在它只是o的函数了对吧,就是这个意思对吧,它它现在是一个二维的函数,那么它既然是二维的一个关于o的函数。
我能不能把它给投影到关于在o的方向上,我也把它投影到spherical harmonix,想进去,对不对,按照这种方式,我仍然可以把它给拆开啊,没问题啊,然后这样一来的话,那我们会得到一个什么呢。
我们我们就会得到哦,原来light transport,这里就不再可以认为是一个向量的,而是一个矩阵啊,这么个意思,那说白了就是说给你任何一个o,你得到的你会得到一串vector对吧。
那你把所有不同的o得到了,这串vector都给摆在一块,那可不就变成了一个矩阵了,这没问题哈,那这样的话大家看啊,这里是呃就是这个计算最后变成了什么呢,这里的计算就会变成说哦我最后计算的呃。
嗯就是说最后出现的这个呃radiance,它是往各个不同方向去,它是o的一个函数,那我一下就可以解除哦,我从不同的方向上面去看,会看到什么,这就是我最后看到的结果对吧,然后也就是他最后不再是一个数。
你给你任意给一个o他都可以去呃,告诉你啊,他往这个方向看的结果,那也就是说最后得到结果是个向量,在关于o的啊,然后呃lighting lighting的话,就是之前的关于i的这么一个呃一个向量。
它没有问题,他还是一直两回的对吧,那么呃大家想这一个向量对吧,你你乘以一个什么东西,才能够得到另外一个向量,所以说从这个角度上来也可以推出来,它必须得是一个矩阵的,没问题吧。
那也就是说呃这样一来呃大家就可以看到呃,说这里light transport这个matrix做了件什么事,他基本上就是告诉你说这个从ui方向到o方向,怎么样去transport的嘛,对吧行了。
那这样的话就是说关于呃glossy的情况下,那咱们就算是对之前的呃diffuse的一个延伸啊,这么个意思,然后在实际渲染的时候,大家会发现呃这里就有代价了是吗对吧,然后两个代价呢。
其实一个是呢任何一个顶点或者shading point,你都要存transport matrix,那原本说假如说你要用25个呃,spark harmonix或五阶对吧,五阶不是25个吗。
然后你现在要用的就是625个存储了,对不对,然后因为因为它是个矩阵呢,它是得变成25x25,那就非常多了对吧,一个是存储,那当然存储多了,那势必在运算的时候,你在实际上呃去render的时候。
那你得到的结果,那你肯定是对于呃glossy的情况下,你就得做一个向量和矩阵的乘,那这个操作肯定就会比呃向量和向量做点乘,那要复杂的很多对吧好啊,ok这就是关于glossy的情况。
像正常情况下人们会用多少个唉,这个spark harmonix的奇函数呢,人们通常会用三阶四阶五阶啊,就是非常低频的情况下呃,咱们上节课分析过对吧,呃三阶的话用来呃去照亮diffuse,物体已经足够了。
然后正常情况下对于glosses的话,可能你得需要更多一些高频的一些东西,因为大家想glossy lobe嘛,他的pet看起来就会比较高频嘛对吧,所以说用的比较多,大家用四阶五阶甚至更多。
然后在我们就是就是就是科研领域,差不多大家用了十阶还嫌不够呢,还有八阶十阶都都觉得仍然是非常低频的,哈哈这个事情,ok然后嗯如果说你选择了用16个g函数,那么你在呃diffuse的渲染的时候。
那计算量那就是16对吧,两个长度为16的向量做点乘,那么如果是glossy的情况下,那自然就16乘以一个16x16的矩阵,最后还得到一个16长度的将来啊。
这么个意思,ok那么glossy的情况渲染效果如何呢,大家可以看到效果还是不错的对吧,这是当年的结果了,2003年吧,应该是呃或者更早,然后就是说大家可以看到呃,那个时候呃像这种在整个环境工程下。
然后我去渲染一个这么高质量的这种,glossy的物体,一个是看起来非常不错对吧,然后另外一个它的速度其实也非常不错,那个年代就是对于glossy啊,不过大家看到了一个数据对吧,3。
6fps很明显它要比那个diffuse要慢很多了,呃那自然就是因为它计算量非常大,不过呢那个年代嘛对吧,呃呃呃硬件什么东西,大家可以看到都是非常非常早期的硬件,现在就算你什么都不做啊。
正常情况下直接实现,比如说四阶的s h描述的glossy,然后你就真正算16去乘以一个,16x16的矩阵,我估计到100是没有任何问题的啊,这个意思好嗯,然后呢呃好正好有同学问这么个问题啊,有同学问说。
如果说呃这个glossness非常大意思,就非常高频对吧,这种怎么办对吧,像这种情况下就是p r t解决不掉的问题了,这是真的哈,就是说呃对于这种情况下,你嗯就是理论上当然能解决。
你可以用非常高阶的s h来描述它,但是s h呢它描述这种非常高频的东西,描述的效果并不好,然后所以那种情况下呢接近镜面反射的情况下,你就不能再去采用呃,呃spark harmonix来做于来作为基函数。
来作为奇函数,你是可以用一些别的东西来做奇函数的,不过好像有同学对有同学直接回答说,那个时候你直接采样就好了,因为如果物体本身它接近镜面反射的话,因为你你是直接知道他是如何去反射到,其他呃东西的。
然后你这种情况下只需要去做retracing就行了,对吧,连pass都不用做啊,这种倒是可以啊,嗯不同的解决思路吧好吧,然后咱们回到这个问题上来,大家同时可以看到另外一个事情就是什么呢。
就是说呃我考虑正确的visibility啊,左边是不考虑visibility,假如说visibility都是一,那当然得到结果不怎么真实呢,那任何一个顶点,咱们比如说吧这个呃这个佛像。
他的这个脚下这个地方,那很明显,你如果往这这些上面这些地方,他会被他身子挡住对吧,那你肯定什么也看不到,他接收不到来自上面的光照嘛对吧,然后所以这里不该那么亮,然而这里考虑的呃这个阴影之后。
效果还是不错的对吧,然后所以挺好,那如果说你在做light transport的时候,然后你把多次的呃反射,也就是说嗯比如说这个呃佛像,它自己的不同的不同的部位之间,而这里这里。
然后呢呃他们之间互相的反射,也把他们给做出来,就都给预计算成light transport的一部分,那就是说我可以引入所谓interreflection的部分,同样啊呃这是呃这是可以做的。
当然上一节课我们就没有细说,这个事情到底是怎么,为什么说你可以把这些多次反射呃对吧,多次bounce给当做是light transport的一部分。
那这个要怎么理解呢,这么看啊,咱们来看这个结果呃,呃这这这样大家很明显,从左边这幅图上可以看到,这就是shading的一个呃直接光照的结果吧对吧,然后我们在games 101里面稍微提到了一点点啊。
就是在说这些就是更高阶的一些算法的时候,比如说什么photo mapping的时候,我们提到了一些关于对不同路径的分类,咱们在这里再多提一句啊,就是说啊,呃我们可以用一系列的表达式来描述,一系列的路径。
它都是什么样一个类型,比如说呢光线从发出直接就被我看到,那么我可以把它写成l啊,l就表示这个光这个光线从light里面出来了,然后e就直接进入我的眼睛,那这个这种类型的pass,我管它叫l e啊。
哎哎哎这个e就是i嘛,light就是l就是light嘛,对吧,l e就直接看到的,那大家看到左边这个直接光照,直接光照是什么呢,那自然就是light,然后谈到了一个呃什么物体上面呢。
glossy的一个物体上面去是吧,打在了一个glossy的物体上面去,然后并且被我们的眼睛看到这里面呢,如果你这个game 101又忘了的话,那那我这里先说一下,就是说正常情况人们区分材质啊。
呃在特别是在real time rendering,大家区分成三种,一种叫diffuse啊,diffuse,一种叫呃specular,specular呢就是指那种镜面,那种那种呃光滑的程度啊。
这种意思就是一个光线过来之后,它会完美地往镜面感这方向盘,这啊这个意思叫specular啊,还有一种介于中间的就叫gloy啊,就是正常金属这种,你说它像镜子吧,它还有点糊,但是你说他defuse吧。
它又不是对吧,就介于中间嗯,就差不多区分成这几类,然后如果说要求不怎么严格的话,在不怎么出现这种呃歧义的情况下,有时候说specular其实就是指glossy啊,这么个意思,如果这里呢咱们说清楚。
咱们就单独把glossy写出来好,那对于左边直接光照直接光照的呃,这个所谓啊pass的类型,这这这那就是光呃,从发出达到了一个gloy物体上,然后被你眼睛看到,那就是e最后到你眼睛没错吧。
那么呃如果是呃有呃两次棒子,像这种情况下,大家可以看到这个壶身反射出了壶嘴和壶嘴,对吧,呃在在这个地方大家可以看到对吧,呃壶身上反反射出来这么一个呃地方,它不就是这个壶嘴的这个高光对应的地方吗,对吧。
那所以这里呢大家大家会看到,如果你你的光线再多bounce一次,它是什么呢,它是从光线出发到糊嘴,然后到湖山,然后到你的眼睛没问题吧,是这么个意思,然后也就是说它可以用lg g e来来描述它。
那么对于通常的物体来说,假如说就是diffuse或者glossy,那么就是就是中间要么是d,要么是g呗,那咱们这时候可以借鉴一下,正则表达式的描述方法啊,大家都学过自动机没问题吧,啊这个正则表达式啊。
或者说模糊匹配啊,呃然后就是说light从光源出发,然后呢它可以打到任何物体上,可能是diffuse,可能是gloy,然后弹多少次,随便零次,一次两次三次对吧,我已经忘了新号能不能表示零次了啊。
然后呃没关系,反正弹射多少次,最后到你的眼睛,这不就正常,light turn transport了对吧,这个意思哈,然后你多个棒子的话,就是就是多个呗,就是就是这么一种写法,然后呢呃对于左边这种情况。
这种是很常见的一个情况,比如说光线呃,正常情况达到一个比如戒指的内壁啊,或者大家平常喝喝牛奶的时候,会比较容易看的啊,玻璃杯的内壁,然后内壁嘛这些东西都是比较光滑的,然后呃我们认为是specular啊。
就是非常光滑了,然后然后呢,他会嗯这个就反过来打到这个地面上啊,就是光线,假如说从右上角打到它的内壁上,然后打到他的这个地面上,然后最后再被你看的,这是一种典型的pass,我们管它叫l s d一啊。
l s d e,所以light打到specular,然后被聚焦到呃diffuse物体上,最后为你看的这种东西就被叫做costics啊,然后咱们之前提过对吧,然后我之前还吐槽过这件事情。
我说把它翻译成国内啊,把它翻译成焦散非常不合适,结果你它散掉你就看不见了,但没关系,我们就管它叫costics啊,然后l s d e啊,当然还可以再扩展扩展一点l s型号,然后d或者g然后也是型号e啊。
这没关系对吧,然后我为什么要这么写呢,这样写大家会发现你,你光线无论如何从light出发的,这都是l没问题吧,来看这些所有的这些light pass,它左边反正都是l,你最后被眼睛看到那中间的东西。
所有东西都是来transport,是不是这意思对吧,那如果这样一来的话,那不管它有多么复杂,不管它有多么复杂啊,我最后要算的,那那那无非就是说呃,呃就是这个整个light transport。
我只要把它给预计算出来了,那我不就知道了嘛对吧,最后的结果,所以说任何的这种light transport的这种形式,我都可以把它分成呃light和剩下的所有东西对吧,那就是这么个意思了。
呃呃所以说我们在实际上去渲染的时候,只要我们采用了p r t的一种思路哈,只要用了p r t的思路,把light和light transport拆分之后,不管你light transport有多复杂。
只要我之前预计算了,我在实际的渲染过程中,它是呃嗯非常简单的啊,就是这么个意思,就是和呃这个transport的复杂度无关的,就是你实际跑的时间啊,这个意思啊,那如果预计算呢。
当然可就是跑的时间就会越来越多了,就是渲染的时间是跟他无关的,那么自然就有同学说这要是在说明什么对吧,再说明说,你当然可以把任意复杂的light transport,都给预计算出来啊,就是想说这事嗯。
那么呃就是说呃怎么算对吧,之前咱们不是提过这个事情吗对吧,然后咱们还回到之前所说的,比如说diffuse的那个例子上来看对吧,diffuse的呃呃这块来说啊,或者说没关系吧。
就是说假如说你的light transport,然后呃这块现在是一个二维的一个情况,然后呃你要把light transport的部分,就是这个红颜色杠呃,把这部分给投影到s h上面去对吧。
这不是light transport投影到s h上面去吧,咱们上节课是出现过这样的对吧,然后呃我们上节课就说了,这个式子还可以怎么理解对吧,你是把这个函数投影到s h。
只是把这个函数和这个s h的奇函数,做了一个product integral,这是理解方式一没问题,理解方式二是这样的,你看这个公式看起来像不像就是rendering equation。
就仅仅是把lighting这一部分给改成了一个呃,某种函数,这个函数你管它多多么复杂,到底它是不是lighting,你还可以把它当成是lighting,是不是这个意思。
所以说如果你要把light transport给投影到,比如第几个basis上,比如说第16号basis上,那其实就相当于是你认为你在用第16号basis,呃,他把它给当做哈哈,把你当做一种光照。
用它来照亮每一个顶点,并且把每一个顶点上照亮的结果给记下来,那自然而然你就会得到一个,就好像是你在用这种光照来渲染这个场景一样,没问题吧,那所以说像这种情况下。
就对于任意复杂的like transport,你都可以这么认为吗,就等于是认为说给定了一个光照,这光照就是spacle harmonix的奇函数,然后你用它来渲染出来的结果。
诶诶啊回来ok然后就是说仍然是正常的渲染,那这部分正常的渲染,既然是预计算的,预计算的话,你有光照,你有这个这个running question,你用什么方法都可以解,用。
用pass tracing对吧,用什么方法都可以做得出来,所以说无论如何,它是可以做出来的,就这么理解,就把他理解成是呃,这个light transport的预计算就是一个渲染过程。
只不过这个渲染过程呢哈哈,他就是好像是在一些奇怪的lighting的情况下做,另外呢这张图显得尤为奇怪啊,我把它说明白是怎么回事,这张图看起来奇怪,这个红色蓝色是因为他用了这种可视化哈。
它把它的值给显示成了红色和蓝色,来表示它是正还是负,红的越厉害表示越越正,然后蓝的越厉害越表示负黑的表示零啊,这么个思路,然后就仅仅是因为它可视化,造成它看起来会比较奇怪啊。
如果说你要把它给显示成是其他一种,什么样的颜色呃,就是像我们平常用的这种这种可视化方法呃,那那反正就是用这种光照去得到一个。
渲染图而已啊,这个意思ok啊,就是这么个理解方式,然后呢那大家大家可以看到,那对于呃不同的b2 d f,如果你说不只是glossy吧,对任意的b2 d f,反正不也是四维的吗。
然后呃呃你就可以得到一些呃,比如说像iso topic的b2 d f的一种现象,大家可以看到类似于对着这个这个鸟啊,它肚子这么旋转着这么摩擦的这个结果哈,呃金属,然后呃中间这算是比较正常的吧。
然后呃右边这这些看起来就比较不一样了,因为大家可以发现他不止有一些,比如说类似各项异性的一个结果,它还有一个属性叫做special varying,意思就是不同的位置上。
它可能拥有完全不同的b2 d f,这里从这个弧有点生锈,这个角度上可以看出来对吗,不同的地方呃,他的b2 d f还不一样,b r d f还是四维的,但是如果你考虑整个物体的话。
它不同位置有不同的b r d f,就意味着它现在变成了一个六维的函数,两维的表示它的不同的位置,另外四位表示在这个位置上,他的b2 d2 的值对吧,然后也就是说它是一个更高维的东西,但是没关系。
就是说只要是呃你能够把它表述出来,就肯定是有办法可以用预计算来做的啊,这么个意思,然后咱们看一看当年的一个结果,ok大家可以看到呃。
他突然换了一个光照啊,在这里对吧,然后也就是说,你只要预计算过这个光照都没问题,现在在旋转什么呢,现在好像是在旋转lighting对吧,然后哦这里现在变成了旋转视角,然后旋转lighting和旋转视角。
都是可以得到一些不错的结果哦,现在材质变成glossy,glossy的情况下,旋转光照自然而然会有不同的结果对吧,但是旋转视角的时候也会有不同的结果,这个这个大家从这壶身上的确定变化。
可以看得出来,对不对,哎所以说呢呃呃呃这是非常不错的一个效果吧。
然后这里就是之前我说的那么一个呃,就是你不管啊transport有多复杂。
然后你肯定是都可以预计算的啊,就只说这么一个意思好。
那这个回了嗯行,那么简单总结一下,就是说嗯之前最早的这篇p2 t,然后他做了一件什么事,他提出了用spherical harmonious的奇函数来描述。
lighting和light transport两部分,然后呢呃对于diffuse的情况下,就可以在实际的呃渲染过程中,每个顶点做一个点乘的操作,然后如果是glc的情况下。
每个顶点就做一个向量乘以矩阵的一个操作啊。
这么一个意思啊,然后当然他有他的问题,什么问题呢对吧,然后一个是他嗯,s h本身它当然有很多不错的性质对吧,但是它有一个不好的性质,那就是它基本上只适合用于描述低频的函数啊,大家注意这个措辞啊。
不是说他不能描述高频的,只要你给他足够多的这些像他就可以描述高频,没问题,但是实际中他就是就是呃,由于说你用没那么多的想得出来呃,并没有多好的高频的表示方法,而不是方法表示结果啊,然后嗯。
所以说平常人们会认为他不太适用于描述高频,比如说这里对吧,大家还记得这个例子,你就25个呃奇函数啊,你去描述这么一个相当高频的一个环境,光照对吧,然后你其实一旦恢复出来,你就基本上不剩什么了对吧。
然后你如果用,那还是一样,上节课如果没注意的同学啊,这不是26个啊,这是26平方个,也就是26阶啊,这这边n等于25,是五阶啊,这是26阶,用了那么多个,然后他他才能基本恢复出来一些高频的东西,对不对。
也就是说他不太适合做呃高频啊,然后呢呃我们之前说要关注p r t,它它的好处是什么对吧,它可以可以比较准确的算出整个环境光照下,甚至多次bs下呃,整个一个场景啊,他最后渲染出来的结果。
当然也可以考虑到它准确的visibility,这是非常好的对吧,但是不好的地方就在于他做了一个假设,要求场景,你只要预计算了,一旦预计算了,就意味着固定住了,是不是这意思对吧,那既然固定住了的话。
那呃就是说呃场景就不能再动了,所以是静态场景,然后甚至你预计预计算了它的材质,比如b2 d f都已经预计算好了,那就意味着你在场景中就不能够动态地,改变它的材质,那就非常不好对吧,然后另外一点呢。
你自然需要大量的预计算的数据,然后这些存储啊或者别的什么东西,这些都会在实际的应用中会造成不小的负担,对吧,ok那么既然他有这么一些问题。
那么之后的人们呢,就嗯研究出了各种各样的方法,来试图去解决这些问题啊,那咱们看什么呢,就是说有同学研究出来了各种不同学啊,有科学家们哈,研究出来了各种各样的呃心型的啊,奇函数。
就是说咱们不用s h s h有点问题了对吧,咱们用点别的啊可以,然后呢有同学也说惯了哈,就是说啊这块这块研究呢又有人指出说这个啊,嗯嗯就是就是现在预计算了什么对吧。
预计算了lighting和light transport,但我能不能预计算更多的想,比如说我预计算lighting计算,又预计算visibility,又预计算剩下的那些部分b2 d f什么的。
哎这样的话我到时候预计算的过程中,我就不再是一个所谓dot product了,就是不是两项相乘再积分了,会变成三项相乘相乘再积分对吧,然后以及会不会有更多有这块,就是呃有相当多的研究在做这个事情好吧。
然后呢,呃呃呃有人发现这个问题说是呃静态场景呃,呃就是p r t嘛限制了场景必须得是静态,那自然是不好的,那我有什么办法能够说我又预计算,我又可以允许这个场景,一定程度上发生一些呃变化安,那就非常好了。
是不是,然后呃还有一系列研究,就把p2 t的这个思路给拿到了一些呃,复杂的一些材质上面去,比如说半透明的材质以及像头发,然后像这些啊,然后最后有一点其实非常重要的一点,那就是呃呃有人研究说啊。
这个预计算确实是不错,但是还有预计算啊,也有它很多问题嘛,那我们如何能够不预计算,然后我们争取能够把所需要的这些东西都能够,解析的解出来,呃当然要经过一些近似了,对不对,那就非常好了对吧嗯。
所以说呢在这里在这里这样啊,我说呃一点事情啊,一个是什么呢,唉从这些问题上大家可以看到啊,从这些follow up work,大家可以看到一个事情,就是说对于科学家来说,你可以看到最难的是什么对吧。
最难的其实是发现问题,而不是解决问题,因为即使是像这个来预计算,分明就把场景给相当于冻结住了,那为什么还还还会有科学家研究出来,怎么样才能让这个场景动起来又可以呃,之前预计算对不对。
也就是说只要有了这么一个问题,说我们争取能够想办法解决,科学家们总是有办法能够解决的,这是个非常非常好的事情,而最大的问题在于说呃说是发现这么些问题啊,就是特别在p r t这篇paper之前。
那人们肯定根本就看不到,说会有什么呃什什么这这这些问题对吧,就是说如果没有引入预计算这么一个概念的话,那这些问题不存在,那自然也不会有人研究了对吧,这是一个事情啊,跟大家说,发现问题总是难的。
解决问题总是简单的啊,这个意思嗯,然后呢另外一个事情是这样,这里呢有一个典型的例子,就是咱们在讲p r t之前讲的split sum,大家还记得吧,在环境光照下怎么算shading。
不算visibility的情况下对吧,怎么算shading,这个就是典型的这个解析的方法,当然呃加入了一些什么预计算的项目,就是计算了一张表嘛,大家还记得吧,二维的一张表,但是那个就非常轻量级了嘛。
然后我们就可以认为,它基本上得到了一个解析了解,那这样的话对于材质的shading,那用那种方法,那肯定会比precomputation要容易很多对吧,然后正是因为在过去差不多10年嗯,甚至15年吧。
也就是呃p r t出了几年之后,有一些方法渐渐的开始考虑,说我开始用解析的方式来解这些问题,而不用于计算,然后就导致说p r t在过去的10年内,并没有那么火啊,这么个意思,然后但是我的一个感觉啊。
我的感觉不一定对哈,就是说我觉得在未来呃,特别是这段时间real time retracing的兴起,很有可能会把p t再给重新提出来啊,这么一个思路啊,看吧啊,看看之后是个什么样的情况。
我自己也挺感兴趣啊,这个意思好,那么呃差不多我们先停一下好吧,我们先停一下,看看同学们有什么其他问题啊,ok有同学之前问说light transform复杂的情况,预计算时间是不是要变多,对没问题啊。
噪声是想说是想说我们怎么样做一个special varin,b r d f对吧,那这里是这样的,就是说p r t关注的更多是你,你知道了这个special lvarin b2 d f啊,各个各个位置啊。
不同的b2 d啊,假如说已经知道了,你还是可以计算,就是你怎么得到呢,就正常情况下,人们会用一些呃这种呃可以控制的噪声来描述,咱们咱们之前在101里面提到过一点吧对吧,什么play noise之类的。
ok呃那这样哈,如果同学们没有什么其他问题的哦,还真有glossy p r t里面视角方向怎么决定,而不是视角方向怎么决定,而是你首先要预计算对于每一个视角方向,就是每一个o你都要预计算一套啊。
这么个意思,然后就是说哦有同学说矩阵毕竟不能无限大,那没问题,说的对,那这回我理解你说的意思了,就是说你不可能说这个这个视角方向,它是有可能在整个球面上都都,这个所有方向都有可能有对吧。
你你肯定还是得从中选择一些对,没问题,正常嗯,这个大家就会呃选择一个grade,然后在grade中间去呃决定一个视角方向,然后只要你决定了一个呃这个观察的这个方向。
然后你就会把其他的所有东西都要与计算一遍,想一想,这是个非常复杂的过程对吧,然后预计算结果不是存成light map,有同学应该是把这个和呃什么light baking,什么东西给混在一块儿了是吗。
就是这块来说,因为预计算的维度是非常高的,然后你不能把它简单当成一个二维的一个表啊,ok嗯行吧,那那这块先这样啊,然后因为我说还要给大家介绍一下啊,呃这个呃其他的basis function对吧。
我们之前说小波啊行吧,在这里我先看同学们还是踊跃的问题啊,挺好的,我先回答一下吧,就是光栅化里面怎么做这个事情做不了啊,正因为做不了,所以才会有这个专门的做retracing的硬件吗,现在是可以了。
dx r是可以做的,direct x retracing啊,是已经可以结合在光栅化里面做呃,实时的re水醒了,然后另外这位同学问这个问题,是说预计算也要写在光栅化里面的。
我怀疑是其实想问这个事情不需要啊,运算出来成这个这个程序之后的结果存在,比如说硬盘等,然后你在做这个实时渲染的时候,再直接把它读出来,这么个意思,要不怎么叫预计算呢。
对吧呃p r t在工业界有什么具体应用,那太多了,基本上来说这啊一直到现在哈,电影和游戏里面还都在用这些东西啊,spherical harmonics,lighting肯定到处都是啊,这个没问题啊。
啊ok啊预计算可以理解成物理材质,可以可以理解成物理材质的一部分啊,嗯ok还有同学问到rtx,我就不再多说了哈,关于这块,因为这个说的有点远了,ok那我这样我先把web说完啊。
然后就是说大家可以看到有人研究了很多,各种各样不同类型的其他的一些奇函数对吗,然后奇函数呢,呃嗯这里给大家列举了一系列的东西,来给大家看一看,大家知道这个这块,大家研究出了多么恐怖的东西。
在markhamox之后啊,大家研究出来各种各样的什么呃,小波来描述呃这些呃二维的一些函数,然后还有人找到了一系列的数学工具,叫做zo harmonix,它和scarl harmonix什么关系呢。
咱们不说了这个意思,然后还有一些球面高斯函数,sg也是二维的函数,理论上来说啊,不应该管它叫基函数,但还行吧,没问题,然后还有之前我说的徐坤老师做的,peace with constant的基函数。
这都是呃一系列的算是经典的工作吧,然后这让我想起来,差不多在15年前那会儿就是m s2 a啊,微软亚亚洲研究院啊,做了很多很多跟p2 t相关的工作,那时候做的非常厉害啊。
ok啊那么这里呢简单的给大家介绍一个。
那就是小波,而且咱们不会详细说吧,就是呃为什么呢,因为这块来说,如果大家不学信号或者干什么,可能接触不到这个概念还是挺重要的吧,或者说挺有用的,简单跟大家提一下,那么小波是什么,小波呃。
刚才说了是一系列奇函数,不过这里呢我们说我们的理解是呃呃,或者说我们要谈论的主题是二维的小波,大家可以看到二维的小波是一系列奇函数,也正画在右边了,对不对,然后这些呃呃小波呢。
它有一些非常呃和s h不一样的性质,比如说不管任何sparkle monica的计函数啊,它是都是呃定义在整个球面上对吧,然后对于小波来说,它是定义在一个,大家可以认为是一个图像块上的。
而且呢不同的这些小波它的定义域还不同,比如说大家看到这些第三列,第三列整个右半边都没有,第三行,整个下半边都没有啊,就是说大家看到黑白的地方才是呃,这这这些小波这些函数它各自的定义域啊。
这么个意思区别了哈对吧,然后呢呃但不管怎么样,大家从右边可以看到它是写正和负,就表示这个值是正的还是负的,就有点像这个step function对吧,呃就是类似这种这种小波。
然后呢这里还说清楚小波呢有很多种,我们这里说的一种小布叫哈尔小波,h a r这种小波他是有明确的这种界限的,然后有一些小波长得非常奇怪的,但没关系,就是一系列函数呗对吧,他还是在二维的情况下对吧。
然后只不过它不定义在球面上,定义在单定义在一个块上,这也没关系嘛对吧,然后呃我当然要关心的是两件事对吗,我第一给你任何一个函数,我肯定也可以把它投影到各个不同的小波,对应的基函数上面去对吧,这没问题。
然后呢,这就是小波和spherical harmonix的不同的地方了,我们说为什么spherical harmonix,可以用来比较压缩的,或者说比较紧凑的来描述一些函数呢。
是因为我可以先给他一个阶段对吧,我就用前多少阶的s h对吧,然后我就可以恢复出来若若干频率的呃,这样的呃原始的函数就通过这种方式来压缩,那么小波的压缩方式不是这样的,小波的压缩方式是这么一种运作方式。
给你任何一个函数啊,2d的,你可以投影到任何的这些,所有的这些小波的奇函数上去,你投影到gr数上去之后呢,呃你会发现大量的时候是这样一种情况,就是很多奇函数对应的系数是接近零的,ok然后呢,这样一来。
就自然而然给了你一个非常不错的压缩思路,那就是说啊我就娶他啊,这比如说对应的系数最大的多少个,那如果其他有很多这些系数都接近零,那那些我我就不要了对吧,然后我就把那些给扔了,然后这样的话呢。
就是人们所说的所谓nonlinear approximation,就是我通过这种方式保留非零,或者说保留最大的多少个呃,然后通过这种方式来近似的描述,或者恢复一个原始的函数,那么它有一个最大最大的好处。
和s h相比,最大的好处就是它支持全频率的表示全频率,意思就是说我可以表示低频。
也可以表示高频,那就非常厉害了,对不对,那么咱们来看一看啊,对于这种小波平常来说,我们所关注的事情就是,怎么样把任何一个函数给投影到小波上,是不是,然后呃嘿正好有同学问这个问题啊。
如果说小波他是定义在平面上的,那么我用来描述一个呃,2d的一个球面上函数的时候不会出现缝吗,哎这种情况就是大家聪明的地方,这个时候大家就自然而然的用cube map来描述,这个22d的在球面上的函数了。
就不再用什么spherical map或者别的什么,那cube map就是六个面,每个面它都是一张图对吧,都是一个正方形的图,那咱们说清楚啊,然后对于cube map来说。
这个light大家可以看到六张图,每张图单独做wave let变换啊,就是小波变换,就是所谓把一个呃图投影成小波的系数,大家可以看到做了件什么事呢,就是说做小波变换,首先呢对于任何一个图,他都把这些呃。
比如说呃呃一些高频的一些什么信息啊,给留在呃,对于任何任何一张吧,咱们就以这张来说啊,原本他是这么一个结果对吧,原本是这个呃对于任何一张图啊,他都先把这些高频的一些信息给留在他的,这个右上呃。
右下和左下这么三个小块里面,把它稍微低频一点东西给集中到这左上去,然后那个左上还可以继续再做小波变换,然后又把高频的东西给留下了,然后低频的东西放在左上,然后大家会发现一个事情对吧。
高频的东西好少啊对吧,然后就是说对于对于这些绝大多数地方,他好像都是零,对不对,那是非常好的一件事情,然后就是说不断去做这样一系列的呃,呃小波变换,那我就可以得到一个非常不错的一个结果了。
就是这么一个思路哈,ok啊哈哈哈哈,请问对,很像四杀树说的很对,没有问题,那我这里呢多说一个事情什么呢,就是说呃大家可以看到给你任何一张图,你用小波变换,然后呃你你就是就是说先变换,然后再保留下来。
就是说非零的这些值,你会得到一个非常非常强烈的一个压缩,没问题吧,然后这个压缩质量也会非常不错,又能保证高频,这就是为什么有一种图像格式叫做jpeg的格式,jpg哈,这个格式然后他就用了啊。
我们说清楚不是小波变换,是一种类似于小波变换的一种变换,叫离散余弦变换,叫dt啊,这种和和小波变换挺像的一个道理,就是说通过我先把它投影,然后再取它的非零的投影出来的这些系数呃。
然后得到一个非常强烈的压缩啊,能这么这么一来的话,就是呃算是补充一个小知识啊,这个意思好,那么呃ok这里就是就是关于这个小波变换。
然后我再保留下来一系列的这些非零的值,那自然其他的东西都一样嘛对吧,我就是说只是嗯就是说我把小波换成了烦了啊,我把s h换成了用小波来描述哎,那用小波来描述之后,是不是可以得到一个比较好的结果呢。
大家可以看到诶,还真是对吧,用相同的存储量,这个小波呢呃可以可以,那渲染出来非常高频的阴影,没问题吧,哎高频的阴影就意味着你对这个lighting的描述。
就是你把高频的lighting的信息给你描述下来了,嘛对吧,然后大家可以看到右边这张图,这张阴影就就非常好,但是哈哈哈哈哈,有同学这就是正好问了这个问题啊对吧,就是嗯这也是特别在图形学中啊。
嗯不太能够存在,说有一种方法能够完美的,把其他的什么什么方法都给干掉哈,不太存在这种情况,小波有一个非常严重的问题,什么呢,小波不支持快速的旋转啊,这是一个非常严重的一个问题,我们之前说这个光照对吧。
光照咱们不是说可以那个吗,可以可以呃,旋转光照等于旋转basis,旋转basis呢,s h basis是很好旋转的,它的一个basis旋转之后,可以用同阶的basis来描述对吧,我们之前说过对吧。
但是s h呃,不不不,但是wavelet他就没有这么好的性质了,那就是说你要是想旋转一个光照,那对不起,你就当当它是一个新的啊,这新的光照吧,然后然后你就得把它先给解开,先给解开成。
比如说一个6x64x64的一张呃,一个cube map,再把它投影到waf lt上面去,再取他的钱多少个,那这不是没意义了嘛,对吧,就是说这样一来的话就就就比较惨。
当然所有的这些方法都有各自的好处坏处啊,这是没问题的啊,ok嗯那行吧,反正就是给大家介绍一下,然后我刚才说了对吧,有很多各种各样不同的其他的方法哦,哦这里是这样的对吧,大家看这个这个这个标题啊。
我就说这里这里是呃人们在呃用不同的basis function,不同的基函数上做的研究,而这个研究并不是针对于说解决这个呃,动态场景说怎么样去解决啊,而这块呢我就真的不能再多说了,再多说的话是这样。
我说句实话,s h呃就单讲啊,不不单讲p r t这么一个系列,咱们就已经可以开门课了,真的是这就是说可以讲非常多节,这是没有问题的,然后呢这里呢呃是差不多在这里停住,然后就是同学们就差不多知道。
p2 t的一个基本思路,然后呢u p r t也比较难写,工业界呢用的不是特别多,然后如果说大家希望在,呃非常简单,大家去参考rv的呃p r t的一个survey啊,这是写的最好的一个啊,哦说起来啊。
而这样吧之后我会补上好吧,以后也尽可能早的给大家发出来,ok啊那这就是这个这个事儿啊,说一说wait啊,另外一种表示方法,那么这里呢给大家说一说我的故事啊。
嘿嘿我的第一篇paper其实就是和p r t相关的哈,然后呃这个在做什么呢,基本上来说就是在做呃,在呃spherical gaussi,刚才我们才说啊。
spherical gen另外一种basis函数呃下,然后我怎么样用它去渲染半透明的材质,什么是半透明材质呢,大家从右边可以看到什么玉石呀,像这些皮肤啊,这这这些东西就是半透明材质。
咱们之前gm 101说过对吧,然后spherical高省简称sg啊,这个呃它有一些非常不错的性质,大家可以看到左左边,左边它呃可以描述呃,一个非常高频的一个环境光,并且可以把这些高频这些点都找到的。
非常清楚啊,这是这个事儿嗯,好然后呢呃这当年啊我第一篇paper呃,大三的时候呃发的,然后呃发在了嗯pacific graphics,2012啊,那当当时啊,然后我这反正挺难的了。
就是然后当时为了做这篇paper呃,我平常大三的,那不是大三,平常正常大学的情况下,我有点呃有点懒啊,早上不愿意早起,然后所以我天天不吃早饭,但是我大三为了做这篇paper,我天天吃早饭,为什么呢。
因为我每天在实验室,我要熬通宵,然后熬到早上差不多七点的时候,吃完之后回去睡觉,睡到11点是上午11点半,然后我再去实验室周而复始啊,大家可以看到我这个还是很努力的,对不对,这样说的。
这个正经一点的事情是对吧,你你有什么样的对手,你就得付出多大努力吗,那个时候就是说如果要付出呃,如果要做一个嗯,那至少pacific graphics,这肯定是算是世界级的呃这个这个会议了对吧。
然后为了让paper中还是要付出点努力的,这是肯定的,唉呀行吧嗯呃这就是那个时候啊,大家想一想,从距离我第一篇paper到现在,不知不觉已经过了9年了,夸张吧,这个事情哎呀行吧,就是从那个时候入坑的啊。
更早1年对吧,我大二下入坑,呵呵行吧,哦对还有一个事情啊,2021将会在新西兰惠灵顿召开啊,如果同学们要参会的话,是就是新西兰,我之前去过,然后嗯是个非常美的地方啊,非常好,然后如果同学们有兴趣的话。
去这pg参会啊,非常不错,好哎呀哎嗯对,有同学反映说我这啊我的头发经历住了考验,是的嗯嗯好嗯啊,不过说起来是这个意思,我只是说这是经历哈,我先说清楚,绝对不好绝对不好绝对不好,然后然后就说努力行。
但是尽量别挤占自己休息时间,这是真的哈,ok嗯好,那这这里还有什么问题吗,同学们,然后如果没有的话,咱们开始说这下一块的内容哈,嗯ok哦,另外是这样哈,呃同学们之后也不用特别担心说我这课之后呃。
照这样说下去,每一节都要往后面这个攒那么一点点,这不是营养进度嘛,中间我们要是什么时候需要多讲一点,就是global illumination的话,我想的这块比较重要,也许会挤占一部分的,就是后面的呃。
呃shading,就是就是呃基于物理的材质的这块的时间,所以说时间上没什么问题啊,咱们就把问题讲清楚就好,ok行吧,没什么问题,咱们开始进行下一环节啊,就是说关于呃实时的全局光照啊,ok试试诶。
还真有同学们有问嗯,好我看看哈,有有同学问有没有全局光照的作业由啊,作业三就是啊是基于屏幕空间的,不是咱们今天要讲的世界空间啊,然后讲讲retracing的时候会讲底料一下会啊,没问题,这是核心啊。
ok啊p r t是实时全局光照嘛,哎啊是这样啊,p r t能做这这全局光照没问题啊,但是我们把它给归为说可以做environment,lighting和全局光照之间吧,好吧嗯是这个意思好。
pb 2在光栅化和光线追踪下面,计算方式是一样的吗,他是这样哈,他该是一样的对吧,因为不管是用什么方式,他肯定只有一种正确的描述方法,但是p p l做了一系列的简化,然后就是说在这种合理的范围内。
然后计算方式会得到简化,但得到的结果会差不多,这个意思,信号相关后面知识用多能呃,我想了想,后面应该不会再多用了,基本上来说就是spark honics这块,我们理解一下它的频率的问题,好吧。
这个意思啊,那行那咱们现在开始继续了哈,嗯那咱们现在要讲的是新话题,新话题要讲实时的全局光照对吧,咱们刚才已经说了,全局光照非常重要的一个呃,缓解能够极大的提升真实感对吧。
然后我们要讲这两块r s m l p v好。
然后呃怎么样真增强真实感,大家可以看到这么一个呃图啊啊,这幅图当然渲染的结果了,然后呃这是一篇关于全局光照的一个survey paper啊,做的呃做的teaser image给大家补充点知识。
什么叫teaser image,就是指论文开头的一幅大图啊,这幅大图是用来炫耀自己做买的东西啊,这就叫ta啊,然后通常大家都会下大力气来好好做,然后大家可以看到这幅图里面呢。
很显然光照就来源于窗户那边对吗,然后就从窗户那边,当然有很多东西它不能直接照到,但是没有任何地方完全是黑的,然后也就是说光线是可以弹射很多次,然后才到人的眼睛的,所以说如果说只是用光栅画来做直接光照。
那这幅图大家可想而知,很多地方都是可以的对吧,那所以说全局光照是非常非常重要的一个环节,我们一定得想办法把它给弄出来,否则的话看看很多东西都会觉得不真实,那么有同学就会立刻联想到一件事情。
我们之前曾经做过一个hack,在games 101里面做过一个hack,然后打全局光照,这这这都不叫近似了哈,这是这完全是hack出来,就是这么一个意思啊,如果同学还记得的话。
这就是我们所说的不灵魂的光照模型,里面的对吧,然后这个模型里面呢假设了一个叫做呃环境,像ambient term对吧,还记得这回事,这个在假设说呃,这任何一个点接收来自四面八方的间接光照。
都是相同的对吧,然后呢,这个得到的最后shing的结果,和自己的normal还都没有关系对吧,做了很多这种这种假设,然后最后就认为哦,原来ambient的像就是往上面增加一个亮度对吧。
那从这幅图上大家来看,全局光照是不是都能这么high呢,不能完全不能对吗,因为大家可以看到很明显在这个书本的底下,它各个地方它的啊,它的亮度也都不一样的对吧,然后大家可以看到一些costics啊。
这些这些就是从这个金属球反射到桌面上对吧,这些东西都是完完全全不一样的,所以说简单的靠,把最后的结果往上提升一点亮度,这是绝对做不到全局光照,还有这么个意思,那呃它很复杂。
这就是我们要得到的一个结论对吗。
然后呢呃我们在实时渲染过程中,我们要解决什么全局光照,咱们把这个事给说清楚,因为咱们之前已经区分过概念了,全局光照其实指的就是直接光照加间接光照,没错吧,然后呢我们会认为直接光照都好做对吧。
直接光照我们完全可以做出来了,从之前所说的各种各样的方法对吧,然后呃split sama别的什么东西,比如之后也还会继续说,那么直接光照好做,那么剩下来的问题是什么呢,间接光照。
间接光照呢光线又可以在场景中弹射无数多次,那这个事情肯定是弹射越多次越不好解对吧,那怎么办呢,那就是在实时渲染中咱们说清楚,人们呃说要解决实时光照,实则就是想解决一次或者说多一次bounce的比。
比这个低比这个直接光照啊多一次,bce的间接光照,也就是大家数一数,基本上来说在这张图里面啊,光线弹射两次没问题吧,看到了吧,就是在红墙上一次在做那个呃这个小box,左边这个面上弹射一次。
然后被你看到对吧,然后这就是我们在实时渲染中要解决的呃,所谓全局光照啊,实则就是呃让比直接光照多一次的间接光照啊,然后人们当然希望两点,第一简单实践起来不麻烦,对吗,这是一个,然后另外一个呢是呃快速。
这是非常重要的事情对吧,因为全局光照非常难算,然后咱们待会儿探2s m,就知道它为什么难算了好吧,然后唉行吧,那就是说呃这就是我们要解决的问题啊,咱们说清楚一次的间接光照啊。
然后这里我们应当如何理解一次的间接光照呢,那如果有同学还记得game 101上,咱们之前说pass string的时候,哎这个时候曾经出现过这么一幅图对吧,然后然后我们说过这么一件事,如果在p点嗯。
就是就是说做tracing嘛,那肯定是从camera出发,对方打一条光线打到场景中的一个点p点,这个p点呢往各个不同的方向去发射光线,它有可能会达到一个呃光源打到光源的话呢。
那他不就是呃接收到直接光照了吗,但如果说打到的不是光源,它打的是另外一个点q点,那么它是怎么理解的对吧,他会认为从q点反射到p点的结果对吧,也就是说radiance那个就是来自于这么一个方向。
从q到p呃,它的这个radiance就是p两个,直接呃呃接收到的光照,也就是说在p点呢,他并不关心说,你接收到到底是从呃直接光照来的,从那个light来的这部分。
radiance还是反射来的radiance,这没关系的对吧,从q反射过来的readings一样在b点参与计算,那么呃从q反射到p的radiance又是什么呢,那就是在q点。
q点本身接收到的直接光照对吧,咱们之前说过这么一个事儿对吧,那么这里我们再多想一步,就可以得到一个非常不错的一个结论,什么呢,这个q点是不是就是被光线直接照射到的物体。
就是说接收到了直接光照的这么一些物体表面,这些物体表面是不是可以认为,他们在场景中会作为光源出现,并且用他们自己反射出的这些光照,然后再去照亮别人,没问题吧,所以说啊一切被直接光照照到的这些物体。
都会呢继续把自己作为光源,而且我们给它起个名字叫做次级光源,secondary light source,然后大家可以想象到,真正的光源就叫primary light source,对吧,呃这个没关系。
那那行,反正就是说呃这就这么个意思吧好吧,然后那那既然我们有这么一个理解了,那咱们现在看之前还是这么一幅图,但是呢这里我们做了一些标记什么呢,就是说啊这里就直接光照,直接光照在咱们说清楚。
直接光照可不代表说他就是要么黑,要么白的对吧,直接光照它,它如果是面光源,比如像这个场景,它这个天窗上面在相当于是巨大的面光源,所以它有的地方它肯定会有个渐变嘛,但没关系,就反正这就是直接光照对吧。
光线弹射一次能够得到的光照和阴影没关系啊,这是一个事儿,然后呃呃然后是呃什么呢,就是说后面的这个诶有同学问灯笼怎么哦,我懂了,就是啊,这这就先忽略吧,好像这暂时关系不大,ok行吧。
然后就是说整个这个场景上来看,基本上来说大家可以看到,比如说p点,p点由于它在柱子后面,直接光照,是无论如何不可能接收到任何的直接光照的,对吧,但是这个场景中间毕竟有很多地方,可以接受到直接光照。
咱们可以用一系列的这些啊,这些小太阳把它给标注标注出来对吧,是111些,当然标注的非常稀疏哈,其实任何一个表面只要被照亮,你比如说问这个nn底下这个地方,他是不是作为一个刺激光源出现了呢,是啊当然了。
任何一个被照亮的这个呃呃就是所谓surface patch吧,对吧,或者说刺激的这个光源都会用来被照亮别人,什么意思呢,也就是说p点它是怎么接收到光照的,唉他其实就是这些所有的次级光源。
然后我们用这些次级光源去照亮p,然后得到的一个结果是不是哈哈哈哈,然后所以说啊特别是考虑one bounce,这个indirect或者叫global illumination嘛对吧。
然后也就是说光线会多弹射一次,也就是说从这些次级光源,它再照亮这些物体,中间不再发生额外的弹射次数,再照亮某一个什么诶,这样的话我是不是就可以得到呃。
一次bounce的indirect illumination,加起来不就是global illumination了吗,所以就是这么一个意思哈,其实大家可以想到呃,呃这是呃。
我们对这么一个间接光照的一个理解哈,也就是说已经被直接光照照亮了的物体,或者说表面会自己作为别的呃,作为光源在照亮别人啊,这么个意思嗯,行ok嗯,那么我们要介绍的一个呃基本的一个概念哈,rs m对吧。
reflective啊,shadow mapping啊,这就是在用这么一个思路啊,来试图渲染出这种间接光照,那么他是怎么做的呢,诶他首先他会呃要解决这么一个问题对吧,什么问题呢。
就是说如果我想得到p点的这种间接光照的,shading的结果,刚才咱们看到的对吧,那个p点如果我想得到呃,就是用这些刺激光源照亮它,得到的确定结果是什么,这不是indirect nation吗。
我想得到他需要知道什么,这就是我们要问的一个呃问题,ok这是很有意思的一个事情对吧,我我为了计算这个点p,它最后的间接光照是多少,我需要知道什么,那很简单,我们需要知道两件事,第一哪些是我们的刺激光源。
换句话说,哪些这个物体表面的这些位置,会被直接光照照到,这个没问题吧对吧,然后我们问这个问题呢,呃这这肯定就会有同学就直接想到了,我们之前已经说了一种方法对吧,这种方法就完全就可以告诉你这个信息吗。
哪些哪些物体可以被这个光源照的,或者说照的有多么的亮对吧,然后从0~1对吧,然后然后就是说呃呃这块,那很显然有同学直接可以回答了,shadow mapping就是告诉我们这个信息的对吗。
假如说我们就只有一个点光源吧,还是认为简单一点好吧对吧,然后这个点光源我shadow map,就相当于从这点光源看向场景,我看到什么,那不就是这些能够照亮的吗。
哎那我就是说我可以通过shadow map来回答好,没问题,那么第二个问题是什么呢,第二个问题就是说我可以把嗯,这些所有的这些小的这些surface patch呃对吧,照直接被直接光照。
或者接收到直接光照的这些呃刺激光源的呃,把他们的贡献呃都给计算到这个点p去,就是说每一个这些刚才画的那些小太阳对吧,都有可能照亮点p吧对吧,这是没问题的,那么他们各自的贡献都是多少。
他们各自的贡献都是多少,我都求出来之后,然后我是不是就可以把它们加起来,然后这不就是我最后得到对这个p点的这个,间接光照的一个计算了吗,是不是这个意思对吧,然后呢,那我们现在这样想哈。
就是说我们刚才一直在说,每一个这个小的这些物体表面对吧,每一个小的物体表面,它既然是物体表面啊,它肯定会有一个诶,它往各个不同的方向反射,它肯定得有个radiance,这没问题。
然后他本身又有一个范围叫做area对吧,它本身有一定的这个大小,然后这个怎么算呃,一个这样的物体表面,它对点p的一个贡献,那其实就是要解一个什么呢。
是不是就要解一个呃rendering equation,并且是一个area light下面的一个render equation,那肯定有同学已经想到了。
我们之前在game 101算这个pass string的时候,我们不是说对于light有一个对对,对light进行采样一个公式吗,一个area light,然后对他采样。
然后让让他来用蒙特卡罗的方式来去做一个点,shading,也就是说我们之前曾经讲过很类似的东西对吧,所以肯定可以解决的,那么呃呃行,具体怎么解决呢,这就是咱们后面要说的这个这个事情好吧。
然后我们先high level说清楚第一步先找到哪些呃,呃物体表面处能够被直接照亮,第二步,然后我们来看这些被直接照亮的,这些小的这些块啊,然后如何贡献到这个点p去,就是他们如何在照亮点p啊。
这么个意思好嘞,那么第一个问题咱们刚才已经说了对吧,然后shadow map就可以完美的解决这么一个问题,然后呢如果说你有一个airlight。
你甚至可以用这些soft shadow mapping的方法,可以得到这么一个就是不同的点,它的入射光的强度对吧,这是没有问题的,然后嗯另外一点呢,对于shadow map。
咱们之前在说他的一些artifact的时候,我们说对于shadow map应该怎么理解呢,我们可以理解成一个shadow map上的任何一个像素,其实都对应了一个小片,是不是这意思,这没问题吧。
然后就是说呃这些小片,然后然后是场景中间的一些一些,实际上的一些小票,他们可能有场景中间自己的脑某对吧,这也没问题,然后但是嗯但是这么一种描述方法,就是对于任何呃对shadow map上的任何一个。
像素或者文素txt啊,然后呃他表述表述的这么一个场景中的一小块,刺激光源的一个一个微小的单啊,这个没问题,或者换句话说这个意思啊,给你张shadow map呃,你从light看向场景,你你这个分辨率。
比如说512x512,那么你自然而然是不是就有了,512x512个呃这种哈嗯刺激光源的对吧,因为你每一个像素内部,你就认为是一个小图片呗对吧,这没问题啊,然后所以说你要做的事情。
其实就是说用那么多个刺激光源去照亮点,p得到的结果是什么,有同学已经想到问题了对吧,这个计算量是不是非常夸张的一件事情,但是可想而知他该是这样夸张的事情,没错吧,因为你要算呃。
就是说总共弹射两次或者一次的呃,indirect illumination,本来就是个n平方的问题嘛对吧,所有的patch都可以贡献的,所有其他的patch对吧,就是这个意思,那所以说他本来就该是这样。
那咱们怎么样把它给做快,这个没关系,但是首先咱们先想清楚,就是说shadow map给了我们一个场景的一种,离散的一种表述,每一个像素,它可以认为这就是我的一个次级光源,好,这是没问题的对吧。
理论上好嗯,然后呢对于任何一个呃这种刺激光源,然后呃我如果说我固定一个观察的方向,我肯定可以算出来它的shading的结果对吧,因为我shadow map这边生成,我就已经知道它的光照的方向了对吧。
任何一个像素嘛呃光照方向知道了,然后呢我如果观察方向知道了,我就可以算它是ding唉,但是观察方向呃这里呃有点不一样,什么呢,就是说如果你要你要呃,最后去渲染这么一个场景。
然后你要看它渲染出来的结果的话,呃然后这个时候他的观察方向就是你的camera方向,呃,可是呢我们如果是需要算一个呃,算个什么呢,就是要算嗯,诶稍等一下哈,是不是有同学反应断了,ok好像没关系吧。
好像回来了啊,我这边好像是ok的,ok行吧,那我就先先这样说,如果有问题的话,我估计到时候录播的时候应该是没问题啊,呃行好,那那是这样哈,就是说呃我刚才说哪儿来着啊,对我刚才说的是这个意思。
就是说你不是要用各个次级光源,也就是每一个像素你是要照亮点p嘛对吧,这这那也就是说你的观察方向其实是什么呀,其实相当于从点p去观察这些这些次级的,呃光源对吧,你不是从你的camera去观察他对吧。
也就是说你的出射方向你不知道,对于不同的点p来说,然后然后你出射方向是不知道的,妈咪怎么算,它是谁定的,这肯定是不能算的嘛对吧,那这个时候怎么办呢,有什么办法,才能让我们不依赖于说观察的方向呢。
那这里面自然而然就产生了一个,经典的一个假设,什么假设呢,我认为所有的反射物咱们说清楚,reflector啊,所有的反射物都是diffused对对,只要它反射物是divs。
我们知道他我不管从哪个方向看过去,我从p点上看过去,我从camera看过去,没关系,反正我看的都是一样的东西对吧,那我认为所有的反射物都是diffuse的,那就可以了行吧,那这里呢我着重强调反射物。
意思就是为了区分,我不需要假设接收物也是diffused,ok我们所说的是次级光源,我们假设它都是也就是接收到直接光照的,这么些东西,在物体表面,他们认为是diffused。
我不要求点p是diffused,ok这里说清楚,ok所以说这不是一个非常大胆的假设,这算是正常吧,我觉得问题不是特别大,正常人们去如果还把这个reflector,还认为说可以是glossy。
好像就太难了哈,这个意思啊,我觉得没问题啊,这里好,那那么这样一来的话,唉我就不用管,这是从各个不同方向上去看会是什么呢,对吧,那没问题,那么问题一算是这么解决了呗,对吧,然后我知道我看到的场景中间。
哪些是次级的光源,并且这个光源它反射出去多少能量,这我也知道了对吧,那问题二是什么呢。
怎么用这些刺激光源去照亮这么一个shading,point p,对吧好,那么为了回答这个问题,咱们先回顾一下之前呃,电子101里面说的一些关于哈哈哈,关于这个叫什么来radiosity。
我又忘了嗯这个词他们的概念啊,就是说衡量或者准确的描述呃,嗯光照的一些属性的一些一些概念啊,什么呢,首先是嗯一个在这这这个图之外的一个概念哈,叫做flux或者叫power,大家还记得吗,哦辐射度量学。
感谢同学们,对没错,flex或者power这是一回事,这基本上来说就是表示整个的就是能量是多少,对吧,然后呢如果我们想描述一个呃,一个单位立体角上对应的能量是多少。
那么我们引入了这个概念叫做intensity对吧,其实叫做radiant intensity,这是全名,然后如果我们想想表述在一个单位的面积下,它对应的能量呃,它这这就是这就是什么呢。
这就叫irradiance对吧,那如果单位立体角又单位单位面积,然后它上面能量是多少,那这个就叫做radiance行吧,总之就是说这块不管什么时候听都是停绕的,这是嗯,但是我觉得吧待会推导这个式子的话。
还是算相对简单啊。
这个意思,那我现在就试图回答一下这个事吧好吧,那么现在是这样的,我们之前就说了,那所有不同的这些呃,小的这些patch是不是都有可能贡献到这个dp,那没关系,我就先考虑其中一个对吧。
我把所有的这每一个都算出来之后,我把它给算出这个加起来就可以了对吧,那我就考虑一个小的patch,然后说小啊,它是真的小对吧,它是一个像素对应的一个patch啊对吧,那这个ph是非常小的。
然后就是说这里对应到什么呢,这这个touch,基本上来说就是呃我们的rsm上面的一个呃,一个text对应的实际的一个patch啊,这么大,然后呢用它来照亮点p,然后得到的结果是什么。
那呃大家应该还记得这事儿对吧,咱们之前gg 101说,这种情况下我们原本再点p,我要算就是就是说这个light他的贡献,我原本要对整个立体角去做采样,我说这样做不好。
然后我们说呃不是浪费了很多sample嘛对吧,然后我何必不在light上面做做采样,然后直接去对p进行shading对吧,然后这样的话呢呃如果大家还记得的话,之前我们把立体角给描述成呃。
用另外一种变量替换的方式,我们描述成这个对这个呃,不是对立体角的积分了,而是对于这个area的一个积分,就是对这个light的一个积分,没问题哈,这个意思,然后也就是说上面就这个公式来说。
没有任何特殊的地方啊,这就是之前所说的内容呃,101的内容,那么这里呢呃大家可以看到,我们想要的是什么呢,我们为了算嗯,最后我看到的一个出色的一个结果,那看到的自然就是这个呃,就这这p点这l o嘛对吧。
没问题,然后呢呃我我不知道的是什么呢,我不知道的是说呃这个patch呃,他在被直接光照照亮之后往这个方向,然后它会反射出多少的radiance,确切说咱们刚才已经简单说了,其实是可以知道的对吧。
然后呃那这块就是从q点到p点,它的这个radiance是多少,然后呢,然后这个patch自然还有一个它的大小,那么咱们现在思考一下啊,如果这个patch比较小的情况下,如果比较小的情况下。
我这个积分甚至都不用积分对吧,我我直接把这个da给写成他的真正的面积,dela a把所有东西乘上,是不是就ok了对吧,这个是没有问题的,咱们想一想,黎曼积分把一个呃区间划分的足够小了之后。
那这个区间内的积分结果怎么样近似呢,这这我就取这个积分中间的某一个位置,比如说我说这个q点,就是这个patch中心的这么一个点,反正整个patch都比较小嘛对吧,然后呢那我自然而然就知道呃。
我呃呃这项是多少,咱们假设待会可以算啊,然后visibility是多少,其他东西b2 d f啊,这些项这些都没问题,最后乘以delta,那就是呃这个呃patch的area大小,那没问题。
也就是说这块是可以算了的,已经可以算了的对吧,然后那我们我我我们想一想这个事情啊,现在剩下来的就是说,怎么样准确的把这个从q点到p点反射出来的,这么一个radiance给解出来,那怎么把它解出来呢。
那首先我们说对于reflector,reflector也就是p点在的那么一个patch啊,他如果是diffuse的话,那我们就可以认为他的b2 df是呃,某个呃这个常数对吧,比如lb 6除以派嘛。
咱们之前推导过,然后这里区分一下,这里的b2 d f,指的不是这个公式里的b2 d f,这个公式的p r b2 d f是p点的b2 d f,它可以是个loy啊,然后呃这个指的就是嗯呃之前在q点处。
他的b2 d f k我应该写清楚了啊,不过还行吧,没问题啊,然后这个patch呢,我又知道他他的这个li从q点到p点,其实就是他的出色的这个radiance对吧。
我想要的就是这就是他的出色的radiance,同学们想一下这个事情啊,呃出色的radiance呃,然后怎么样和b r d f联系起来来着对吧,那就说明什么呢,说明b r d f就是我们要从什么地方入手。
b r d f定义bdf怎么定义来着,出色的radiance除以呃,呃这个叫什么来着,呃入社的irradiance没错,也就是说出色的radiance,li。
其实就应该等于b r d f乘以入射的irradiance,这里入射指的是q点的入射,也就是说直接光照的那个入射哦,ok哈哈哈,然后erence是什么,radiance就等于flux或者是哈哈行吧。
越说越麻烦了对吧,就等于是flux去除以它的这个这块的面积好吧,ok然后为什么我们要这么做啊,这么做的一个好处是,当你把这个东西描述成这个式子之后,然后你把它给带到这个li的时候。
你会发现一个更好的性质什么呢,因为这个area都已经被消掉了,看见没有,这边最后有一个delta对吧,然后这边本来也就有一个delta是吗,然后你如果说啊,对于呃呃你你想知道任何一个reflector。
它这个l是什么,你就直接用f r乘以它对应的incident,the flex就行了,incident flux是由光源决定的,他这个是没问题的,ok所以说呃对于嗯reflector。
他的b r d f是常数,然后呢他他的入射的呃呃呃这个flex指导,然后我们可以把呃呃这个five和呃这个f2 ,就这两块给成在一块,这就是人们平常所说的reflected flux啊。
这这不是一个多么标准的定义,但没关系,就是说也就是说对于radiance呃,不对于reflective shadow map,对于它上面的任何一个像素,我其实要的是什么。
为了得到他的这个反射出来的li是什么哈,我其实就要一个这个东西,这个phi乘以它的b2 d f,也就是它的reflected flux就ok了,然后这样一来的话有个好处。
我甚至都不需要知道这个patch,它对应的这块大小是多少,就是说这因为什么呢,因为这da和da消了,你会发现存flux的好处,就是我要么原本我就存它的这个叫什么呢。
就是他的incident radiance和他的area大小,都说我存两个数,现在呢我都不用存两个数,我就存一个数多好呢对吧,那所以说这这其实就是一个简化的一个,一个方案啊,就是说如果你真的就去存呃。
对于任何一个a text,你去存他的入射的incident radiance,这肯定可以吧,你从light知道了吧,你知道它的da是多少,你这个之前,因为你因为你完全可以知道这整个场景。
怎么投影到你的shadow map上的,所以你da也知道你存两个数也能解决问题,没问题啊,这就是说对于这个paper它的一个小优化,这个意思就通过这种方式,它就只用存呃,呃就是说呃还是我刚才说的啊。
incident flux乘以b2 d f,也就是reflected flux这么一个概念啊,这个意思嗯,然后呢嗯最后得到一个结果什么呢,大家会看到如果你存这个东西,这里发1p。
其实这里就是它的这个b r d f乘以,就是reflected flux啊,这两项f2 乘以y,然后那就把这一项给换掉了对吧,然后da消掉了,da消掉了,然后呃中间呃这块。
最后最后你就可以用这块的入射的呃,irradiance也就是他的这个e p啊,然后和这块的b2 d f结合在一块,积分出来的结果啊,就这么多少,ok也就是说这里并不要求说你的呃,对于点p。
他的b2 d f一定得是这个diffuse或者gloy,glassy是可以做的啊,咱们说清楚,这就是这个意思,然后呢大家会注意到两个上哪两个上,哪一个v v是什么,咱们之前在上一幅图里面。
就就这这里说的清楚对吧,就是p点到q点到底能不能看见,那反映在我们的这个呃呃呃实际的这个应用中,就是我的任何一个所谓reflector呃,或者说surface patch。
或者说呃刺激光源能不能看到我的这个点p,那那这个问题就很难了,哎为什么这个问题很难了呢,因为你这个时候就不能不再能用嗯shadow map来做,为什么你总不能允许说。
你对任何一个shading point。p你都生成一个shadow map,你去看向之前所有的那些刺激光源吧对吧,然后然后就是说就是说你要所有的四级光源。
你都要判定他们对所有可能的shading point,他们的贡献是多少,这是又是一个n平方的问题,你是不可能直接通过一张嗯no嗯,一张shadow map来得到这个visibility。
于是这个visibility不好算不好算,怎么算呢啊那就不算了,就是这么个意思,就是人们在这个呃reflective shadow maps里面,他们就不去算次级光源和。
我实际的就是第二个pass的情况下,这个可见性就是它它中间这块呃,这个确实是没法算啊,这这块嗯,因为确实它本身就是个n平方的问题啊,这个意思这是问题一啊,问题二是什么呢。
问题二是这里啊大家可以看到这个公式里面哈,就是这个公式是从呃这篇paper,这篇paper名字就叫reflected shadow maps,大家可以看看一看,找一找相关细节哈。
然后就是说呃就是说就是说这个公式里面,大家可以看到它下面有一个,这两个距离的四次方,看到这种东西了对吧,然后呢,大家可以看到说我这边推导,推导出来是什么东西呢,我推导出来是平方对吧。
然后然后这个平方很好解释,它就是就是相当于是我把立体角给换成area,measure,它必然要产生的一个,也就是说从p点到q点的一个for all of,哎就是就是这么个意思,这这没问题。
然后他这里四次方我百思不得其解,然后我觉得是这个意思啊,就是说呃我呃这样哈,我慎重的考虑了一下这个事情,然后我得出结论是他写错了啊,他真的写错了,因为工业界的话,而而且错的原因我可以猜到啊。
我可以猜到什么呢,就是说呃应该是他无脑的假设了,在工业界的一个基本假设,就是认为radiance在传播的过程中,就是这个li就是这个这个radiance,在从p到q到p的传播过程中,会有一个平方衰减。
工业界常常做这个假设,ok如果他做了这个假设之后,那这个l你算出来从q发出到达到p的时候,然后他又有一个平方衰减,这个假设是非常不对的一个假设,之所以之前人们假设,就是因为为了适应这个呃这个平方向。
也就是说他其实double count了一下这个事情啊,这是我得出来的一个结论,然后然后我我就直接下结论,他说错了啊,这真的是错了,然后就是说如果同学们有兴趣的话,自己推导一下。
如果觉得我推的不对的话啊,这么个意思,然后就是说它它绝对应该是平方,ok然后如果是四次方的话,同学们我直播吃键盘怎么样啊,这样安排哎呀行,那这就是就是说呃这个意思啊,哦另外paper里面p和q是反的哈。
然后这个嗯就是说他们会认为是是p点,照亮q点啊,这没关系啊,这个意思啊,我立flag啊,就是这么回事,ok好那这一步就解决了是吗对吧,我就知道任何一个patch呃,或者四级光源怎么样啊,照亮一个呃。
任何一个shading point对吧,还是这个意思好,那么嗯有了这个事情之后,基本这个问题就解决了,那么还剩下一些小问题,那咱们把小问题说清楚什么呢,呃第一个是这样的,就是说在r s m里面。
大家可以看到这不是光源吗对吧,光源照亮整个场景,然后这个这个那啊这上面这个p点,这就是它的这个paper里面标的就是每一个text对吧,它其实对应到你这呃实际物体上,它有一个某种patch是吧。
大小没有画出来,然后呃呃每一个这样的patch,比如说这x1 x2 ,然后左边的x-1 x2 ,他似乎应该都是对x能够有贡献的,按刚才这么一个计算方式啊,呃这个呃这个意思嗯。
然后呢嗯有时候他这些东西是根本不需要算的,就是你知道他百分之百不会有东西啊,什么时候呢,就是说呃当你出现了一些呃,呃首先当然是visibility的问题了对吧,咱们刚才已经说了。
他们会忽略一切的任何一个这种这种刺激光源,和shading point之间的一个呃可见性哈,这不考虑不考虑的问题好像也没有特别的大,因为反正是间接光照嘛,就已经不像直接光照那么的高频了对吧,这是一个。
然后另外一个方向上,从方向上其实就已经可以看出来这东西,为什么呢,因为你看啊,比如说咱们以x-1为例,x-1是哎这个shadow map记录,他应该记录的是这个桌子吧,桌子这么一个表面在这。
然后这个它的法线在哪儿呢,他法线是向上的对吧,然后这种情况你又知道桌子和这个这个,shading point的连线是往这个方向上去,所以他是根本不可能哦,哦就是说就是说这呃呃这里记录了这个patch。
而是根本不可能照亮x的啊,这是没问题的,就是说他有很多这些这些判断啊,然后就是说呃,我们当然通过这render equation本身就可以解它,只不过这里给大家一个形象的一个呃,这个这个说法。
然后嗯比如说吧这个距离肯定也是吧,咱们咱们可以认为说哦如果距离离得非常远,就咱们刚才说的那个平方对吧,呃然后如果距离离得非常远的话,然后嗯是会有这么一个呃事情呢,就是就是说他的贡献。
他本来经过了一个距离平方,他贡献就已经非常少了对吧,那所以说呢你基本上来说,给你任何一个shading point,你只用找离它距离比较足够近的这些刺激光源,是不是就ok了对吧。
这其实是一个不错的一个观察,那么这个观察就会造成一个不叫造成什么,就会引出一个很不错的一个技巧,什么呢,就是说这篇paper做了一个极大的一个假设,你怎么知道对吧。
我问给你一个shading point,你怎么知道离他比较近的,比如说某个区域里面,他们刺激光源呃,都都都是什么对吧,都都都在哪,都在shadomap的哪对吧,那么这个时候啊。
这边微博做了一个非常大胆的假设,什么呢,就是说哦我想找的是在世界坐标下,它们两个点比较接近,那么我就我这个不好找,那我就把shading point啊,p点投影到shadow map上去。
我在shadow map的周围一圈范围内,我去找,我认为shadow map上他离得比较近,或者说比如说深度会离得比较近,或者shadow map上离得比较近是吧,这么个意思,然后呢。
那我就认为它在世界坐标内离得比较近啊,通常情况下这种情况也不算不合理对吧,但是就是说这是一个比较大的一个假设吧,这是肯定的对吧,然后呢同学们肯定想到为什么要这么做呢,咱们之前说了对吧。
给你任何一个shading point的p,这个贡献都要算一遍,所有text对这个点批了这么一个贡献,那每一个shading point,你要算512平方次计算这个还得了啊,对不对。
那所以说你肯定不能这么假设,你怎么怎么办呢,就尽可能减少你要算的这些数量,那么刚才说的是一个思路啊,就是说在shadow map周围的一个范围内去查,然后即便如此,你也可能会面临着比较呃。
嗯大的一个范围之差嘛,那怎么办呢,那就是说呃呃这种情况下嗯,他就可以做一些啊比较聪明的一些采样方法吧,就是说咱们之前说pcs s也是这么一个道理,对吧,给你一个范围。
你要做blocker search对吧,你要做filtering,你不希望把这些所有的这些范围呃,那个那个text都给走一遍,你就随机的采样一些,可以没问题的,所以这个时候呢一个道理。
在shadow map的周围某个范围内,你去采样一下,然后就可以了,那至于说这个paper,提出了什么样一种采样的方案啊,比如说比如说哪些地方我多采一点,哪些地方少踩一点,但是权重会多一点对吧。
是这个意思,那你可以大胆想象啊,离你那个shading point呃,那个对应的shadow map的位置周围,那应该踩的稍微密一点,如果离得远一点,踩了输一点,但踩的疏一点,就意味着。
你其实相当于你把很多像素的贡献,当成一个了呗,那这很多像素占据的面积肯定要增大呀,它它对应的贡献他的权肯定要大一些啊,就这么一个思路,就是说这些就是很非常heuristic的一些,一些做法。
工业界的一些trick了啊,这我就不再多说了,但是不管怎么样,通过这种方式,他们把它减少到了,如果我没记错,几百个啊,400个吧,比如说对于任何一个shading point,我去取呃。
iosm上面的400个呃这种呃,这就是txt,然后来把他们当作刺激光源,然后来照亮这么一个神灵幻影皮,那那就好了,然后得到一个结果,ok那没问题,然后所以所以说这样的话就能承受了吗。
那至少400比512平方的好太多了,哈哈这个意思行吧。
那呃咱们总结一下,shadow map上多存了点东西,那shadow map本来要存depth,他还要存对吧,然后这里多存了一些世界坐标,用来判断实际上两个点的距离嘛。
咱们要钻shading的时候要用对吧,然后又要存,肯定要存这些反射物,他们的法线对吧,这肯定要知道的,然后用来算了cos一项,然后这里又要存它的flux flux,咱们说这是跟光源相关的一个属性。
它和这些不同的表面的法线都没关系,所以大家看上去就像是一个平的算数,light shading的一个感觉哈,这么个意思,然后嗯所以说基本上就是就是存这么写对吧。
为什么存这么写,咱们之前的公式就已经都已经讲清楚了,那它的效果如何呢,效果是非常好的,然后呃这里说一下啊,效果非常好,其实是怎么说呢,就是说对于某些现象非常好,特别对于什么来说,对于呃手电筒啊。
几乎这些游戏里面,现在一旦涉及到手电筒,都非常愿意去用这个啊,rs m,我猜的原因是因为手电筒啊,覆盖一个范围相对较小吧对吧,你不需要一个非常大的rs m,然后就意味着说嗯这个分辨率就会比较低对吧。
那分辨率低就意味着快对吧,那所以说适合用手电筒,那么嗯它效果的话大家从上一行和下一行啊,这这里大家可以看到这是the last of us,呃然后他下一行是开启了这个rs m的,上一行是没有的。
那大家可以看到下一行要比上一行要亮对吧,那有同学反应它好像就亮那么一点点,这有什么实际作用吗,有啊,大家看这个天花板上是不是绿一块,是那个藤蔓反射出来一个结果对吧,就是说很多这些这些啊是啊叫什么呢。
间接光照啊,他肯定要比直接光照要暗很多嘛,但是就是说就是因为这么一点点这些细节,就会让你会觉得说看起来结果就会好的特别多,这是真的啊,这么个意思,尤其是你来回切这两张图就可以看得出来。
这样看着呢不是特别明显吧,ok然后大家看到不止是the last of us啊,很多游戏都在用战争机器四,然后还有这是什么神秘海域四对吧,都在用这个呃呃呃这些呃叫什么呢,就是说用2s m来做手电筒啊。
然后大家大家当然这也就看到问题了对吧,那如果说你你要是有呃啊。
这样咱们反正之后要总结的嘛对吧,然后2s m有什么好处对吧,因为它其实就是shadow map的流程嘛对吧,他就是shadow map的流程,你第一个pass生成一个rs m。
第二个pass呢你就只管从眼睛开始看上场景,你不是每一个像素都要做shading吗,那你就那每个像素就是那个shading point p了,然后你要算所有的这些呃,他的贡献是多少,ok好吧。
那这好算对吧,然后容易实现,那么它问题问题是非常多的,一个问题是唉大家知道这是shadow map,shadow map肯定有shadow map自己的问题,不管他是什么2s m对吧。
他肯定会共享shadow map肯定会有的问题,那就是你有一个直接光源,咱们说清楚这里的light的数量啊,指的是直接光源,或者说呃primary light source的呃呃个数啊。
呃直接光源它的个数,那他有多少个直接光源,你就得做多少个shadow map,那当然就得做多少个reflective shadow map了,这就不好对吗,那就会越来越慢啊,这是一个。
然后呢啊我们刚才说在这个计算过程中,他们不去算反射物到这个shading point,之间的可见性,那自然而然会造成很多呃不真实的情况,就是人们人眼啊是非常厉害的,人们看到一些一些场景呃。
一些图片自然而然立刻就可以分辨出来,这些结果看起来不怎么自然,不怎么真实啊,或者说不是人也是人脑,还是我们平常训练的这个大脑对吧,然后呢一眼就可以看到不真实,很多情况下也是因为这个原因哈。
没有做这块儿呃,反射物到shing point的visibility啊,当然也做不了,真做不了,就是大家想一想,之前环境光到一个shading point怎么样去做呃,阴影对吧,这不完全一个问题吗。
环境光来自四面八方的圆的,都这不同方向都是不一样的,嗯然后照亮不同的shading point,他也是个n平方的,或者n乘m的这么一个级别的问题嘛,那所以说嗯大家可以看到在实时渲染中。
现在的这种n乘m的或者n平方的问题,仍然不是好不是很好解决对吧好啊,这里呃不多说,然后呢呃呃他当然做了很多不同的假设对吧,咱们咱们之前已经已经说了,对于呃假设这个反射物它得是diffuse。
然后呢嗯对于这些呃距离什么东西呢,它会认为说在shadow map上的这个这个距离,或者什么的,就是就就一定程度上能够反映说呃,实际的这个距离对吧,咱们刚才也说了,在采样的过程中对吧。
然后这些呢都有可能会对质量进行一个啊,造成一个不好的影响,这是真的,然后最后呢当然就是说你既然考虑到sample,sample的话,咱们同学们开始对pcs s,应该是已经截止了对吧。
然后所以说大家写pcs s意识到了,对不对,但现在当然是用多的sample效果就会好,用少的就会不好,但用少的就会快对吧,所以说他永远有一个这么这么一种诶,trade off在里面好吧。
那么呃在这之后呢,我再说两个呃啊我想到了两个点啊,什么呢,一个是呃2s m现在用了这么一个概念,它不是相当于把shadow map上,任何一个这个小的像素啊。
它都当成一个surface patch来看对吧,这其实和离线渲染中间的一个重要的概念,叫做virtual point light或者叫vpl方法是非常非常接近的,或者更广义一点来说啊。
这些呃vpl方法在这个实在离线渲染中,曾经在反正20年之前好像还一直有人研究呃,呃然后它属于一个更广义的呃,方法叫做instant radiosity,叫及时辐射度。
或者叫i2 instant radiosity,然后这块来说就不是基于光线追踪的啊,最早不是基于光线追踪的radiosity,然后后来及时辐射度呃,算是引入这个v p l方法。
然后它可以和关键追踪结合的非常好啊,这么个思路呃,所以说之后如果说有各种各样的文献说,提到说这些什么东西是vpl,就是virtual point light,可以理解成。
就是这种小的surface patch或者是点光源啊,都没问题,然后呃ok这是一个事情,然后另外一个事情了,大家注意到这个事情了对吧,我们平常说shadow map是呃图像空间的一个做法对吧。
因为他们在第一个pass的时候,就已经把一个场景给变成一张图了,之后我再渲染什么东西,其实就从这个图里面去寻找信息,这里是一样的。
我们其实reflective shadow maps经过一次shadow map生成,我们就已经可以得到所有的这种呃,他需要的所有信息了,我就可以得到这个信息了,然后我之后就只用第二个bounce。
我正常去从camera渲染每一个点,我就可以得到结果,所以呢其实呃,他应该算是一个图像空间的一个方法,但为什么我这里要把它给当成,3d的一个空间呢,是因为我其实希望这么来归类。
就是说这种方法他不会受到呃,最后你这个所谓camera pass是否可见呃,造成了一个信息影响,或者这样说它不存在呃,就是一开始就记录不到,就是他从从理论上来说就记录不到,就会丢失信息这么一种情况。
而这种情况是图像空间呈现的一些问题,因为你图像只能记录一个图像,而这里面呢基本上来说你就真正的记录到了,所有需要的信息了,所以我把它理解成是3d空间啊,另外一点呢,为什么是3d空间呢。
因为呃之后要提的方法也就是lpv方法,然后他会建立在rs m基础上,不过今天没时间讲了,咱们就先到这好吧,先到这哦,还是一样哈,就是说呃之前咱们不是说了吗,呃把两节课并成一节课。
咱们正常情况下时间就按照嗯差不多,这呃国内两个45分钟的课时来安排啊,然后差不多吧,我觉得这是之后就就就就这么来,然后再看之后我想一想嗯,下节课我们来讲,lpv和v x g r应该会讲的非常快。
应该会讲的非常快,就不至于说嗯,这着重来说一下这个呃具体方法怎么做好吧,嗯然后我们再讲图像空间,ok啊行吧,来看看有什么问题吗,嗯好行,如果没有的话,那咱们嗯到这吧啊作业二咱们开始说了吗。
就是呃顺利的话,这周末发布好吧啊ok啊,下节课咱们把这个3d的内容说完,然后呃看看这个图像空间的这种算法,还有好多呢,s s s就是指指屏幕空间,看大家看到好多,然后到时候我们在2月说吧啊ok行。
那今天就讲到这儿啊,行一周一节,这已经算是很多奖了,是对这算正常多讲之前是唉不好意思,哎行吧,这真真的按克容量来说足够了真的足够了,我觉得同学们平常大家想一想,正常情况下要真是按照这个时间来算。
只有像什么数学分析那种超级大课,才会出现这样的时长对吧,ok哈哈哈哈哎呀行,也不见得真的短学期变长学期啊,是是就是说呃如果过了sirrah asia之后,我要是真的有点时间,也就是在5月底之后。
如果我心情好的话,到时候再把它给变回一周两节也没问题啊。
就是说到时候都好安排啊,都好安排行啊行,总之就是今天咱们就先到这儿好,不然后行吧,然后呃我看同学没什么其他问题了,先这样啊,先这样,然后还是一样,下节课啊,那就是下周国内周六对吧,然后到时候再看。
ok好,那就先这样,感谢同学们,下周咱们再见啊。
今天的文章 GAMES 图形学系列笔记(三十九)分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ji-chu/87869.html