05.渲染中光和材质的数学魔法 | GAMES104-现代游戏引擎:从入门到实践 - P1:GAMES104_Lecture5-change - GAMES-Webinar - BV1J3411n7WT
Hello,大家好,欢迎大家回到games104游戏引擎的理论与实践,那个今天这一讲的话呢,我们会继续讲渲染,那么这一讲的话呢,其实也是我自己认为是难度最大的一家,我们整整爆肝了一个星期吧,然后说实话。
我到现在虽然写完了整个课件,但是我并不是特别有信心,我们能把这一讲解好,为什么呢,因为这一讲的内容实在是太大了,如果说我把今天这一讲的内容,分成十节课来讲的话,我认为也没有什么太大问题。
那么今天这讲什么呢,我觉得就是讲绘制绘制最核心的,绘制的核心是什么呢,其实像上一节课我们讲的就是A材质对吧,讲到这个材质啊,那个mesh啊,包括一些GPU,你怎么怎么去组织管理,听上去好像都非常有道理。
但其实这些道理呢,你把这么多数据放在这,你让GPU去做,但其GPU到底怎么做呢,他需要绘制,那这里面的绘制的第一个主角是什么呢,就是光光的核心就是光子,就是光子发射出来反射被吸收反弹。
最后进入我们的眼睛,形成这个事件的光的原理是什么,那么第二个呢就是这个光和材质,就是和物质到底怎么反应对吧,我这物理是当你把你光是反弹回去,还是把你吸收进去,还是再让你在我里面转来转去。
那么你的这个物质和光是怎么反应,这件事情又决定了这个东西,我们看起来是什么样的,那么最后一个的话就是说,我们我们的SHADER该怎么去写,有很多复杂的运算,所以其实这节课讲的这个东西啊。
就是说我们讲lighting material shader,就是光材质与这个着色器,实际上是一个非常庞杂的一个系统,我自己啊竭尽所能把它挤进去了,但是这一节课的课件长度,已经接近100页左右了。
90多页,我记得好像有90多页,然后其实我自己有感慨啊,就是我我写完这个课件的时候,跟我们的团队在一起,我学着我们是把过去几十年,就是全世界最聪明的这些理论学家。
就是图形学的这个科研工作者和工程师在一起,各种非常惊人的聪明的想法集结在一起,但是这里面有很多大胆的讲,假设非常这个我认为叫厚颜无耻吧,这个打个双引号,就是说基本上是什么都不管不顾的。
各种hack放到一起,他居然就work了,然后就终于形成了我们这种,非常棒的这个游戏体验,所以说啊这节课的话呢,我觉得我们就是虽然讲的东西非常的硬核,而且中间我首先高能预警一下,会出现很多。
非常非常这个这个看起来让大家头疼,肚子疼的数学公式,但是呢大家可以当成一个故事来听,就像我我我是我跟大家讲,我是一个很民间的民间的物理的这个爱好者嘛,就典型的民科思维方式。
所以我最喜欢的一本书叫量子力学300年对吧,他就是把这个人类认知怎么怎么从简单到复杂,一步一步的去建立,这样的一个一个就是对对世界的本源,认识的越来越清楚的过程,这中间就是各种的观点的碰撞。
各种人的想法在一起打架,这事读起来津津有味,所以我我其实今天在写这一趴的时候,我基本上说那来这样吧,既然硬核的知识讲不了太深,那我就跟大家讲个故事吧,所以呢首先的话呢,我们就从这个故事的原点开始。
这个这是最著名的,就是渲染最核心的那个我们的宗师吧,叫柯基亚,那卡西亚的话呢,这个这个是个日本老哥,日益老哥,我不是,我忘了,他是在美国大学教书,还是在还在日本工系统,好像是在在美国。
然后这这位我们的大圣,那个我们的先贤在35年前就提出了,那个时候sf大家记住了,那时候sf好像还没有电子版,我印象特别深,好像是那种打印出来的版本,我觉得是惊为天人,然后呢老人家就写了一组方程。
说唉呀同学们这个全世界所有的渲染,用这一个六维方程方程基本上就讲完了,你们就就膜拜吧,其他的事情你们就不用想了,这个方程看上去很高大上啊,但其实也蛮简单的,你仔细看他说呢,就是说你在一个点。
你去观察一个物体的表面任何一个X点对吧,这个点可以是啊二两维的点也可以,三维的点,这个多少具体多少维度要数一下了,那么你首先有一个观察角对吧,就是那个欧米伽O,那就是你人的observer的观察角。
那么首先的话呢那个点它是不会自我发光,他如果自我发光的话,那他在omega那个O的那个角度射出来的光,肯定会让你看到,对不对,好第二个呢他得加上什么呢,加上说这个点,如果被很多其他的周边的光源给照上了。
去的时候,它会最后反射出来会是什么样的,一个一个一个一个一个结果,那么这个时候它就是一个呢积分项,就是说从所有可能的球面上的入射角,射出来的光,然后呢它投影到你的表面。
这里面注意要乘上一个cos theta,这cos c塔是什么东西呢,就是说你可以理解成就是如果光斜着照过来,同样的光强,你的表面上能接受的能量是不是会越来越低。
这件事情听上去好像很这个cos西塔很高大上,其实呢去理解它其实非常的简单,比如说太阳光照到地球是不是无差别的,对不对,那为什么在纬度高的地方就会冷,纬度低的地方就会热呢,因为在同样的单位面积上。
纬度高的地方的话,它乘上了一个就是你的那个那个高纬度的那个,球面上的那个那个就是我们的垂直向,就其实就是法向和太阳光的那个角度,那如果在极地的时候,那cos theta几乎为零对吧。
在那个赤道的时候几乎为90度,所以呢你接收到的能量就会很高,然后呢这个时候有另外一个方程,我们叫scattering function,就是说呢他会跟你说,哎你在这样的一个入射角下。
在这样的一个出射角下,你大概有多少能量能够被反射回来,这里面到底发生了什么,很奇怪的就是光电子反应,那个就是卡基亚同志呢也没解释,但是说这肯定是一个思维方程就能解决了,这个思维方程呢就是这个最著名的。
我们叫做BRDF叫双向,这个那个反射分布方程对吧,这个是让我们所有做图形学的同学,做graphics engineer的同学,都是这个叫什么叫魂牵梦绕,这个这个就是既向往又害怕的这么一个方程。
所以凯基亚同志的话,这个这个六维方程,基本上就把渲染的东西全部讲完了,对不对,这个是将近35年前,但是呢这整整35年,我们整个行业就被这件事情搞得死去活来,那为什么呢,因为真实的世界的光照非常的复杂。
就是大家看这张图吧,这张图的话也是一张很经典的图了,他就跟你讲说,你看啊,我就画这么简单的一个书桌的一角,你看到它有直接的光线照在我的书桌表面,变得很好看,对不对,变得很亮,然后呢。
有些地方它呢就是那个光会被一个物体挡住,它会形成一个我们叫做shadow阴影,对不对,大家玩游戏的时候,最在乎的就是这个shadow做的好不好,这个阴影其实比大家想象的非难很多,好这事我们就忍了诶。
但是这个光呢你打到这个很多表面,它又反射了,反射了之后,它本身又变成了一个光源,又照亮了别人,这就很蛋疼了对吧,这个就是我们在那个有个很著名的说法,叫COLORBBLEEDING。
就是比如说你这个反射面如果带颜色的话,这个颜色还可以去反射出去,然后呢你还有一些非常glossy的物体,它本身像个镜子一样的,就直接反射回来了,然后呢还有一些半透明的物体。
光在里面就是做了reaction,就是在里面折射,做了好多次光机又出来了一下,那你想这么多东西,这么多效果,这个你说它符不符合科基亚老先生的方程呢,是非常符合他的方程的,但是呢问题是我怎么解对吧。
而且我所有的东西必须要real time的去解它,这就是我们的挑战,那这里面呢我们很难的点是什么呢,就第一个就是以下的这几个挑战,是我纯个人总结的,就是我我得声明一下,就是因为呃。
很少有人像我对这个老先生的这个方程这么的,就是不能讲是不公吧,就是内心充满了这个抱怨,就是说老先生你只是给我们指了一条路,但这条路怎么走对吧,我要带什么道具,这个带什么,带多少干粮,你都不告诉我。
然后我我在这饿得死去活来,累得死去活来,所以呢我我就借用这个课程,小小的向老先生表达我的这个作为一个学徒吧,就觉得师傅帮我不够的这种抱怨,那我第一个抱怨的就是说老先生,你有没有意识到。
其实visibility to light就是你一个点,你告诉我有个光,我能不能看见他这件事情其实并不简单,那么这个visibility to light呢,从我们大家最熟悉的方式解释是什么呢。
那就是shadow阴影对吧,就是这里面讲一句,这个我在在在这个就是课程上不敢写的话,这个里面就是政治不正确,就是以前在我们游戏行业里面,有一个非常资深的一个一个图形学的大佬。
他讲过一句话叫shadow beech,就是说阴影实际上呢是计算机图形学里面,最常用的一个效果,但是呢几乎所有的graphics engineer,他告诉你说,我在做几乎所有的游戏的时候。
shadow想做的好,那都是非常非常难的,有大量的hack,而且你解决了情况,A情况BCD可能就要出问题,所以就这么一个简单的visibility,Visibility to light。
就解决了我们死去的活来,那么但是呢这个东西这个效果可可不可以没有,那显然是不能没有的,因为你一旦没有了阴影之后,大家看到这个就这右边的这个图的话,那基本上这个空间关系会让你产生很多的错了。
因为我们很多时候是利用这种明暗的遮挡关系,人员的大脑是判断它的层次结构的对吧,那么这是我称为叫这个第一组挑战的,第一个挑战,道光的可见性,第二个挑战呢是大家不太注意到的,但实际上又是非常常见的。
就是这个光本身啊,它很复杂,为什么呢,因为我们想几个最简单的光源吧,比如说那个方向光源,比如太阳在无穷远的地方照过来的,其实它不是无穷远,那我们可以假设太阳光是平行线,这个呢还简单一点。
然后呢接下来来了一个就是点光源,点光源其实也还好,我们也有办法能处理,然后呢路灯下大家经常见的什么是一个spotlight,就是一个锥形的光源,就是大家也很常见对吧,但是呢突然给你来一个叫面光源的时候。
你会发现这件事情就变得非常的复杂了,而且面光源也就意味着说,当我一个物理我接受的光照的时候,你你同样有光什么强度变,我把那个光源自身转来转去的时候,你会发现下面的东西完全就变掉了。
那么其实光源本身它也具有一定的复杂度的,这个是很麻烦的一件事情,所以这就是我我觉得它的方程,这个就是IRRADIANCE,就是进来的这个光给我的挑战哦,忘了给大家讲个概念了,就是这个在我们图形学里面呢。
大家一定要学两个黑化,一个叫做radiance,一个叫ERENCE,先讲radius是什么,radius呢实际上是叫辐射度,或者叫你辐射出去的能量,就是它源自于黑体辐射的逻辑。
就是说比如说我一个光照到物体上,它往外反射出的能量叫radius,对不对,那好那入式的能量呢,我们以前叫做incoming radiance,但是呢我们把两个词合到一起了,叫一瑞典,就是入射的能量。
那么在球面空间上,我们的整个reading的分布,或者这个它的信息的获取,其实呢这在我看来是第一组挑战,这个挑战已经很麻烦了,那么第二次挑战是什么呢,就是老先生讲这个材质那个方程,大家看下面那个方程啊。
我是要在整个球面函数上跟对,把它的这个光和他的那个就是BRDF模型,那个四维函数在一起去积分,同学们想一想,这个是不是很头疼,非常头疼对吧,当然我可以很粗暴的用这个那个数值的解法,就是一个个采样。
我一个个解,但是大家想象一下,在实时的时候我怎么办,我做不到,对不对,那我怎么样能够快速的去算出,这个光和我的材质之间的这个卷积的,这个结果呢,这件事情其实很麻烦,非常麻烦,我后面会跟大家具体讲到。
所以这其实是我们第二条,就是说如何做,用一个graphics的话讲,就是你如何做shading对吧,我我告诉你光了,我就把整个球面的光我都告诉你了,那你把这个材质的效果做对,其实这件事情也并不简单。
那么这是我的第二个材料,就是积分怎么做,那么第三个呢也是让我个人觉得头疼,肚子疼的东西,就是说其实在一个真实的世界里面,所有的物质它本身就是光源,为什么呢,就像这张图讲的特别明显,就是你的地面上那个点。
你光直接照到我了,OK我亮了,没问题对吧,这个时候呢你打到墙上,那个墙上又会bouncing回来,又把我照了一遍,然后呢你再bouncing1遍,再别BING1遍,两遍又把我照了一遍。
就是它可以一次BANCING,二次BANCING,所以在图形学中有一个很著名的案例,大家可能已经就是如果上过101课程,202课程的同学们应该知道叫康奈尔box对吧,这是我们图形学最经典的一个一个案例。
这个里面的话,两边为什么有两个不同颜色的墙呢,他就是告诉你说,光在这里面来回的几次bounce之后,它会形成一个非常复杂的光影效果,所以其实我们在做渲染的人,经常会拿康纳box说。
This is ground truth,就是这是拿真实的算出来的结果啊,这是我一个hack的算法,跟他之间side by side进行比较,看看我们能够逼近它多少,所以其实这就意味着什么呢。
在场景中我们有无穷多个可能的光源,所以这三个挑战在一起啊,其实对我们来讲是一个很大的折磨,当然我这里面得声明一下,就是这纯属games4104课程,就是这个我我自己私人的,私家的这个总结的三点挑战。
但是可能每个人说法不一样,但是我自己做rendering做了就是很长时间之后,我自己感觉最痛苦的事情,第一个就是说你对incoming的那个ERIS,实际上我很难去得到它对吧,我如果得到了沙的问题。
我就解决了,第二个的话呢就是包括那个面光源的问题,我就解决了,第二个的话呢就是光源我全部拿到了,但是呢我去磕我的表面的材质,进行做这个CD运算,它是个积分运算,这事情又让我很头疼。
那第三个呢就是说哎因为光是可以被弹出来的,所以的话呢你光一旦开打开之后,场景里每一个物质都是我的光源,这就意味着什么呢,这就意味着说你第一次计算出来,那个每一个每一个物质的。
它的那个就是light的output,就是它的输出实际上要作为下一次的输入了,所以这里面是一个无限递归的东西,所以说问题三又会把问题一变得更麻烦,这个简直就是一个恶性循环,所以说呃在最早的时候。
我们在做这个场景光照的时候,有个很出名的算法叫retracing对吧,那么retracing呢,你们还有一个方法就是基于这个叫啊分布教师,distributed retracing嘛。
我记得那个算法就是它最大的问题就是你一颗,你一跟瑞打出去之后,他得不停的发散发散发散发散,最后那个rain就会爆炸掉,但是现在没有人真的这么去写了对吧,这么写的话呃这个就算是离线,他也扛不住。
但是呢我讲它但它确实反映了光学着,它本质是这样的,因为我经常讲一件事情,就是说上帝它的存储空间,它的算力是无限的,所以它可以用最简单的风头去解决这个问题。
但是呢到了我们这种graphics engineer的时候,我们会需要在非常有限制的这个这个计算机上,去模拟他老人家做的事情,所以这这这这个地方呢就是我个人的总结,就是卡基亚老先生。
把这个render equation扔出来之后,我们折腾了我们才30几年,实话实说,到今天的话,我们也没有完全解决他老人家汽车的问题,但是我觉得现在看到了一些希望的苗头,我后面会讲到。
就是说那接下来我要讲今天我们的正题了,就是how to do这个rendering in the engine,那这件事情的话呢,其实后面会讲到大量的公式会越来越复杂,那我在写这个课件的时候。
我就想一件事情,我说其实当年我在学图形学的时候,我在学最开始做游戏的时候,我真的需要学那么多复杂的,这个什么BRDF模型对吧,各种球面调和函数,各种什么积分对吧,这个这个信号的这个从这个各种信号的转换。
好像也没有,其实我最开始写这个游戏引擎的渲染,包括写渲染算法的时候,实际上是非常非常简单的,所以而且呢这会会帮助我们建立一个,非常清晰的,这个就是说引擎的它的渲染的基础流程是什么。
后来我想那这样咱们这个课也是这样的,因为这个课games焦虑四课程的这个课程的话呢,我希望是能让越来越多的人能听懂,所以呢我觉得咱们也不要好高骛远,先从最简单的开始,就是最最简单的渲染是怎么回事。
那首先的话非常简单嘛,这个世界我先去简化它嘛对吧,你不是光滑很复杂吗,那我就用最简单的光源形态,比如说我第一个叫主光dominant light对吧,那我给它设置一个,你要么就是一个方向光。
要么就是个点光,要么就是一个这个spotlight,一个一个一个就是那个叫柱状,那叫什么叫圆锥追光追光,感觉有的时候脑子反应不过来啊,然后你你的球面上不是有很多的这种广场,我不知道嘛。
哎我第一个东西叫做ambient light,ambient light是什么概念呢,就是说我假设把这个主光刨掉之后,环境给我的光,我可以用一个他的命,就是它的那个平均值代替。
那我是不是可以得到一个叫AMBNOL的,这个东西对吧,大家四面抛来的光,我就就是用一个数值把你带到了第三个呢,哎我这样的话,其实这个东西最牛逼的一件事情是什么呢,就是说在最早的硬件上。
完全支持了他所有的所有的光的这个这个效果,那这个时候我的我其实这个时候东西会输出来,已经很像那么回事了,诶我还不满足,我想一想这个环境中,可能我假设我的这个物体表面,它是个非常光滑的东西。
它是不是要来反射一下环境,其实这个时候呢它既不是主光,但是黄金的一条光正好跟你的就是它的那个啊,就是我们的最著名的那个,就是你的你的那个入射光的方向和,法线和那个反射光的方向正好和法线的重合了,对不对。
那我要看到一个很漂亮的反射,那我们想了一个简单的hack,我们研发了一种东西叫做什么呢,叫做环境贴图,大家有没有印象它是一个六边形的,就是大家想象一下,我一个立方体,我把它切出来是不是正好六个面。
对不对,那个六个面的话叫环境贴图,好,我根据我眼睛看的角度,我呢根据你表面的法向我反射一下,砰,在那个那个包着的那个,这个这个大的方形盒子里面找到那个点的图,诶,这个又把我的那个就是广场那一部分。
也表达清楚了,那这样的一个简单的组合的话呢,实际上大家回到这个卡基亚老先生的方程,你会发现,虽然我们用了最最简单的方法,但其实我们是符合它的方程的,本质上,我们把一个半球形的这个光照光场的分母。
把它模拟成了一个均匀的环境,光的一个入射光,再加上一个突出的dominant light,然后呢在环境过程中一些高频的东西,我用一个environment map把你表达了,这样的话呢。
我把你BRDF中特别敏感的那个spectra,那一项给你反映出来了,但这里我提前讲解一下什么叫SPL,大家想想这个是不是就是我们在学数学的时候,我给你一个通用函数,你去求它的积分,求它的解析解是很难的。
对不对,通用的方程,但是的话呢我一旦把方程参数特例化之后,诶这个方程我就能求它的解析解了,其实最早的这个我们的graphics engineer的话,没有被卡基亚老先生给忽悠,我们想你你的方程牛逼。
我觉得你都是对的,但是呢我们很土,我们写算法的人,我们写硬件的人,没办法,我们就用这种最土的方法去解决了,所以这是最早的这个光照模型,我们就用这种方法去解决了,那么好,接下来就是材质了,对不对。
材质这件事情呢就非常的神奇了,如果大家有机会去研究一下这个整个材质的,就BRTF模型发展的历史啊,那简直就是百花齐放齐放,各种理论,现在最前沿的都已经到了,这个光的波动理论。
就是讲这个光之间会互相干涉衍射了对吧,这个绝对的高大上,那个数学公司看的你绝对是这个,这个觉得,我恨不得大学回去再去多练两个专业专业,但是呢其实在材质模型中,有一派是我特别特别喜欢的一派,叫什么呢。
叫做经验派,就这帮人是这样的,就是他也不去研究你,物理空间到底的本质是什么对吧,第二个呢我也不做实验,说这个实验,我去真的拿我的模型跟你的实验去进行比较,我就根据我的观察,我觉得哦材质是有什么呢。
诶有这个漫反射像对吧,就是说你一个光打进来,我四面八方看起来好像都是一样的,漫反射像还有什么呢,还有那个诶很很亮的那个反射,就是说诶我这有的有的表面非常的光滑,油的表面呢。
它非它它这个这个反射的loop叫NOLOB,loop的话呢它相对比较缓慢一点,大家想一想,看在数学上什么方程能够让我一调,我就能够把那个反射的那个那个波,把它调的变宽变窄了。
其实最简单粗暴的就是这个power函数,就是几次幂对吧,你的一次幂,二次幂,三次幂,四次幂,那你的这个函数摔的是不是就是越来越抖,越来越越来越宽,诶,就用这个方法,所以呢,这个这里面就必须要说说。
我们的大名鼎鼎的布林风模型了,那么它其实是非常非常的简单,就是说ok defuse,他就说用cos你入射角,然后呢我就把你的光的能量那个算一下,然后我就把你反弹出去了,但是呢我和我一个反弹率。
因为有些能量可能在我的内部被吸收掉了对吧,我可能我只能反弹这部分能量的,比如说20%,30%,40%,那么呢你还有一些特别漂亮的东西,我用那个sparkler把你冰给你反射出去,让你看上去很像金属。
很像那种光滑表面的感觉,就我有我们看到的高光,那用两个简单的方法加到一起诶,我们就能形成了这样的一个材质模型,所以不吝风模型的话呃,说实话虽然它很简单,它很粗暴,但是呢我直到今天我还是觉得非常的亲切。
比如说今天假设我要去教图形学课的话,我会让我的同学们先去实践一下,bling phone这个模型,那么其实在这个BINFO模型里面啊,这也体现了一个非常简单朴素的光学原理,叫什么呢,叫光可叠加原理。
其实刚才我在讲的那个卡基亚方程的时候,也忘了说这件事,就是它那个方程,为什么你的出射光和他的这个所有的光,都能够积分起来,就是这是光学的一个基本假设,就是说我的所有的光不管你是来自于什么地方。
我最后都是可以用linear的线性的叠加在一起的,那么这个bling phone的这个模型的话又简单又好用,但是它的问题是什么呢,其实有两个比较大的问题,那第一个问题呢,这个问题在最早我们做那个。
就是说游戏渲染的时候,还好,我们其实无所谓的,但是呢如果你用不灵风模型做一些真正的,就是比如说离线渲染的时候,你就会发现点出问题,为什么呢,他的那个能量其实是不守恒的,也就是说在这边你你在那边写的时候。
那个那个SPARKER的参数,diffuse参数,包括SPER那个power,你会发现你的入射能量,最后通过它的方程反弹回来得到的出射能量,这个能量可能会比如说超过一,就是你进来能量是100份出来。
假设是101份,这个听上去好像还可以,对不对,你人也注意不到,但是如果你假设真的做了一个,就是光线追踪算法,在这个在这个里面,它会无限的进行来回反弹追踪的时候,你就会发现这个震荡就会放大。
所以刚才你看这个在左边的这个图里面的话,就是一个retracing,如果用blink phone的话,里面本来是应该一个黑枪对吧,但是呢只要有光漏进去之后,他在里面就开始无限无限的来回倒,倒了之后。
反而内部的东西反而变亮了,这个在一些离线渲染的时候,就是要要人命的事,要出事的东西,所以我们有一个说法叫做energy conservative,那个a conservation。
那么很多很多人把它翻译成叫什么呢,叫能量守恒,然后我个人是觉得这个翻译其实是有问题的,应该叫能量保守,为什么呢,因为能量是不守恒的,它的光射到我的表面的时候,肯定是有被我这个表面会吸收的。
所以你要损失能量的,但是呢你要确保是说,你从一个球形的空间射进来,所有的能量,最后我以一个球形的把你弹回去之后,我出去的能量一定要小于对吧,到等于或小于你的入射能量,所以我的能量是损失了。
我要保守一点对吧,所以他不守恒,所以我觉得翻译成能量守恒的话,这个我个人觉得还是有点误导的,反正我当年学B2DF的时候,我就学着,我就很懵,我说能量怎么守恒呢对吧,能量守恒的话,那我那个参数乱调。
他岂不是就不对了嘛对吧,所以说话这个地方的话呢,就是说它的能量就是不能够爆款,那个就是那个唉呀,我也被带偏了,就是它的能量不能保守的话,它在retracing的这种环境下就会出问题,那么第二个问题呢。
也是这个这个这个artist的深恶痛绝的问题,就说不定风非常的简单,但是呢他并跟真实的世界的东西啊,关系没有那么大,当你去表达越来越复杂的材质的时候,你会发现bling phone它表达不了那种细节。
比如说像左边那个图,那么你靠左边的这个小图的话呢,就是用bling phone做的这个模型,你无论怎么调,你就柏林风有个特点,就是你做什么看上去都很塑料对吧,就是你做那个木头,石头做着像塑料。
金属做的也像塑料,就是很很有意思,非常有意思,那么但是的话呢你看现代材质,比如说后面我们会提到的pp r材质的话,它就能非常好的把金属的非金属的对吧,塑料的这个那个这些材质表达得非常到位。
所以说我们在现代游戏里面,基本上看到的材质已经不是不灵风了,但是呢这毫无这个这个毫不影响,柏林峰在我们这个渲染上面,很经典的这样一个地位,那么最后一个呢就是讲这个visibility to light。
那么shadow呢其实很简单,就是说它实际上呢就是说指我在我眼睛看到的,这个场景里面的每一个点,它道光是不是可见它其实解决的就这一个问题,这个问题当然这个假设是那个光,要么是方向光。
要么是点光或者是spotlight,而不是更复杂的光啊,如果是更复杂的光的话呢,它实际上是有一个百分比的,那么其实在这里面啊,就是回顾图形学的早期,大概在二三十年前,其实很早很早的时候。
大家就提出了很多的shadow的算法,那么我印象特别深的叫shut volume,大家如果去看那个早期的什么quick啊,还有那个我记得好像quick那个时代用的shadow,好像就是shadow。
因为那时候硬件不支持shadow map这些东西,然后包括就是呃还有一些perspective shadow这种方法,就是就是真的是百花齐放,如果你们去search grx的文章,就是特别有意思。
就是你看大概呃15年前,20年前的那组paper的话,基本上都是各种各样的方法,但是其实呢在游戏引擎行业,我们呢还是很坚定的,我们说我们只信shadow map,所以游戏行业在过去的整整十几年的。
20年里面的话,我们基本上只用了SHMAP这么一个简单算法,但是我现在讲的是他是foundation,就SHUTMP的思想其实非常的straight forward啊,也不叫非常smart。
我觉得很聪明,他说你不就是想知道道光的这个这个,这个可见性吗,那我从光的视角渲染一张你的场景,这个渲染呢我不需要你告诉我他的什么名啊,这些东西我不需要知道,你只要告诉我它的深度对吧。
那这个深度就表示了你到光的点的那个距离,那么好,我当我去做正面的相机位置的渲染的时候,我每一个点我通过反向投影,把你投影到那个光的那个,就是那个光源的那个视角的那个projection那个地方。
然后呢我也也可以得到一个距离,如果我这个距离大于那个就是那个最近的那个,遮挡物的距离的话,那我知道我就在shadow中了,如果我等于或者小于的话,那我就不在shadow中了,这个方法其实是非常的简单。
那么具体的更更多的算法细节呢,我觉得在这个课程我就不展开了,如果同学们想了解的话,可以看看那个也令奇的那个101那个课程,他讲的更细,讲的非常的好,我我发现了令奇的课讲得特别的细。
把每个算法讲得都很清楚,所以给我这边省了很多事,就是所以呢我这边的话就跟大家讲一下shadow map,最基本的思想,那shadow map其实问题有没有,那当然有了对吧,就是首先最最简单的一个问题。
就是说其实你在渲染,从这个光源那边形成的一个shadow map的话,它的采样率我们叫sampling rate,和你从相机这边去看过去的那个世界的采样,它两个采样率是不一样的,如果大家学过信号和系统。
就知道,就是说如果采用率是不一样的话,他们就一定会产生各种各样的artifact,那这里面的话就是这个就是shining map的话,最头疼的问题就是说哎自遮挡的问题对吧,特别是那种很精细的结构。
如果sha map的精度不够的话,或者说你采样率不够,或者是他那个depth的那个精度不够的话,就会产生很多artifact,那这个课这个事情的话呢,我们游戏行业里我们都是hack大佬,我们怎么办。
最简单吧,加个boss就解决了,就是哎我就把它的容差变得更大一点,但是呢你这样会出什么问题呢,就是那个非常简单的就是人脚是浮空的问题,所以大家如果看一些早期的,做的不是特别好的游戏的话。
你会发现那个人的阴影离地总是隔个,那么比如说五公分,十公分,这就是很常见的一件事情,那么这件事情的话呢,其实在shadow里面,我给你讲一个故事,就是到直到今天吧,如果用SHADO爸妈的技术。
如果当光源特别特别靠近地平线的时候,那个时候shadow都是最难做的,为什么呢,因为那个shadow会拉的非常非常的长,但是呢你知道我们在真实的做游戏的时候,你如果去问艺术家说。
你想怎么设计一个场景的时候,艺术家很多时候都想做那种叫夕阳残血的效果,说诶同学们,我想表达一个环境对吧,血红的夕阳下,然后那个那个天空出现了五彩的云,然后呢这个建筑拖了长长的影子。
然后一个人只能看到他的剪影,当艺术家开始这样描述的时候,一般graphics engineer那时候就开始抓头了,就说我我的天呐,大哥你这是要整死我的杰作,我给大家讲一下,就是现在的游戏,游戏的话。
我忘了是什么游戏的,是最新的一个很不错的很不错的一个游戏,他那个当时是说我做了两套shadow算法,当那个那个阳光基本上还是比较,靠近天顶的时候对吧,比如说在傍晚之前。
我用了算法A当你开始逐渐逐渐接近地平线了,比如说清晨和傍晚的时候,诶,我慢慢的传C生成另外一套算法,才能解决这个问题,所以说我具体echo一下,就是那个graphics大佬说的话,就是shadow。
真的就是我们做graphics,程序员最头疼的一个问题,所以抱怨不会抱怨,但是这个是我们的革命的老伙伴,所以其实啊这样一个非常简单的solution对吧,我用一个简单光源加上AMINOL。
然后呢用environment map去hack一下,这个你的快速的反射,然后呢,我把你的这个render equation的光的那部分,给你hack掉了,然后呢我用bling phone对吧。
把你的这个这个这个卷积的问题,也变得非常的简单了,我也不算那么多东西了,我就直接给你几个几个,就是其实是POLNOL,就是这个多项式的这种计算的时间,我就能算出你的光照了。
然后呢唉我再加上一个shadow map对吧,一个简单的就是在光源空间去采个样,我就能大概骇客出来,我到光到底是不是可见,我把你的三个挑战基本上全解决了,其实啊就这么一个东西。
它最后形成的结果如果配上很好的艺术家的,出的效果并不差,这边的话是动画的画面吗,就是我个人觉得就是说你不仔细看,你觉得诶这个画面还可以,至少不影响我去享受这个剧情了。
所以这个呢我我我在写到这一趴的时候啊,突然就诗兴大发了,就是我突然想起来了,我们中国特别可爱的五九改对吧,就是远抗,因为我是一个那个这个名民科,加上一个这个伪军迷,所以我就远看五对负负重人。
就是你那个五九改,五九在最中间那个地方,但是我们见过40年对他各种魔改,其实啊这些我刚才讲的那个三件套的那个,那个方法呀,实际上即使到今天在有些特殊的场合,他还是挺管用的。
比如说在一些啊游戏超低配的时候,诶我就全部切到这个非常简单的方法去做了,包括一些如果硬件的技能不是特别好的时候,比如在移动端的时候,我其实也可以这么做,所以呢而且呢大家在理解渲染的时候。
这个呢是大家最基础的理解渲染的东西,所以这个老伙伴我的建议是大家一定要先学,先掌握它,然后呢我们在进入我们真正的高端的部分,这也是所以接下来的课程的话,就会相对来讲比较高能了,那这个东西。
这个这个东西是怎么就是是怎么产生的呢,首先得说一下,这个很著名的就是3A游戏行业对吧,我看国内很多游戏开发者天天说我们要做3A,我们做3A是3A,这个行业还是蛮有意思的。
就是我觉得3A这个行业最大的特点是什么呢,就是自己给自己找麻烦,因为我以前在美国做游戏的时候,我还是蛮能感受到那种文化,就是说每天早上醒来会问自己,就是说我怎么样能够给自己搞一些,更挑战的问题。
就好好的日子,不过就是既然你的三件套那么好使,那我为什么要给你们做的一样的对吧,我既然自称我是个3A的人对吧,我就要高人一等,那我就得这个做的跟你们就不一样,对这其实就是这样一份执着对吧。
其实本质上就是想把大家钱包里的钱,全部掏出来,那作为3A同学们,我们的这个这个行业的工程师们,就每天早上起来就想说,我一定要做的跟大家不一样,其实呢这个行业呢,我个人觉得它的一个最大的突飞猛进。
其实从15年前开始吧,就是特别是在2003年04年,学着这个SHADER,就是可编程硬件的出发,其实你会发现就是商业行业的游戏的品质,和一般的游戏差距就会拉的很大,对不对,那么这个是那个刺客信条。
15年前的画面,老师低低座的刺客信条,那可是我第一次热爱上,怎么就跳草堆了,这个草跳草堆这种事情,我居然会非常喜欢,而且觉得哇那个站在那个顶上看世界,简直是一种享受,但实际上呢我把这个图截下来之后。
我一看哎呀好像画面哎也就那么一般般了对吧,好像那个资料还有点僵,那么其实呢在这个过去的10年里面,我们还是以刺客信条为例啊,你会发现他的画面真的是越做越好,越做越好,你比如像5年前这一作起源对吧。
那你看到他就做了很多在精彩里面探秘啊,各种内部的光照,看着你就就就是说这个如梦如幻,但是呢最新的像大革命啊,像这些那个那个娃哈娜,这个就越做越好了,那今天我不展开,因为我今天这一趴讲的是什么呢。
是这个上一个时代的3A游戏做的效果,注意啊,我讲的不是最新的,最新的,我最后回去点一下,因为那个太复杂了,那我先讲一下,就是呃大家印象中的,比如说五到10年前这个行业,这10年里面我们所研发的这个技术。
那么这个还是按刚才那个思路来讲,就是说首先我们要解决的问题是什么呢,还是光照的问题好,这光照问题很难对吧,就是这个球面的光怎么办,这个其实我我我,我把它简化成一个暧昧的一个常数,这个实在是太不礼貌了。
这个卡基亚老先生知道了肯定会很生气的,对不对,虽然他扣不了我的工资,那我们就想到了一个办法,说唉算了,我预计算好不好,就是我把这些,我反正假设场景中90%的东西,它都是不动的,假设太阳的角度。
我每个关卡我就锁死了对吧,那我是不是可以通过预计计算,这就是计算机那个图形学里,或者计算机引擎里面,最常用的一个思路叫什么呢,我相信大家以前学过那个数据结构的,知道有个说法叫什么叫空间换时间对吧。
大家记记不记得,其实这个就是一个非常典型的,空间换时间的思路,就是我用PRECOMPUTER,我来去看看能不能把这个这个这里面哦,不好意思,有一个词儿我还突然冒出来叫global nination。
这个词,听上去非常的高大上,全局光照对吧,我相信现在很多同学买游戏的时候都会问,这个游戏支不支持全局光照啊,对不对,全局光照on and off会有什么效果呀,它本质上就是说哎我的这个光啊。
就是比如说来自四面八方反射的光对吧,就是如果想能分解一点,就是直接光照和间接光照叫inja light都有的,这种光照叫全局光照,那我们呢把这个所有的这种光的效果,全部预计算出来,那怎么办。
就是那首先的话呢我们要解释一下,就是说为什么全局光照这件事情这么重要,那这里面就是左边和右边这个图,就是在游戏中啊,我们有大量的场景,他其实比如说你坐在一个房间里面对吧,那如果比如白天家里是不开灯的。
对不对,那你这个如果只算直接光照的话,你看到的是什么呢,你看到的就是这个像我这个图,这个左边的这个样子对吧,那好那我们怎么high,我可以high啊,我可以加个N倍的,但是MING的加上去。
它的一个特点是什么呢,就是你家里面所有东西都统一变量了,看上去非常具有平面感,如果大家回想一下,你们以前玩的这种20年前的游戏的话,15年前的游戏吧,你进到室内的时候,特别是一些网游。
你会发现感觉这个里面的房间特别的平面,就是你几乎感受不到什么光照,这个原因呢,其实不是因为那个就是程序员不努力,是因为他真的没有做全局光照,因为你要做全局光照的话,你才能模拟出来这种诶光照到地上对吧。
地上反弹回来,又把房间的天花板和墙应亮了,这样你走的人的话,他才有种光的感觉,所以全局光照啊,其实对于这种真实感的刻画,实际上是非常非常重要的一件事情,那这个时候我们的挑战是什么呢。
就是这个全职光照拿到之后啊,它实际上是一个在球面空间的一个采样对吧,你可以把一个球像地图一样展开这个map,那么但是我如果存了这种东西的话,它的数据量会不会非常的大对吧,如果我整个场景只踩一个没问题。
我服了对吧,那我也能存好,就算你能把整个场景的这个光照全部踩下来,你这个时候你我给你一个材质,你说我这一个DE图片和整个这个材质上的,球面光照怎么去算,他的这个这个就是积分呢,啊这这又是要命的一个事情。
对不对,那你当然了,你可以用最粗暴的,比如蒙特卡罗的方法,就是我就是在这个球上撒无数个采样点,比如撒100个好,我每一个每一个方向都给你算一下,算一下,我再积分一下,但是大家想想看,我们在做绘制的时候。
每一个这个屏幕上你看到像素,我要去做它的shading的时候,我都要跟这个这个这个球状的,这个整个光照函数的积分一下啊,都都都做一下采样,然后再做一个累加对吧,其实这个卷积运算了。
那是不是这个要疯掉了对吧,那这个所以的话呢我们需要去想一种方法,能让这个积分非常快速的能够进行,这其实就是摆在我面前的挑战,这个时候呢我就要哎对这个地方开始高能了,但但这个地方。
如果大家上过那个101202的课程,这个地方我们我觉得我们俩课程真的要联动了,我这两天一直在跟林奇在聊,我说你简直救了我的命,我发现你很多东西你的课程已经讲的非常好了,我直接就框包括这张图。
这个图我是直接从他的那个啊课程里面,直接抠出来了,我觉得他讲的特别好,因为本质上啊回到上野啊,就是不好意思,回到上一,回到上一页那个这个球面上,它是一个无穷为的,这个这个这个信号它是个连续信号对吧。
你你只能在它进行采样表达,它实际上是无限的向量,那这时候你碰到这种信号的时候,你怎么办,那我不得不说我们的傅里叶的这个老先生,这是啊1830年去世的一个数学家,我现在真的想不明白,就是他在那个时代。
为什么搞了这么一套特别牛逼的傅里叶变换,这样能够把各种循环的这个信号,它能够把它分解成几个不同的这种频率的信号,的一个累加,我真的想不出这个应用,但是我我我今天还特别饶有兴致地,做了一件很无聊的事情。
就是我查了一下麦克斯韦,老先生是哪一年出生的,我发现是麦克斯韦是啊,他是1930年死的,麦克斯韦是1931年出生的,也就是说他死后一年后,麦克斯韦才出生了对吧,因为你到无线电的时候。
比如说我我无线电的信号来的时候,我是调频啊,截屏啊,我需要这套技术,但是我不知道数学家为什么那么牛逼,有先见之明,把这套数学工具就给出来了,但是呢这个分裂变换听上去非常的高大上啊。
但是其实它非常的非常的有用,就是说比如说我在空间上的一个信号,这张图也是从另起的这个课件上透出来的,我觉得特别好使,就是你给我一张照片,我可以把它分析成一个,傅里叶变换的一个频率谱。
就是把这个从空间域变成频域,这个时候呢,如果我在频域中只截取前面的一小段,实际上我就完成了对你的信号的一个,非常粗糙的表达,但这个表达虽然会粗糙,但是呢基本上能让我看出来这是什么东西。
比如像这里面他只取了九项,你就能看到这个小女孩的大致的样子,这件事情是不是很神奇,对不对,本来我要存一个完整的照片,到这边我就诶就可以拿到这个小姑娘的照片,这个就是怎么说呢,在我知道福利变换之前的话。
如果有人让我写这个效果,我只能用最简单的就是加权平均,加权平均吧,土的要死诶,但是你一旦上到了这个傅里叶变换之后,你发现他的一切就有数学的这个解释了,所以正是因为这个方式它其实有很多好处,第一个好处呢。
就是你本来像这个小女神的照片对吧,他是呃差不多,我看了一下大概200×200的像素对吧,1万45万的数据,但是呢他可能用九个参数就能够大概表达出来,这个小姑娘长长什么样子对吧。
但是我不知道这个数据是不是真的久,也许要更多一点,但反正anyway你确实是可以压缩,高速高效的压缩这个数据的,第二个好处是什么呢,就是当你啊对这个图像和另外一个图像,做任何的叫积分运算,或者讲的。
其实大家如果学深度深度学习的话,有一个词用的特别多,也是我这边的这个标题叫做卷积,就是对它进行这种卷积运算的时候,你会发现你不需要那么傻傻的,对这几万个数据点进行一次的,这个叫乘法加累加运算。
那会算是你的诶,你只要把它投入到频域空间的那几个参数,进行一次卷积就可以就可以得到它的结果,这是一个非常厉害的牛逼的一个数学性质,所以当大家把这个性质提出来之后,接下来就来了一个大名鼎鼎的。
这个球面调和函数叫sofa harmonix,这个SUVHARMONIX是真的是非常了不起,就是我当年学到这一趴的时候,我真的是惊为天人,你知道吗,而且呃我特别崇拜,就特别佩服,就是把这个数学工具。
引到我们graphics领域里来的这个人,这个老哥呢如果我没记错啊,叫peter pex lo,叫皮皮斯隆,我们叫他皮斯隆,这个老哥我是特别讨厌跟他一起开会的,为什么呢,他是个北欧人。
身高大概有1米9几,快接近2米了,每次我跟他开会的时候,我就这样看着他就特别有压迫感,你知道吗,就是所以我跟大家讲,就是你跟老外开会的时候,最好自己个子高一点,如果你的个子像我这样只是在中国叫中等的话。
你很多时候尽量远离北欧的那些科学家,因为他的专业上给你强不强不重要,首先从气势上,他就把你碾压到了,那么皮特帕克斯龙同志呢,他真的是非常了不起,他那时候还在微软,在direct team,他就想到说诶。
他当时就提出来那个叫PRT对吧,然后呢他就是pre computer,什么那个什么什么reader transfer吧,那个全称叫什么来着,我已经有点忘了,然后呢他就说他想到了这个基函数。
这个方harmonics啊,它其实它是一组sin和sin的一个函数集,你听上去非常的复杂,但其实啊它的数学性质是非常非常简单的,那么你看到了,比如说一阶的这个函数,它就是一个加权平均嘛。
在球面上所有的型号加权平均二阶函数呢,你其实可以想象成在球面上的每一个方向,那么大家想想啊,如果是个球坐标记坐标,你有CTF两个角度对吧,决定了一个方向,那么如果你在笛卡尔坐标系里面,你去表达它的时候。
是不是就变成了一个归一化的一个向量,XYZ啊,虽然它有三个值,但是就是X平方加Y平方,加Z平方一定要等于一,对不对,所以它其实只有两个自由度的,那么实际上它的第一阶的那个三个基函数呢。
就是Y值ZHX值简不简单对吧,当你在X轴的正面正面的时候,那个值就是X对吧,在X轴的负的时候就是负负负负负的这个值,那么ZY也是一样的,那么即使到了第二节的时候,他其实也不复杂。
你会发现就是说他每一次上一节,他的多项式就多上了一一阶而已,但是呢它的外形看上去就特别的魔幻,这个图的话大家看一下,就是呃绿色表示是正直,红色表示负值,你发现没有,就是说实际上它在这个空间上。
是不是就是在一阶的时候,像两头鼓出去的一个泡泡,这个形状其实非常的漂亮,然后呢到二阶的时候就变得更加精彩了,三阶四阶越来越好看了,这里面很神奇啊,就是他的这些所有的这些无限维的这些函数啊。
它们都是什么的,都是正交的,正交的什么意思,就是说你把它们卷积在一起,它的值永远是零,这个非常有意思,那么这个东西呢实际上真的是,我觉得我我自己一直觉得,上这个这个世界的技术原理。
到底是物理的还是数学的,我觉得大概率可能是数学的吧,如果氢原子里面的那个电子轨道,跟这个东西几乎是一模一样,我这边还今天还特别的这个这个,这个闲得蛋疼的,就是去找了我们同学说。
哎同学们查一下氢原子的电子轨,我记得以前我在学习for harmonix的时候,好像老师跟我讲过这个事儿,我们又查了一遍,发现诶好像是对的,真的是这样子的,所以说这个harmonic函数也是非常了不起。
就是在这个讲的数学上更更深一点,更有意思的一个属性,就是说它的二阶导永远是零,什么意思呢,就表示它这个函数永远是光滑的,它的变化永远是非常的流畅和光滑,你看多么的和谐,就这么一个简单的函数。
它就解决了我们所有的问题,那这样的话,当我来到了一个球面的光照信号的时候,你就可以用非常简单的一个POLNOL的,就是这个一个多项式的一个,其实连多项式的就是一阶多项式,一个乘法加加法。
你就可以把这个信号大致地表达出来,那这里面的话,你看到下面有几个非常复杂的信号吗,实际上你用几阶的这个就是SAFARMONIX,就能近似的表达表达出来,当然了,在我们的游戏中的话。
我们一般不会用的那么复杂,我们一般用到像最早我记得在做halo的时候,我们用到了好像是二阶还是三阶吧,但是的话其实现在很多时候,大家只用到一阶就完事了,为什么呢,因为我只需要表达低频。
这里面给大家举个例子啊,比如说当我有了这样的一个工具的时候,我在这个场景里面,我在任何一个点,我这时候看到的东西是什么呢,诶是一个是一个light probe对吧。
就是或者叫erence prom进来的光,那我把这个球呢,假设按地图一样的展开成,一个一个一个一个地图,就像这边屏幕的右下角,出现在那个小长条形方块,我用SAFHONEX对它进行压缩。
这里面呢我们只取它的这个,就是说呃S0和S1总共只有四个参数,那大家看看我重建出来的这个图,是不是虽然看上去非常的糊,但是呢它基本上能告诉听说光从哪边来对吧,哪个比较黑,哪边比较亮,这件。
而且它的整个过整个数据是非常连续的,而且如果我要去问,在任何一个方向的光强到底是多少的话,只要用一次线性的就是vector运算就完成了,这张图呢,我是选自于2018年的戴斯的一个报告。
他讲行双引擎里面他用的这个技术,那么其实他就说这个其实够了,为什么呢,如果我用它去做一些就是表达环境光,因为环境光大家会发现啊,如果我把主光给抠掉之后啊,环境光很多时候它就是低频的。
所以这样压缩它的效果其实基本够用了,而且这样的话呢,它就有一个非常有意思的属性了,就是我去表达一个点上的,它整个一个球状的光的话,你会发现它只需要14个12个参数,那为什么是12个参数呢。
刚才我们讲了四个参数嘛对吧,那为什么这个时候变成12个呢,其实因为它的颜色是有颜色的,就是说我要去压缩一下诶,蓝色的在这个层面上的分布,我要说要绿色对吧,红色RGB3个颜色,所以呢就是4×32个参数。
这里面的话呢就要讲个细节,这个细节我觉得觉得我觉得他讲的非常的好,这里面我也分享给同学们分享一下,就是说它虽然有四个参数啊,但这四个参数权重是不一样的,比如说你的一阶L0。
就是说那个那个均匀的球的第一个第零阶函数,它不是相当于对我整个环境的广场,做了一次加权平均吗,那这个时候呢因为我们现代游戏基本上是HDR的,所以呢它对它的压缩采取了HDR的压缩方法。
它这里面选择了就是那个BC6H,这个H可能就代表这个high resolution的这样,一个东西对它,但是它只是一个阿尔法channel的去压缩,但是的话呢他对于他的那个剩下的两个接的话。
他用的都是这个LDR的压缩方法,那实际上就算他用高精度的,比如说这个b c seven去压缩它的话,那实际上它的一个球面上的,整个一个光照的表达,他只用了多少呢,只用了大概24个beat。
这个事情其实非常的了不起啊啊啊啊,这个啊32个beat,这32beat是什么概念呢,就是我们在游戏里面存一个颜色,假设只有这个一就是一个BT,表示一个测的就是256个色阶吧,都不是HDR颜色。
我存一个RGBA就是32个那个by a beat,所以这意味着什么,就是我用了一个存在阿尔法的颜色的空间,就能存一个在每个点上的一个光照,所以这件事情是非常了不起的,他那么他带过来第二个很大的好处呢。
这里面我今天不展开了,就是说我因为把这个光用SAFARMAX去表达,那我去算diffuse,甚至我在算SPEARKER的时候呃,其实在那个death的文章中,他只算了diffuse。
实际上在最早halo3的这个工作中的话呢,我们把SPARKER也做,因为hero3当时对这个SAFARMA存在接触比较高,好像我记得存到了二阶或者三阶了,那么实际上你都可以把它转换成。
两个向量之间的点击或者是卷积就完事儿了,非常的简单,大家有如果有兴趣的话,可以去推导一下这个,这个反正就是如果大家没有兴趣没关系,直接在网上找公司,你就按这个去写,一般来讲不会错。
但是注意有些有些有些parameter要归化对吧,经常你有时候忘了除一个派,这个就这个整个数值就完全不一样了,所以呢但是呢他的思想他就告诉你说,我在球面上两个函数的卷积可以简化成。
你把两个函数分别投影到,SURFHONICS的这个机上去,你投影出来的参数,这两个参数之间的卷积就等于他们的结果,这个事情其实非常的了不起。
所以有了这么神奇的这个数学工具之后,我们就可以做一件非常丧心病狂的事情了,就是大名鼎鼎的LIGHTMAP,那这里面我要跟大家澄清概念,就light map这个词啊,不叫光照贴图吗。
实际上不是为了做全局光照发明出来最早light map,如果我没记错的话,应该是在还是我们那个大神吧,KMARK在做最早的quick时代,好像他那个shadow算不过来。
他好像就已经用了light map,预先的把这个这个shadow就算好了,但是呢后来随着shadow的技术,比如说shadow map这些技术的发展,大家就觉得哇塞真是太土了,我们就不这么干了。
但是呢等我突然发现,我们需要算全局光照的时候,诶,这个老祖宗的利器又被寄出来了,我们发现我们应该用light map的思想,就是把整个场景的这个光照,给烘培到一张图上去,因为我有我有很了不起的数学工具。
叫SAFARMONIX嘛,所以说你会发现,就是基于全局光照的LUMAP技术啊,是在peter park sloan,好像是提出了PPT之后才爆发出来了,如果我没记错的话。
好像halo是第一家做这个东西的人,那么当然这个这个有待查实啊,因为我现在没有那么多的时间,在做其他的research工作,但是呢基本上是这个思想,允许我们去做这样一件事情了,那么这边的话。
你看的就是那烘烘烘烘焙出来的贴图,那个图我们一般叫什么呢,叫做atlas,atlas呢,翻译成中文叫做航海图或者地图,就是你就是把很多的几何拍到一张图上去,我们叫做atlas,那怎么个拍法呢。
首先呢你要对这个世界进行几何的简化,就是你不能用那个非常fine的那个geometry,就非常清晰的结合geometry,因为什么呢,因为这里面有一个有一部,有一部课程叫PRIMARIZATION。
就是说把三维空间的复杂的几何,把它投影到二维的空间,如果你是一个比如说一个方块或者是一个球,这个promotion呢就是参数化呢是比较简单的,但是大家想象一个任意的形状对吧,无数个三角形。
它的参数化是比较复杂的,所以呢我们会对这个几何进行简化,然后呢我们要进行这个在参数空间进行分配,这里面有个小小的细节,就是我们尽可能希望,在同样的这个面积或者体积里面。
我分给你的这个texture resolution,就是那个那个那个就是texture的那个精度,基本是类似的,这东西听上去很抽象,但是我觉得这张图讲的特别好,就是如果我把每一个text标成不同的颜色。
但就是大家现在看到的格子吗,你发现他反向投影回这个世界上,你看诶好像每个格子大小都比较均匀,这件事情啊是一个LIGHTMAP很重要的一个需求,但是呢真正大家在数学上写一写,还不是那么简单的。
我如果没记错的话,direct大概在呃十几年前专门开发了一个API,就帮助你做这个参数化展开的那个这件事情,那个东西的话其实啊很重要非常重要,但是我们当时一直在用,一边用一边抱怨,他的好像有很多小问题。
不知道现在修的怎么样了,然后呢这个时候我其实开始给他做lighting了,这个lighting呢,实际上这个讲解来就比较丧心病狂了,就是这个lighting。
实际上我们有一个巨大无比的叫light farm,这个farm呢是有很多台很快的电脑,这个做成的一个集群,然后呢这个当美术做完了场景之后,把光源设置好,参数设置好点,一个叫烘培。
我们叫做那个叫我记得以前叫baking点一下好,这个时候美术可以干什么事情呢,美术就可以出去买一杯星巴克了,然后呢可以坐在阳台上跟同学们一边抽着烟,一边喝着星巴克,一般来讲会半个小时到一个小时左右。
所以我记得那个时候,当我们用LIGHTMAP这个技术的时候,呃,我实际上就很痛恨这个技术,我觉得我的天呐,这个会让我们3A游戏开发的效率急剧下降,所以当我后来自己做引擎的时候。
我就坚决不肯上light ma,宁死不从对吧,但实际上的话那效果上肯定会打折扣的,因为light烘出来的效果确实是很好看的,那么它可以烘出非常漂亮的这种这种来,这个就是全局光照的效果。
然后呢你再把它附上这种就是直接光照在一起,你会发现这两张图的比较,就是这个是啊只有LIGHTMAP的图,你会发现很多光在里面bouncing的效果都会有了,而且你能看到就是两个临近的很近的建筑物之。
间的物体之间的这种软阴影,但是呢你这个时候再加上domino lighting,就是主光源的时候,整个这个光这个环境就非常的饱满,然后你再配合上材质,你会发现这个感觉就非常的真实,如果这个关卡的话。
就这个这个场景的话,如果没有LIGHTMAP的那个就是那个补充那个GI的,就是全局光的东西的话,它看上去会非常的难看,为什么呢,因为你看你会发现它的光只能照进场景的,很小的一块。
而且呢你就算用安静的去补的话,其实那些不能被光照到的结构,它的名啊,它的几何关系你是看不出来的,所以说这个GI就是global emission的感觉,对三游戏来讲的话是非常重要的一个一个属性。
那么所以LIGHTMAP的话呢,这个技术的话呢,我这里面不会展开特别的细啊,但是希望同学们就是分享一下我自己的理解,它的好处是什么呢,就是说你别看它烘培速度特别慢,但是呢它在实时的时候。
RUA的时候其实效率非常的高,因为它成本非常非常的低,那么第二个的话呢,就是说它因为它是离线baking的嘛,他把整个空间这个分分解之低下之后,它可以产生很多很细节的,很subtle的这种效果。
这种效果的话说实话艺术家是非常喜欢的对吧,就像这里面那个飞船,它在地上那种软软的那种就是明暗关系,会让你一下子觉得这个东西跃然于纸上的感觉,那么它的缺点呢,刚才也讲了,第一个就是非常长的这个预计算时间。
包括今天我在准备这个课程的时候,我没有办法去给大家一个完整的来看我的图,为什么呢,因为我们的引擎没有,然后在网上搜也没搜到,因为我当时我做引擎的时候,我就特别不想做这个玩意儿。
我觉得这个东西实在是太麻烦了对吧,那么你要构建一个lion f,然后呢,第二个呢,就是说它只能处理静态的物体和静态的光,大家想想是不是就是当你的这个物体一旦变了,或者光源一旦动了。
你以前烘焙的东西就全部完蛋了,当然有些同学也很丧心病狂的,想做那种可以real time更新的light map,但是在工业界呢我见到的好像比较少,就比较难,其实确实很难。
但是呢动态物体其实是有办法hack的,就是以前比如说在做一些简单的游戏的时候,我们可以说哎,我从这个物体从周围去sampling一个点赞的LIGHTMAP,我就能获得猜到黄金光长什么样子。
这时候我给他一个光照,那么但是呢这个效果其实有很多的问题呢,就比如说以前最经典的一个bug是什么,就是地上LIGHTMAP投入了一个shadow,你这个人走上去的时候,这个人那么大。
一个小小的shadow,把人突然一下子变黑了,你人在走开的时候,哎这个人又变亮了对吧,这个效果就非常的这个非常的塑料,非常有问题,那么这其实也是LIGHTMAP一个很大的一个挑战。
那么第三个挑战呢就是我想了,既然咱们是一个叫空间换时间的策略嘛,那在run time的时候,LIGHTMAP本身占用个几百啊,几十兆到几百兆的存储空间是很常见,一般来讲是几十兆到100兆左右吧。
这取决于你的场景有多大,但是呢就场景大了之后,它导致的问题还烘焙时间也足够长,这个方法呢就是实际上我在后面会讲的,就是现代游戏中啊,我个人认为啊,light map的方法可能会逐渐被淘汰掉了。
但是呢为什么我是特别喜欢,特别希望跟大家去讲一下,这个light map的这个方法呢,因为他的有两个思想,其实我个人觉得是非常了不起的,第一个思想呢就是说啊空间换时间对吧。
我用存储空间把大量的一句算放在这,第二个思想呢叫我对整个游戏的场景,把它参数化到一个比如说二维的texture上去对吧,其实我也可以把它参数化成一个,三维的WORKO上去,当我把这个空间啊。
就是本来大家理解一下游戏的环境,它是非常复杂的,各种各样的几何面片东西,但是我一旦把它变成一个非常容易管理,非常容易表达的这样的一个2D的texture,或者是3D的一个涡轮的话。
其实我很多的计算就可以去做了,所以这个思想的话呢,我希望同学们能够get到,所以说我们今天这个104的课程,我一般会跟大家讲,就说我不会特别纠结于每个算法的,具体的时间的细节。
但是呢我是特别希望和同学们分享一下,就是说当你遇到一个,因为今天我讲的所有的算法,可能并不能解决你未来真的在做引擎,真的在做游戏,你所遇到的困难,但是你一旦掌握了这种方法之后。
其实你可以发明你自己的新的算法,所以这就是like map,OK好,那接下来的话呢,就是其实也是非常straightforward的一个想法了,那你既然把空间上去。
把这个把这么复杂的这种几何给我拍平了对吧,太麻烦了,对不对,大家如果有人写过那个就是参数化的算法的话,你就知道那绝对是恶心的不得了,写写不好就一堆bug,我来个更简单粗暴的。
我在空间上撒一堆的这个采样点对吧,我们叫什么叫light prop,你不是说每一个点上的那个光照,就是一个一个一个一个半球嘛对吧,那就是个泡芙嘛,好我就放一堆light pop对吧。
你看这张图中就是这个图,不一定大家能看得清楚啊,你可以看到那个字,如果仔细看你会发现那个这是一个这是FA,就是那个啊就是微软的当家花旦的赛车游戏,这是当年我最爱玩的一个赛车游戏之一吧。
我我这个这个我还是蛮喜欢这个游戏的,然后呢是force最新的一座horizon,他就用了这个light prop的这个技术,他就讲解说,你看我在平面。
我在这个赛道上撒了无数的这个light probe对吧,然后呢我对于每个prop诶,我采样它的整个广场,当这个你们任何一个物体或者人,在你们去移动的时候,诶。
我就去找我周边的这些那个light probe,对它进行一个差值,就算出我的光照,它旁边那个小动画,大家自己看那个小球的颜色一直在变,为什么呢,因为它当它在动的时候,它的邻居一直在变。
这里面的话就是一个很简单的空间体系化的,这么一个算法,就是我要把这些light problem变成一个个的点,然后呢我连出很多的叫四面体对吧,Trohr,然后呢我就可以对它进行插值了。
这个算法其实啊如果大家稍微学一学,难度并不大,那么我就可以采样,其实light pp呢有一个很有意思的问题,就是哪个老哥去把这些点摆上去,在早期的live power。
比如早期我们做一些规模比较小的游戏,的时候呢,我们喊粗暴说对吧,我记得以前我我我我我跟ARTI思想说,你不是想要pp吗,来我给你做个工具,你自己点吧,对artist说好,我要这个效果,我也我愿意点对吧。
但是呢其实到后面他就发现这事他不想干,为什么呢,因为level artist他经常会改这个关卡的设置对吧,我今天放了这个点,我沿着这个通道很精彩,因为你不能乱点,你尽量沿着这个玩家走的通道去放嘛。
对不对,那好那每一次你关卡一旦变了之后,你得再重新改,而且这个地方经常会改错,而且会有无数的bug圆缺,所以呢我看了一下,就现代的游戏呢,很多时候它是有自动化生成的方法了,那简单来讲的话。
就是我对空间的几何进行,我首先均匀的产生采样点,然后呢根据玩家的可大大区域,包括建筑物的这个几何往外往外做一个延拓,我然后呢相对均匀的去把这个点撒出去,这个算法其实并不难,但是呢就是说这个呢。
我认为说如果今天同学们做light pro算法的时候,假设是真的工业级应用的,我会建议就是大家想办法,就是写一个这个这个light pop自动生成的算法,因为这样的话你会发现。
当你进入到真正的就是这个生产流程的时候,艺术家会爱死你,那如果你让他手动点的话哦,他肯定会恨很恨你的,你要小心点,嗯所以这是垃圾pop怎么去生成,那你这里面再讲另外一个很有意思的概念。
就是说其实light pp呢我们去采样的时候呢,一般会踩的比较密,但是呢我们可能会用一些压缩算法,比如说把精度压的非常的低,因为我主要用它做光照模,讲的就是光照,如果做diffuse的话。
其实可以非常的低频,就这个地方如果我有算法和max压缩,也没什么太大问题,但是呢我们在游戏里面有很多非常光亮,不灵不灵的东西,对不对,那你这个人走在这个环境里面,他身上反射的东西是不是要经常会变呢。
所以呢我们会有的时候会专门做一种prop,叫做reflection probe,就是说反射pro它的特点是什么呢,首先呢我做的不会特别多,但是呢它做的它采样的精度很高,为什么呢。
因为那个反射它对高频是非常敏感的,所以我希望能看到大概清楚周围的环境,这个里面的话呢,一般来讲它会分开的,和这个就是啊,就是那个光照的那个problem去采样,它的密度会低,但是呢它的精度会高。
所以基本上你把这两个东西放在一起的话,你就能够实现一个诶还挺不错的一个GI的效果,它的好处是什么呢,就是第一个RUA其实也是非常快的对吧,然后呢它能处理就是静态物体和动态物体。
而且呢它有个很好的优势是什么呢,就是说你其实啊是可以在RUNTIME的时候,可以更新它的,就是你这个场景如果发生了一些变化,包括人物发生的位置发生的变化。
实际上现在计算机上light prop是可以软弹更新的,这个里面呢有一个细节,就是说啊我要去做light pop怎么做呢,大家想想看怎么做,我是不知道是不是在这边放个相机,然后呢朝上看看,朝左看看。
朝右看看,把周围拍六张照片,诶我把它拼成一个图,然后这个图拿到之后呢,我再用我快速无比的这个GPU的SHADER,对它进行各种各样的处理,那个速度其实也非常快。
那么一般来讲呢我们去做light pop更新呢,它的特点是说我们不会每一帧都去更新,这个prop,就是说我们基本上隔几帧,或者说我会判断你的位置,是不是发生了巨大的变化呀,场景是发生变化了。
而且我一旦发生变化的时候,我也不会马上就更新,我可能会找一张比较空的时候去更新,所以这个呢也就是说在现代引擎架构的时候,我们会有一个概念,就是说有一些update我们会differ就不会马上做。
否则的话,你会导致你的帧率在那一下子突然就不稳定了,所以的话呢就是说呃就是light probe的一个一个,很很有意思的一个特点,但是呢它的缺点呢就是他比不上light map。
因为它能给你里面动的物体,非常好的光照感对吧,环境也有这种感觉,但是呢他没有办法实现,就是像light pap那种,非常nicely的这种soft shadow的感觉啊,这个物体之间那种交叠的感觉。
这个感觉真的做不到,包括有一些非常漂亮的那种color的,leading的效果呢,他做的也不是特别的好,这就是因为你的材料太稀疏了嘛,对不对,人家light map对吧,在一个地图上。
他要采大概几百万个点,你light problem你再狠几万个也就不得了了,所以你是人家几1%的采样率,你肯定达不到人家这个效果,所以这个世界是很公平的,所以你用这个方法的话。
就是说light map加light prop方法,基本上在过去的就业就是说十几年的话,你能够hack出来一个还挺像那个样子的,一个光照的效果,那么好,光的问题我们用这种方法就基本上解决了。
接下来我们要解决第二个问题就是材质了,这里面呢就要引入我们大名鼎鼎的这个,基于物理的材质系统来打physics basement based material,pp r对吧。
其实应该是physical rendering pdr,那个p r rendering pp r material对吧,他这里面其实概念挺多的。
比如说p p r lighting pp r这个camera p p r这个material,但是呢这个都是吓唬人的,我们今天的话呢,这个既然这个数学上或者说行业,你们大家喜欢吓唬人。
那我今天就决定这个也也失从一下来,先给大家看一个非常酷的东西,就非常吓唬人的东西,叫微平面理论,这个其实呢大家如果学习过图形学理论课的,同学们都知道我对吧,听上去非常的高大上,但实际上呢是蛮简单的。
就是在在这个里面的话呢,我觉得他有一点讲的特别好,就是他他用一套假设解释了就是各种光学现象,他认为就是说一个表面它就是无数的反射,那么如果你假设是一个全是金属表面吧,你看起来粗糙。
看起来这个就是说那个他的那个就是光滑,实际上跟他表面法向的聚集度有关,如果他所有的这个小表面的法向都集中在一起,那你看上去就非常的shining对吧,反光很好,如果全是一个方向的话,那就是镜子了。
对不对,但如果它分散的比较开,你看上去就比较糊,这个逻辑其实是非常非常简单的一个逻辑,那么这里面的话呢,就引入了一个非常著名的这样的一个一个模型,就是这个这个模型呢,其实现在大家用的最多的是GGX模型。
说实话就是我在这个行业待了这么久,到现在为止,我还没搞明白为什么这个模型叫GGX对吧,但是大家到后来发现我们都在用GGS这个模型,这个模型大概是2007年提出来的吧,那个包括我查了原文。
他这个文章中突然出现了,叫GGX这三个字的时候,没有任何解释,然后我就一脸懵逼,我说啊怎么回事,那其实呢,它这里面有一个很很有意思的一个解释,这里面的话呢其实讲解的很高大上,但实际上很简单。
就是说其实一个光啊打到物体表面,它无非就发生两种事情,第一种事情呢就是我把你的光弹回去了对吧,弹回去呢我能弹多少,取决于我表面的这个法向的这个分母,就是roughness,它的速度。
如果它的法向特别散乱,那我们彼此之间的话呢,就会这个这个这个就是发散,就是就是说你可以看到高光很发散,但是呢还有些光它会设计到物体里面,好这里面高能的地方来了,就其实也也不用那么复杂。
就是如果是金属对吧,金属的电子可以捕获这些光子,那那些电子呢就把这些光子给笑纳了,对不对,但是呢如果是非金属诶电子,它就没有能力捕获这些这个光子,这个光子就在里面来来回弹几下。
然后呢以一个随机的方向射出去了,就相当于一度一束光射到物体表面,在里面发生了几次这个折射之后,啪就全散出去了,这个东西是什么呢,就是diffuse对吧,非常简单,所以呢PB2的材质。
它的模型实际上就是两趴,一趴呢就是number version的漫反射的这个部分,这个部分其实非常的简单,就是如果你把球面上所有的这个漫反射的部分,积分子起来的话,就是一个派分之C。
那个C就取决于你的这个多少部分的能量,进来对吧,这个大家有兴趣可以记一下,其实非常的简单,这个这里面当然需要一点点的这个,微积分的那个支持啊,但是呢还有另外一个很著名的part,就是哎反射的一部分。
它引入了一个著名的叫cook torres模型,那库库托斯模型呢,它的数学公式看上去就很漂亮了,大家可以看到一个很著名的三项叫DF7对吧,这个DFG呢听上去很高端对吧,看上去像什么黑社会的这个标识一样。
但其实它每一个字母呢是代表了一种光学现象,它其实也很简单,那这个DFG是什么呢,我先跟大家讲一下D吧,D就是大名鼎鼎的这个normal distribution function,就就是法向分布的方程。
它本质上讲的就是这个normal,分布的是更加的发散,更加的聚集,然后呢cook托老先生呢,他就推推推推推推推了一大堆诶,他最后给出了这样的一个方程组,这个方程就现在大家呢normal di图片的方程。
大家都会习惯用什么呢,用的这个GX这个模型,GGX4种模型呢,其实数学上那个公式大家可以看一下,其实看上去很复杂,其实就是一堆的这种啊,多项式的加减乘除的运算,其实你真的去SHADER去写。
下面我们给了一段尾代码,大家看其实并不复杂,而且这个事情非常有意思的一个事情是吧,就是我它引入了一个RA那个值就会叫阿尔法,阿尔法是什么呢,就是roughness对吧,你们可以尝试一下。
把阿尔法设成零时长,0。5,时长一,你算一算那个出来的值是多少,其实呢你不用特别理解他的这个公式是什么,其实练习的课程能讲的会讲的更清楚一点,我觉得我在我这个课程的话,因为我更多的教大家怎么做引擎嘛。
所以说大家大概有感觉就可以了,但是呢做游戏引擎的人,我们需要知道什么东西呢,啊这个是当时那个GG那个材料原文中,我个人很喜欢的一张图,他就讲啊那个缝模型诶,高光你看到的是这样的一个曲线图对吧。
那么GJ呢是另外一张选图,大家如果在视频上能看得清楚的话,那个绿色的那条线是GG的,这个NDF的那个方程的图,大家发现它的特点是什么,如果用一句简单的话讲,就是他的高频的就突出的地方。
大家发现它是不是更加陡,更加尖,对不对,很很尖,但是呢它在低频的地方,就是哎它不像缝模型或其他的模型,快速的就衰减于与接近于零了,它呢还是在往外延拖很久,这个东西如果大家玩音箱的话,我不知道。
你们知道音箱里面特别讲究一个东西是什么,知道吗,就是我要买个很贵的音箱,叫高音,要足够的清脆,够高,低音要足够的沉,那这就是个好音箱,它的表现力就比较强,对不对。
其实呢当然这是我个人发明的非常粗暴的理解,为什么大家都在用GG这个光照模型,其实它对高光的表达,真的符合这个一个好音箱的标准,就是我要表达那个清脆的,高亮的那个高光的时候,诶你这个波峰足够懂。
但是呢当我这个声音是混响,我的光也是混响,你的高光不会消失的那么彻底,如果大家用浮模型啊,你们会发现当我去调那个power那个参数的时候,一调不好,你会看到一个非常生硬的高光的边界线,就特别的硬。
感觉就像那个一个物体上贴了个狗皮膏药,但是呢你用了这个cookies模型,你用了那个GG这个模型的时候,GGX这个模型的时候,你发现诶它的过渡就很柔和对吧,所以这个大家如果怎么去理解,为什么行业。
你最后大家都用了这个GX模型的话,就用我今天这个非常土的这个比方,就是你买一个音箱,高音要脆,低音要沉对吧,要足够广就完了,这个那这个好的这个光照模型就出来了,当然了,我们得感谢我们的这些理论工作者啊。
就是用一堆的数学公式积分简化骇客,最后说,你看最后你用这种简单的数学公式就拿出来,实际上我为什么你们讲个hack呢,因为大家如果仔细读这些推导,你会发现大家做了非常多大胆的假设对吧。
那个也就是说real time render的精神是什么,就看起来基本对的,就拉倒吧,你你可以大胆的做各种的猜测和简化,只要不要把这事演砸,你这事情就过了嗯。
所以呢这个就是distribution的方程非常重要,而且这里面引入了一个非常关键的参数,就是roughness,就是它表达了你的法向分布的这种随机度,如果roughness越高,它随机性越强对吧。
roughness越低的时候才随机性就越弱,他就越聚集越像一个镜子好,你既然有了个随机度的时候,其实呢你就可以得出另外一个东西,就是那个GG是什么呢,就是叫几何这个微表面几何内部的内遮挡。
它简单的光学解释是什么呢,就是说哎你每一个表面不是凹凸不平吗,当我的视角看过来,我可能会被自己挡住,对吧好,当我的光射进来的时候,光可不可能被其他的东西也会挡住,所以实际上这里面只要理解一个方程。
就是那个GGX那个方程是什么呢,就是说那个叫那个斯密斯那个方程,它是实际上哦对之间的一个方程,他就算了一个东西,就是说我基于微表面的假假,假设你的表面上法线形成一个分布分布的,这个RP分母方程。
我给你对你一个假设之后,其实啊我可以用一些积分的方法大致估算出来,你在每一个不同的角度,我有多少的光会被挡住,然后而且那个挡住有个特点,就是因为我是全随机的分布嘛,所以说它只和你的这个你这个角度的啊。
怎么说呢,就是你的那个垂垂直的,这个就是这个这个这个cos应该是cos,还是sin的投影有关吧,而跟你的如果你是一个各项匀质的材质的话,我跟你的朝向是没有关系的对吧。
那好我对你的视线的阻挡是满足这个分布的,对不对,如果你是个均匀分啊,你这个随机分布的话,其实你的光过来也是一样的,所以你会发现诶他最后GGX材质的话呢,他就耍个流氓,他说诶我把光这个算一遍,你的阻挡性。
再把视线算一遍,阻挡性,我就知道有多少的光从入射的这个表面,到弹给我的时候全部被挡掉了,这里面最最简单的解释一下,比如说啊啊一个光百分之百的能量射进来,我根据你的normal碎片方程。
就是你的roughness,我知道比如说30%的光被挡住了,那我知道我剩下来的是多少,70%好,这些光呢又是无数的光子,开始往眼睛里面去跑的时候,因为这个分布是isotropic的,就是各项同性的诶。
又有70%中的30%被干翻了对吧,所以最后流到我这儿的就多少呢,应该是啊70%再乘70%,应该是49%的光到我这儿来了,它其实就这么一个简单的原理,但是它这个公式很妙的一个地方是什么呢。
就是我们在算那个它的这个D的,就是normal的实现方程,我们引入了一个阿尔法这个参数的时候,它又完美的直接用在了这个G的这个选项,所以你就只要设置一个参数,就是roughness。
你就能得到两个结果好,那第三个那就是大名鼎鼎的FNOL对吧,FNOL就费尼尔现象,我相信很多同学都已经啊,如果学习过图形学的话,或者说上过图形学相关的课程的话,再次提我的师弟另起的课啊。
那他讲的很很通透,大家不用担心讲的很清楚,如果实在大家想不清楚,过两天天很热,大家去柏油马路对吧,站在路上晒一下午,你看到远处的路面上出现了那个车的倒影,你就知道了哦,那就是FNOL的这个效果。
简单来讲,就是说当你的眼睛的视线非常非常的,这个靠近那个表面的那个这个切线方向的时候,它的反射系数会急剧的增加,然后呢这个时候你就会产生这种倒影的效果,就是我们的海市蜃楼的啊,当然这不是海蜃楼的成因啊。
海蜃楼它更复杂,它空气的密度是不一样,我们不展开,但是的话肥料的话,它本身它就能让你看到这样的一个倒影的效果,那么其实呢,它其实也是可以用微表面的方程去推出来的,但是呢这件事情我还是要感谢这些理论的。
这个这个图形学的这些研究工作者,他们就直接给了一个说哎,你把这个参数给个参数,你自己调,然后呢比如说你是非金属,你是金属,你是什么材质,这个数值范围是多少,我就告诉你了。
然后呢给了我一个很著名的叫做五次方,我记得从我开始学图形学的时候,我就一直在问为什么是五次方对吧,然后呢老师就会告诉我说,嗯这个是人家推出来的,然后呢我就默默的相信了,直到今天我自己我我得坦诚啊。
我还没有推导过我,我我觉得我以,我现在已经把大学的数学还了一半,给我的老师的这个这个现状的话,我觉得我得好先复习一下我的数学,才能推得出来,反正就是说大家记住了,这里面有个大牛推出来,这是个五次方。
好这个方程完美了,所以大家发现就是说诶,这个时候COTAS这么复杂的一个反射方程,实际上我只要用一个roughness这一个参数,阿尔法,再加上一个FNOL参数,我就能够非常符合物理的基础。
假设的去表达一个材质,所以这件事情真的是非常的了不起,所以这种工作啊,他他是能够上这个这个很好的这个paper的,cotton上这个paper,但是呢很遗憾,就是一些其他的一些方程的话。
好像我没看到他能上上C挂在C其实蛮难,就是对rendering其实不是特别友好,我待会儿会跟大家讲这个问题好,所以那其实呢,我们的计算机的这个引擎的工作者,其实包括我们的这个就是做动画电影的工作者。
我们就做了一个非常了不起的工作,就是这是著名的这个就是那个MRER这个lap,这个lab是非常了不起的,这个我如果没记错的话,是在德国吧,还是在欧洲的一个地方,他们做了这套设备,不一定是那个设备。
但是这是一个很经典的,这个就是b r d f measure的这个设备,就是光啊,和他的那个就是摄像机的角度一直在变,然后我就把这个所有的真实的材质给裁出来了,因为我这样踩出来之后啊。
我就可以告诉艺术家说,你对不同的材质,你的阿尔法你就是你的rough,你该怎么设置,你的这个就是啊你的FNOL该怎么设置对吧,包括你的diffuse应该是多少,这次其实这其实真的是一件非常了不起的事情。
那么当我们有了这样这么多感性认识的时候,我记得当时我在做啊,刚刚进3A行业的时候,我们其实那时候用的就是CUTORS模型,那时候我们已经不用不用不LIN缝了,也不LPHONE,其实3A行业很早就不用了。
但是的话呢,事实上,那个时候普通人的模型真的是有很多问题的,就是artist经常会把它用的,怎么说呢,就是匪夷所思对吧,你会经常看到很奇怪的bug,特别是刚才我们讲了吗,就是说如果你的能量没做好。
不守恒的话,那么这个light map就直接炸掉就死给你看,然后你就开始去调,你说为什么怎么回事,因为light map它会模拟光的来回的BING,你就会死掉了,那么这个时候实际上的话呢。
我们这里面要引入一个大神,这个这位老哥也是我非常敬佩的一个老哥嘛,就是迪士尼提出了这个BRDF的principle,最著名的迪士尼那个信条,他中间讲了几个点,为什么我今天就是作为游戏引擎课。
我会把这个东西再开了,其实这个老哥呢迪士尼是在做动画电影的时候,他们首先引入了就是PB2,基于物理的材质,但是呢他提出了几个信条,这个信条呢,我认为是跟游戏引擎设计的理念是高度相关的,他比如讲了第一条。
他说每一个参数它必须要符合艺术家的直觉,对吧,就艺术家不能不懂,你不能够用,这个就是说非常抽象的这个物理概念对吧,然后呢,第二个就是说你不能,就是你不能像做一个理论物理模型说啊,这个东西的它的波长。
它的,就比如说你设置你这个材质的反射光波长对吧,那个光那个电子的这个吸收光谱的频率,那你跟艺术家讲,艺术家当场死给你看,他都不知道这个这个游戏,这个东西应该怎么做了,所以他必须要让艺术家能够理解。
第二件事情是什么呢,就是说你要尽可能少的参数,这一点真的让我回想起我痛苦的过去,十几年前,当时我们在做游戏的时候,那个材质参数是这么差,非常差,真的这个调到后来自己都晕掉了,你不知道在调什么。
经常是你调到上面的,下面的就嘭一下就变了,但是呢它它解决不同的问题,而且呢第二个的话呢就是说他希望是啊,所以第二点说参数要尽可能的少,第三点呢所有参数的值的范围最好是0~1哎。
大家想想bin phone里面那个power,就是那个高光的那个那个参数,是不是可以23456789,你你高兴写到100都没有问题,对不对,但是我问那个布林峰,那个100和50和十到底什么关系。
你想不清楚对吧,但是这个就是BRENT同志,他就这样说,我们迪士尼的信条是我设置所有的参数,最好一定要0~1对吧,但是呢在有些特殊情况下,我也能允许你超过这个范围。
但是呢它必须要有一些有意思的这个结果出来,那么这就是说明你这个模型是有一定的,就是叫创作弹性的,那最后一个也是非常非常重要的,就是说这些参数你去调它的时候,随便你怎么调。
它的组合不会产生那种非常诡异的结果,它每一个组合基本上都是有意义的,其实这五条啊你看似很简单,但我在游戏的图形学里面,甚至我在做游戏,比如说做游戏的物理,我在做游戏的AI的时候。
我给这些这个我们的designer,我们的artist去暴露出来参数的时候,你会发现事实上你如果能够实现这个五条的话,其实是非常的难的,但是这件事情为什么我一定要去讲呢。
就是说当同学们在做游戏引擎的时候哈,呃一定要意识到引擎本质是什么,不是对自然界的一个模拟器,它实际上是一个工具,他的真正的用户是我们的设计师,是我们的艺术家,所以你必须要用他能听得懂的语言。
去帮助它来构建他想象的世界,所以所有的复杂,所有的这个困难留给我们自己对吧,把悲伤留给自己,把困难留给自己,把这个快乐留给我们的艺术家和设计师,所以我个人对这个迪士尼信条,是非常非常的推崇对。
所以这个这个人的话,我还专门找到他的照片放在这,我们的课程上供起来,这样大家以后下载我们的课件的话,每天可以对着照片膜拜一下,我觉得我我我我,我特别喜欢在课件上给大家讲一些,我们崇拜的大神。
因为确实这个行业能走到今天,真的要感谢这些大神,那么基于这个逻辑的话呢,他就提出了一些一堆的概念,实话实说啊,就迪士尼那个那个那个他的P2吗,T2,有些材质属性到今天,引擎支持的也不是特别的好。
比如说像那个啊clear coat对吧,我就是表面生成一层木漆的效果,包括shame这种很像抑郁的这种效果,实际上呢就是迪士尼它自身也在一直进化,它的材质模型,但是呢我们的引擎因为我们是实渲染它。
它是离线嘛,所以我们一直在追他们,但是呢以及仔细去读他的每一种材质的表达,真的符合他的原则,就非常的直觉,非常的明确好诶,我今天好像时间有点长了,已经一个多小时了,后面还有好多东西啊。
我我我想想看我怎么去给大家去加速一下啊,OK这确实今天的东西实在太多了,我们我们这个准备课件的话,这这这一周多干的真的是爆肝,肝没了,但是说实话我们还是对自己很不满意,我觉得课程准备的还是不够好。
确实有意思的东西实在太多好,那其实这里面的话呢,我们只有直接直奔主题,就是作为同学们的话啊,因为PB2的知识量很大,那我觉得同学们先聚焦,就现在这行业里面用的最规范的,PPR模型是什么。
我们就介绍两种对吧,最主流的第一个就是啊,spector glasses的这个模型就简称S级模型,它这里面的话呢其实它很巧妙的一件事,你就说他几乎没有什么参数,所有的属性全部用图来表达了对吧。
我相信很多同学这时候很激动了,对我很熟啊,如果你们用了substance用什么,你们肯定就知道这个模型,这个这个材质模型,那么很简单,第一个defuse to对吧,那么它有三个通道。
RGB还有一个什么呢,就是spectre to spectre图控制什么呢,控制它的那个就是说那个他的那个就是那个啊,FNOL那个参数对吧,然后呢第三个图是什么呢。
也是RG比较它的free nol是三种颜色,它的free nol是不一样的,为什么呢,当我去表达,比如像黄金,像这种带颜色,像铜这种带颜色的金属的时候,它对于不同的色彩,不同的角度,他的反应是不一样的。
这个也是非常了不起的事情,就是被这帮老哥居然给研究出来了,那最后一个参数叫glasses对吧,就控制哎我这个区域到底是更粗糙,更光滑一点,就4G模型的话呢,我认为是一个全模型,它非常的完整,非常的经典。
那么而且呢它符合迪士尼的principal,就是每个参数都是0~1之间对比,大家看一下好,那当我踩到了他这些参数的时候,我拿到他的SPEER,拿到他的diffuse,拿到了normal对吧。
还拿到它的一个向量,就一个不是向量,是标量,就是那个他的那个光滑度的时候,哎我就可以写一段很漂亮的SHADER了,这个SHADER的话呢具体的细节我不展开了,但是大家可以看他在前面做了一系列运算。
比如说他通过GLOSSLESS用一减这个值的话,诶我算出了roughness好,包括我的那些中间值全部算出来之后,大家会发现没有,我就可以带入到前面讲的那个就是AGGX。
那个就是那个cot模型里面的那个,就是F那一项,就是那个FNOL那一项,我可以算出他的FNOL那个part是多少,我可以算出他的geometry,就是他ACCUTION那一项我算是多少。
我可以算出什么呢,我还可以算出他的那个就是那个啊normal distribution,那个方程的像多少,把这三个项乘到一起,你就能得到它的一个非常漂亮的,COTANCE的反向值。
你看这个伪代码的就是第一个函数的最后一段,是不是就三个数一乘,你就能出道你的结果对吧,那这里面当然当然大家真的去写这个这个方,写这个代码的时候,一定要注意,就是有些规划要做,比如说有的要除以派啊。
有的要怎么样,这个地方的话呢,在初学的时候是特别容易写错的,我自己最开始在写PPP的时候,我我们其实也是经常会发现哇,这个材质看上去怎么这么假,后来又发现哦,里面某一步运算你知道吗,你整体算错了没问题。
它就是变量变换,有的时候你中间有一项算错了,你在很多时候你觉得你都是对的,但是突然在一个时候你发现错了哦,原来里面的某一项,我没有把它规划做一些必要的处理,因为他的所有的数值意义都是积分出来的嘛。
就积分你在球面上积分,你最后求出来的那个那个总的那个膜,是个派还是四分之派还是派分之四,whatever他都有有讲究的,所以这个东西呢大家要小心,但是呢如果大家严格地按照书上的说方法,去实现的话。
一般问题不大,所以你会发现就是spectre glasses这个模型的话,它很巧妙的一个地方,就是你几乎不用设置任何的参数,大家还记得刚才我们在讲bling for模型的时候。
诶你要设置一个诶我的那个这个SPECER啊,我要设置我的这个就是那个啊这个diffuse,这些东西现在全部变成土了,这样的话就artist可以精准的进行像素级的控制,而且他无论怎么控制它。
金属的就真的像金属,非金属的,真的就像非金属,就像这边左边的这个球吧,这个案例的话,其实它非常完美的展现了这个PP2的这个power,他的他的这个实力。
但是呢这个PP2呢SPECTACROSSNESS模型的话呢,它实际上是有个小问题的,就是说它太灵活了,特别是SPEER那个RGB那个通道,artist呢它一旦设置不好。
它就会导致这个FNOL内向就炸掉了,那个那个那个内向叫F0内向,一旦炸掉之后,这个材质啊看上去就非常的奇怪,所以呢在工业界大家后来呢想了一个土法炼钢,说我们研发一个新的模型叫MATIC,Matic。
那个那个那个roughness对吧,这个就是mr olic roughness,这个模型呢它就很粗暴,他说你首先设置一个base color,color放在这儿,你别动。
那么你呢设置只需你设置一个值叫roughness,就是你的roughness就表示你的粗糙度,这个没问题,我支持你设一个值叫什么叫metallic,这个词其实很关键,这个直接表示叫金属度吧。
你可以解释一下金属金属度它的意思是什么呢,就是如果你这个金属度非常低,你不就是个非金属吗,对不对,不好意思,你的这个颜色就不能够进入到他的那个diffuse,那个SPEER那个反射那个项里面去。
就是那个那个那个就是FNOL那个项里面去,但是呢如果你是金属的话,你的颜色就会被我大量的抽走,放到这个就是这个free nol内向里面去,所以这样的话F0的话就这里面大家看一下。
他其实他的做法非常的有意思,就是说他你可以认为就是说啊,MR2这个材质模型是在cs系模型外面包了一层,大家怎么去理解呢,就是我写个函数,这个函数我写了一个通用函数,非常强大对吧。
但是通用函数很强大之后很多人会用用错,比如说我做了一个啊,我做了一个软件,然后或者做了一个app,这app功能很强,大家什么都能用,但是一用用不好会变会把整个操作系统搞炸掉,对不对。
嘿那我在外面再包一层小白用户指南,我只允许你这几个开关,你开关变少了,但是呢我会保证你所有的参数都是有意思的,这样我的系统我的系统不会炸掉去,MR2的它的核心思想就是这个思想,然后呢它里面有个ERP。
就是根据这个metallic这个值,它在如果你是非金属的话,非金属我就直接把你锁死了,那个值好像很低,我忘了,好像是0。02还是0。3,就是你的base color。
就是你的那个那个那个color只能这么多,那个呃那个那个spectra整的那么多,但是呢如果你是这个金属的话,诶我逐渐的就从你的这个base color里面,把你的纸给取出来,这样的话虽然作为艺术家。
他的灵活度下降了,但是呢他很不容易出问题,所以其实在现在游戏行业的实践中的话,越来越多的工作室呢,会倾向于用MR2的这个材质,而不是用S级,因为其实就是这,这就是为什么那个迪士尼那个principle。
非常了不起,就是说当你管理一个几百人的团队,在做游戏的时候,实际上啊这种可控性反而是非常的重要,诶不好意思,我今天已经讲了将近一个半小时了,不好意思,我争取后面半个小时能结束吧,我们这个这个部分。
所以就同学们如果在学PB2的时候呢,我觉得大家重点的学习,就是这个SPECTACROSS这个模型,然后呢接下来再学习一个MR2这个模型,这两个模型基本上够用了,那么包括同学们去经常见到的一些引擎。
比如说像那个unity啊,Aria,大家也是这么实现的,那么呃就是刚,其实刚才我已经讲了他们的优缺点嘛,那么当然MR2这个模型呢它其实是有坏处的,它的坏处就在于,就是说当你在非金属和金属之间过渡的时候。
它容易产生一个小小的白边,这个白边呢你不注意可能注意不到,但是你仔细看也是能看得见的,这个问题其实真的就是MR2的一个问题,到目前为止的话,我们还做了一些研究啊,发现好像没有特别好的解决方案。
但如果同学们如果发现有的话,也不妨告诉我们,那我们马上把引擎改一改对吧,其实这个事情也让我们挺头疼,但是实际上我们的artist的话呢,确实蛮喜欢这个MR2这个模型的,因为MRR模型确实更加的符合直觉。
而且更不容易出错,好这就是大名鼎鼎的PP2的这个材质模型,那接下来呢就讲一个更加大名鼎鼎的,就是image based lighting光照,那这一趴呢其实有大量的数学公式,那今天因为时间不多嘛。
所以我可能公司会跳着往下讲,就是让同学们去快速的知道他的核心想法,其实他的想法也非常的淳朴,就是那好,什么叫光照,我们一直讲它是来自一个球面对吧,那球面的表达是什么呢,哎它就是一个一个一个一个。
就是说你可以用一个cube去表达,他最著名的cube map,一张texture,我就能表达来自于四面八方的所有的光照,如果你把这个cube展开,就是这个十字架这样的图,对不对。
大家看那个地平线和天空对吧,你把想象一下一个折纸游戏,你你就算折成一个cube texture,那么IB2的它的最核心的想法是什么呢,就是说如果我能够对这个真实的那个,这个环境的光照做一些提前的预处理。
我是不是就可以快速的把它,整个环境对我的光照,和我的这个材质的卷积运算直接算出来,在前面我讲的就是,我们用SAFAMONUX是不是也能表达,对不对,但是呢SAFMX那个表达其实是比较粗糙的,实话实说。
它能让你有些明暗的感觉,但是呢达不到我们想要的那种场景的,我们叫做这种细节感和凹凸感,那么而且呢当我们在游戏中去走的时候,你周围的环境一直在变嘛,其实我们是希望特别是主角身上。
他的比如说我的光从正面照过来对吧,我背面看到部分照亮了,那还有很多地方是暗部,那我希望暗部也有很多我们想要的这种细节感,这个时候呢就是有个很聪明的人,提出了这个IB2的这个思想。
这个AB2思想呢其实讲解来也很简单,就是说大家去看我们的这个材质模型,第二天为大家看到数学公式是不是很头疼对吧,它其实实际上就两趴,一个是defuse的部分,一部分是SPEER的部分对吧。
那么刚才我们已经详细讲了这两个函数的构成,对不对好,那diffuse部分,其实大家仔细观察就会发现它非常简单,它本质上就是一个cos函数在球面上的分母,那好对于任何一个就是比如说法向的朝向点。
那我是不是给定一个光照的时候,我是不是可以算出来,说这个这个面和这个球面上所有的点,进行积分之后,用cos loop进行积分之后,它的值我是不是可以提前算好对吧。
那我是不是就可以直接先算法一个叫diffuse,这个这个它的卷积的结果,这个这个图叫什么呢,叫diffuse erous math,对行业里这个叫法,其实这个词我认为不是特别准确,但是呢它的解法就是说。
当我知道了一个环境上的这样的一个一个,一个这么漂亮的一个光照的时候,我知道它的diffusion部分,无论你这个表面上的法向怎么转,比如说以我的身上这个衣服为例,诶,我知道光照过去,我我选一个方向。
我去采样,这个就是diffuse unity map,我就知道我和整个这个广场卷积的结果是什么,大家这个又是我们最经典的那个概念,叫什么叫空间换时间对吧,我先帮你把这个这个卷积计算给你做好了,放在这了。
你就记住就黑了,那这个东西为什么很重要呢,因为你想我这个空间上的光场采样,我比如说采样一个32×32吧,他也就是几万个点,这个卷积运算用硬件加速是非常快,但是呢当我去渲染这个游戏引擎的画面的时候。
实际上我屏幕上是几百万甚至是上千万的像素,而且呢我每一帧都要做,就是每每一帧要做啊,每一秒要做30次这样的运算,至少那这个运算量是非常大的,所以如果这样的话,我这个计算用一张这个小的计算texture。
就是其实这已经预先算好的,这个你可以理解成他这个计算表对吧,我查表我就能知道它卷积的结果的话,哎我的速度是不是会快很多,这其实就是IB2最简单的一个思想,defuse也是最好解的。
那SPECULAR呢实际上是比较复杂的,今天呢我们本来是认真的去推导一下,今天下午我们还自己再核算了一遍,确保一下我们的理解全部是对的,但是呢这个工程这个工程量太大,我今天就是因为时间确实太长了。
我就不展开,而且呃它实际上呢我觉得就这几个公式,没有那么容易讲清楚,但我跟大家讲几个最核心的想法,第一他这个对于SPECTRE的解释的话呢,这个解决方法我们我认为不是特别的这个呃。
呃我认为就是它它是一个不准确的一个解法,它实际上做了大量的假设,它本质上是三个方程乘法的积分,它变成了三个独立的这个方程的积分的乘法,这个讲解来有点拗口啊对吧,但是没关系,这个大家理解一下就好了。
但是它最核心的一个想法是什么呢,就是我们在这个我们也是把SPER这东西进行,沿着光,沿着这个自己朝向的积分,对不对,但是我不是有个很著名的量叫做RAGHNESS吗,粗糙度嘛。
那你不同粗糙度它接记错的结果不是不一样吗,诶它有一个非常巧妙的方法,就是他用了那个硬件上的q map里的meme map,这个功能,就是它把不同粗糙度的结果,存到了这个MMAP的不同的层级。
就像大家现在看到的这张图对吧,为什么呢,这个事情是很有道理的,第一个就是说,我相当于我可以在三维空间去查这个数据了,第二件事情的话呢,你会发现粗糙度越高的话,它对光照的这个敏感度就越低。
他就越低频的数据,对不对,所以我就可以把它放到mp的最低级,所以注意啊,这是你们的map,不是用mr map,就是俩二合一二合一合出来,他是真的一每一层要单独算出来的,这个大家一定要注意。
千万不要写错了,但是呢那而且呢它实际上是一个,它实际上是一个速算法,你的那个你的roughness从0~1的时候,你就可以在里面迅速的去查就好了,那么还有一个值呢,就是这个这个是这也是个。
其实这个学名叫look up table,大家如果玩过excel的话,都知道这个概念,就是诶,我把一些计算法的事放在一个look up table里面,我这边输出任何值的时候,他在里面去找对吧。
这个logo devil有两个维度,一个是什么呢,哎一个还是你的RPENCE往里往里面放,第二个呢就是你的那个斜角cos theta,记住啊,他只是如果你的表面是这样的,它就是这个cos theta。
就是你的这个角度跟这个这个环境的关系,你用这两个词合在一起,这个时候你会发现一个很神奇的事情,就是那个他的FNOL那一项的话,变成了一个线性项,就是放在里面。
你就基本上能够模拟cook torren的这样的一个,在这个就是环境光照下的效果,所以这个IP2的话呢,它的这个对SPEER的解决,我个人认为啊,也许我想错了,如果讲错了,同学们跟着我。
就是他其实是做了大量的假设的,给出了一个近似解,但是他的很优良的一个点是什么呢,就第一个,他第一次让我们能够在这个,就是说环境光照里面看到了一些高光的东西,注意啊,这个高光不是那种非常生硬的高光。
那其实用q map就能解决它,真的让我感觉这个地方好像诶有一点光亮,但又不完全光亮,而且呢它能模模糊的让我感觉那边有东西对吧,这个其实是非常了不起的一件事情,那么所以的话呢这两个方法合到一起。
就是一个完整的一个材质在环境光照下的效果,那这里面给大家看个图吧,就是这个左边的话是没有IB2的结果对吧,右边是那个对,右边是有IP,你会发现第一个看上去眼睛是不是舒服了很多,第二个大家如果仔细看的话。
你会发现这里面的层次结构很清晰,很漂亮,这个其实是IB2很妙的一个地方,所以这也是为什么十几年前,这所有的3A大厂毫无疑问的全部上AB2,这就是有道理的,他就是,所以其实呢IB2呢。
严格来讲是一种光光光照的方法,但是呢就是我们在讲的时候,我们发现我们必须要先把PB2是什么,讲解清楚,我才能讲IBR这两个真的像孪生兄弟一样,就是一下子让我们的游戏看上去真实很多。
大家看这边这个场景的话,是不是感觉就很真实,就很有这种感觉,所以这也是3A行业的话呢,就是大家最后总结出来的这样的一个方法,好最后一个就是shadow shadow的话呢。
我们今天的话因为shadow它的数学很复杂,我们今天不展开讲,但我只讲解一下,就是说在经典的3A游戏里面shadow几号啊,其实我相信很多同学如果听说过的话,能猜到,其实在经典的这个游戏里面啊。
shadow的最主流的解决方法叫casket shadow,对这个这个,这个当时我最早听到这个名字的时候,我就觉得我就想象成一节一节的台阶下去,我脑子里立马出现这个画面,其实它也是非常的简单。
就是像我讲的,就是我们的游戏世界越做越开阔对吧,但是呢你从光那边踩过来的沙特map的精度,它永远是不够的对吧,你我方圆一公里,方圆这个就是100米10米,那我都要看他shadow,比如说远处有座山。
我要看到它的影子,对不对,近处有10米之外,20米之外有棵树,我要看它的影子,对不对,门前地上放了一把枪,我要捡起这把枪,枪也得有影子吧,你其实这个东西如果你要把山的影子。
树的影子和枪的影子全部解决的话,这个shadow就非常的痛苦,你这个精度怎么设置都不对,那诶有个很聪明的人,他提出来了,说我把shadow分成几层对吧,就是他通过你眼睛视锥的方向诶。
我在你近处做一个很高密度的shut map,那个sha map的话呢,实际上就是精度很高,但是呢他一般做10米左右,然后呢接下来就是比如说30米的,然后呢100米的。
接下来就是2km的更大的这个shadow这样的一层,就是这这边有下面有个图,就是从你人眼看过去,你用的不同密度的,那个绿色的是密度最高的对吧,那个蓝色的是最稀疏的。
我形成了这样shadow的这样的一个图,而然后呢我其实这样的话,我这样的话我形成了最后绘制出来的shadow,他就近处看着足够的清晰,远处看着足够的系数,它也符合一个光学原理,为什么呢。
因为远处那些shadow他就算有一个边界的话,投影到你的眼睛的话,相对来讲实际上也并不是特别的大对吧,所以它是就是近大远小的原则嘛,所以远处你的眼睛的采样率也是下降了。
所以说呢哎你你你眼睛的采样率下降了,我把你的光的那个从光的那个方向,采样率也下降了,怎么样,我们两个就完美的配合在一起了,所以这就是casket shadow的一个简单淳朴的想法。
但是这件事情真的非常神奇啊,这么淳朴的一个想法,但真的是统治了这个游游戏行业将近十几年,就是我看了很多的游戏,基本上这是一个最经典的一个学习方法,就是在当然后面一些fancy的东西出来之前啊。
现在天下已经大乱了,但是在过去那个时代,casket shadow绝对是王者,那么他有一个经典的挑战是什么呢,就是说你在不同的层级之间,你要做这个差值要做,否则的话呢你可能会注意到一条硬的边界。
特如果你不做任何差,你会意识到就是当你的相机推动的时候,你看也有一个固定的地方,那个shadow那个地方会破掉对吧,但是你要做很多的处理,但具体的处理呢都是SHADER,你那些hack。
这个hack的话都非常dirty吧,就是说我当年也写过这些hack,所以我个人感觉就是不耻讲出来对吧,这这都是程序员内部的一些小小的这个,黑暗魔法在里面对吧。
所以的话呢就是说blend between the casket shadow的话,那就大家如果去写的算法的时候啊,一定要认真的研究一下几个不同的方法和套路,然后呢去看看自己选哪个方法去解决好。
那这里面的话呢,其实要讲的另外一个就是这个cos cocky shadow的话呢,它的问题呢就是他要以空间换时间,它的存储空间是蛮大的,另外一个就是说我要生成远处的shadow。
其实我相当于把场景给绘制了一遍,那时候你要画大量的东西,其实这个成本其实是不低的,就是大家如果了解一下,就是在就是那个游戏引擎啊,其实shadow的rendering。
实际上是游戏引擎里面最贵的一个独立的一套,而且这是让你真的很蛋疼,就是他并不是你真正绘制那种,漂亮材质的组成部分,它只是确保你的光的可见性是正确的,但是呢如果我们的绘制假设是30ms给我啊。
shadow很多时候会吃到4ms,甚至到5ms都有对吧,如果在一些比较复杂的场景,如果做的这个比较复杂一点,所以shadow我我自己的经验是,很少能做到2ms以下,对。
我不知道其他有没有大牛能做到这个级别一下,反正shadow你想做好的话,基本上是要到这个量级,所以shadow其实是非常非常expensive,尤其casket shadow对吧,你要绘制四次。
然后对场景要做四次的这个裁剪,因为你因为你在绘制那个最密的那个shadow的时候,你并不希望他花很多问题,其实你要重新算一次visibility,然后再算它,这里面就一堆的,怎么说呢。
就是这个老大说说做做凯斯克沙的,大家都很开心,但是真的去写的时候,发现卧槽无数的这个细节在里面好,那今天的话呢我顺便再说一下,就是其实啊shadow,因为过去给我们这个graphics。
程序员带来了无数的困难,所以呢其实我们后来也也想了很多办法,比如说我们就特别喜欢软阴影对吧,做游戏引擎的人都特别爱soft shadow,那么呢就是这里面的话呢,因为今天时间的关系我就不展开了。
因为我我我看了一下,就是啊闫令琪的课程的话呢也讲了很多算法,但这里面我就重点讲几个点几个吧,就是说第一个就是大名鼎鼎的PCF对吧,其实PCF真的是个好东西,就是他就是非常scientific。
用滤波的方法告诉我们说你怎么去做这个软硬,那么呢基于p cf的话呢,大家实战中用的算法就是PCSS对吧,它呢更精妙,他说哎我考虑一下你到底离光源的远和近对吧,我再用一个sample0。
我就能选中shadow,其实这个PCS的话呢,在过去的就现在很多引擎里面都是属于标配,就所以很多引擎里面,你去看他的shadow时长都带一点点软阴影,好像ARRA如果我没记错的话,就有PCS。
那么这样的话,你能看到那个阴影是稍微有点软的,那这个效果的话呢,实际上就能够极大地缓解我们的这个shadow的,这个alias对吧,OK不好意思,我讲课讲的比较忙,所以没空看大家的弹幕。
到时候我统一回答大家的问题,因为我现在赶时间,我希望我发现我已经讲了一小时40分钟了,争取两小时学习是结束战斗吧,所以这个我们的games课程的这个传统,是什么叫拖堂,然后呢我在前面一直控制的很好。
但自从一到图形学这一趴的时候,我发现这个就控制不住了,好那最后一个呢给大家讲解就是warrens shut up,那个soft shadow map,这个呢也是就是具体的算法,大家可以去研究一下。
我这边偷了令旗的这个课件啊,我觉得他这个灵魂画手画的这张图,是我见过把vs上单map解释的最好的一个一个图,我觉得这个讲的特别好,就一下子讲清楚了什么叫正态分布,什么叫方差的这个概念。
所以他简单他的想法其实非常的简单,就是说哎我去用它的二次方,一次方,我能算出它的方差,算出它的均值,这样的话当我知道我一个depth的时候,我其实就有一套数学估计方法对吧,这里面有一个叫切克夫不等式。
然后呢我就大概猜到我说我是大概百分之多少,这里面其实是无数的骇客,但是呢你架不住他最后真的work了,所以其实那个virus soft shmap的话呢,实际上很多引擎也是真的在用的。
而且实战效果还真的很香对吧,所以大家如果做shadow的话呢,基本上把这些方法搞明白了,根据你的情况去选择的话,就能达到一个你想要的这样的一个结果好,那所以呢其实在上个时代吧,我觉得这也是我今天课程的。
主要就是大家可以理解就是当我做渲染的时候,光我一般用LIGHTMAP加light prop的方法,一般来讲很多引擎的这两个方法都会去用,就是在一起它它解决不同的问题的,那么然后呢我去材质的话。
大家这个真的就是天下武功吧,一统江湖就是PBR1统江湖,真的这是当今世界毫无争议的王者的存在,然后呢诶我对于这种背光面的表达,对环境光照的表达,大家现在也基本上也一统江湖了。
就是image base lighting,所以说你掌握了PP2,PP2只需要掌握两个模型,一个是S级模型,一个是MR2模型对吧,在学会IB2,你基本上光照这这个材质,光照这一趴就够了。
然后呢这个时候你遇到最难缠的shadow怎么办,还这个大神已经帮你指出了一条明路,就是casket shadow对吧,这真的是大神,我觉得那那篇paper我还读过,好像我记得好像是一篇CH对吧。
我也很奇怪,c graph居然能发这么工程的文章,这个然后呢就是casa shadow,然后呢你再用比如说vs sem,就是那个warrants soft shadow map。
或者你或者用那个就是那个啊PCSS对吧,Percentage clothes,Soft shadow,这技术加上一点点那种软阴影,恭喜你,你基本上有能力可以写一个大概呃。
5年前到10年前的3A游戏的渲染引擎了,这个基本上可以出来找工作,没有什么太大问题了,但是呢这个后面这1part我会讲的比较快乐,就时代真的在一直快速的变化,因为就是就像我在第一节。
第一节课和那个就是在rendering的第一节课,我讲的这个概念嘛,就是说我们真的要感谢,就是这个硬件的飞速的进步对吧,这个这个N厂A厂都很都很努力,得天天掏空我们的钱袋子,然后呢DX十二十二。1。
然后VULKAN出来,然后实际上的话呢它极几乎是彻底颠覆了,就是渲染的底层算法和逻辑,这个我真的要这么说,为什么呢,因为他把整个的计算全部开发出来了,就过去我们很多想干不敢干的事儿。
他现在在硬件里面我们都可以看,第二个就是它的硬件算力对吧,基于一个WAP,基于一个就是wave,它的算力非常大,而且之前数据通讯同步数据的,就是来回的倒来倒去的非常的方便。
所以其实刚才我讲的像light map啊,像light property算法,在最新一代的这个游戏里面,我们真的在这个突破的边缘,所以我在这个就是RNN的这节课,第一节课我讲了一个概念。
就是说如果大家真的在这个实践的这个行业,这个领域里面去金砖的时候,你会发现比理论领域很累,为什么呢,因为你要去不断的跟进最前沿的知识和体系,特别是在硬件发生革命的时候。
各种新的算法和方法就雨后春笋的就冒出来了,那这里面比如说大名鼎鼎的对吧,叫实时光追对吧,实时光追这个东西,实际上本质上就是硬件提供了整个这个方法,就是诶你可以把三角形扔进去,他帮你构建好一个。
我们在这个老早以前反复讲的叫b vs tree对吧,这个时候你输出一个瑞,他就会告诉你说你是hit到一个东西呢,还是什么都没黑到,如果hit到了,我给你回调函数,没H的到,我也给你回调函数好。
接下来怎么办,你自己处理,那么实时光追这个东西呢其实非常有意思啊,就是说现在游戏的标配,你的也要有个实时框架,否则你都不好意思说你是现代游戏了,但是呢你仔细看,在现在游戏中。
我用我看的比较多的都在用来做反射,就是甚至我我再提一下,就是那个当时那个微软最著名的那个FA,赛车游戏,他当时那个最新一作horizon,说我实时光追的时候,他故意把那个就是那个汽车的那个GG。
做的非常的bling bling的,就很多很多的反射,我就说啊大哥你为了卖一个feature对吧,也是也是很用力,所以说呢其实我自己也很很好奇,就是说实时光追这个东西啊。
它其实或者叫recasting这个这个模块啊,它能解决的问题绝对不止这个SPECTRE这些东西,或者不只是retracing,实际上我个人认为,它会彻底的改变我们的光照体系。
就是real time的格罗布image information,就实时的全局光照,我相信同学们在看那个就是说啊,虚幻五最新一代引擎的时候,大家最震撼的是什么,lumen那个效果对吧,很漂亮。
那么实际上呢这就是硬件的能力解放出来了,那其实现在做JI的很多方法在互相的形成,比如说最高效的screen space gi对吧,在评论空间我去快速的形成这些GI,那包括就是说哎我基于有向距离场SDF。
我做的这个GI,包括呢我把这个世界分成各个WORKO对吧,那么这个最著名的就是SVOGI,就是那个叫spars这个vocal这个OCRGI,那么还有什么呢,就是这个VXGI,但是现在也是当红炸子鸡。
大家都很火,包括还有就是那个real reflective shmap对吧,还有这个什么RTX的GI,听说是大家是眼花缭乱,对不对,那个没关系,这个首先大家建立一个概念。
就是说当这些real time的积压起来之后,整个游戏的画面真的会有一次质的飞跃,我个人认为,就是现在作为一个商业级的游戏引擎的话,这个real time的格罗布是必须要解决的问题。
而且呢它的解决方案其实并不简单,就是我们在这个课程的这个后面的高级啊,就是后面的有一个专讲,我就讲一些前沿技术嘛,我们会专门拿至少半节课的事情,努力的把这个比如像lumen的技术给大家讲清楚。
就提前给大家剧透一下去lumen里面的话呢,它并不是一个单一算法,它实际上是把三四种算法应该是四种吧,如果没记错,四种算法保保这个组合到一起去用,最后能产生我们想要的那个效果。
所以其实它是个非常复杂的一个工程问题对吧,但是我个人认为的话,同学们,今天如果想跳到这个图形学这个领域,里面来的话,我是我,我会鼓励大家密切的关注这个领域,因为这个领域真的是蓬勃发展。
有大量的前沿的技术和观点再出来,说实话,有时候连我都觉得这个几个月不看paper,或者说不跟大家去聊的话,我都会感觉有点落伍的感觉,而且我真的感觉就是有一个巨大的革命,正在地平线升起来,就这件事情。
这个时代已经到来了,那么另外1part呢,就是说在现代的这个3A里面的话呢,就是这种比较复杂的这种材质的渲染,比如说3S的皮肤材质啊,毛发渲染,都在推到了一个非常非常高的一个,一个一个维度,为什么。
比如现在毛发渲染为为例吧,现在由于GMRSHADER这些技术很发达,就是我可以迅速的生成无数的细节,而且它光影效果会做的非常的复杂对吧,3S材质的话,我可以用这种就是强大的算力。
可以模拟光在那个材质里面的,refection的一些数学结果,所以这也是让这个就是这些东西都变成了可能,所以比如像cs才知道,最近这两年的那个新的方法和paper是非常的多的,所以的话呢他很遗憾。
就今天这个课程实在内容太多了,所以没办法给大家去展开,我现在的语速好像也是越来越快了,OK好,那最后提醒大家,就shmap shader map的话呢,传统的CASA的shadow是挺好用的。
但是呢我会提醒大家注意一个新的一个方向,就是这是我们前段时间去研究虚幻五的时候,发现一个非常有意思的事情,就是他们提出了一个virtual shmap,这个想法其实呢很淳朴,就是大家如果以前学过啊。
这个这个还是还是跪拜我们的john ka这个大神啊,他以前提出很牛逼的概念叫virtual texture,就是说我把这个游戏环境里面,所有的你要用的纹理,全部拍到一张巨大无比的纹理,纹理上面去。
那个纹理叫什么叫VERTEXTURE,就是你要用的时候,你就把它调出来用,你不用的时候把那些texture卸卸载掉,offload掉,那么virtual shadow map的想法跟那个有异曲同工之妙。
诶你不是要做cask shadow吗,你要做很大的地方吗,诶他先用算法去算说我每个地方,哪些地方真的需要去这个生成式的map对吧,这个山的麦密度到底是多少。
我就在一个完整的这个这个虚拟的shut map上,去分配它的空间,然后呢你就一小块一小块TID,去generate你的shut map,当我用camera去渲染的时候,我打出每个物体。
其实我可以知道说你应该取哪个沙雕web的值,然后我就反向去取它,这个想法其实是非常的有意思的,而且呢我个人觉得它能够解决,就是那个casket shadow的话,空间的在有些场合下利用率不够高的问题。
而且也很废的问题,所以呢这个方向,我觉得如果大家现在做现代引擎的话,我建议大家去关注一下这个,这个这个新的方向好,那最后我花5分钟吧给大家讲一下,这个就是大家可能注意不到的事情,就是其实在游戏引擎中啊。
有一个东西很麻烦,就是大量的SHADER,非常多的SHADER,这个里面就是扩一下我以前的老东家那个班级,班级做完destiny之后,这个其实这个项目我也参与了,所以我知道他们讲的这个所有的东西。
就是确实是很蛋疼,然后呢他就讲了一个例子,就是说一个关卡,你看过去就是一针下去几千个水准,跑跑出去了对吧,哪里来的那么多SHADER呢,其实有两个源泉,第一个源泉呢首先怪我们的艺术家对吧。
艺术家他会做大量的shader graph,大家理解就是每个shader graph,到最后它们都会变成一段SHADER对吧,这个艺术家的想象力是不受你控制的,所以这个SHADER的数量会很吓人。
那么第二个的话呢就是我们程序员自己的问题,就是大家去想象一下,就是其实在游戏中啊,各种的限定条件非常多,比如说你这个材质是在点光源下,是在面光源下,是在这个全球光照下。
sf server harmonix下,你是单面渲染,双面渲染,你带不带阿尔法是不是一堆的变换,如果你把每一种变换组合都单独写个SHADER,这个SHADER的数量是非常非常大的。
所以呢我们一般会写一个完整的SHADER,这个SHADER叫什么呢,叫UBERSHADER对吧,这个词同学们可能听过,然后这里面呢我们一般会用宏定义,去把各种情况给它分出来,那么每一种红灯异。
就代表了函数的一种可能的分支,大家还记得我以前讲过,就是那个GPU里面,他呢最讨厌的就是分子,为什么呢,因为比如说一个函数跑起来,它有一个分支的时候,就会导致它的执行的时间长短是不一样的。
但是呢他那个GPU采取的是SMT的架构,他希望我1P指令扔出去的时候,结束的时间最好是一致的对吧,所以我们就会把这些所有的分支编译成,铺天盖地的学着,这里面我举个魔引擎的例子啊。
就是大概有165个我们手写的SHADER,Template,就UERSHADER它的生成多少,生成7万多个SHADER,这里面我随便截了个图,大家看一看对吧,这个就非常的非常的丧心病狂。
但是为什么uber 这件事情是有道理的,因为你想期望那个学着,假设今天我发现了一个bug,我要去改一类SHADER的算法的时候,如果你不采取五本式的这个方式的话,你得逐次的改它。
所有可能组合这个很可能就会改错,对不对,但是用UBER的这种方式的话呢,它自动就编译出了各种组合了,所以它是有道理的,但是呢这些学着就是warrens或者叫permutation。
其实是现代游戏引擎非常重要的一个,方法论和概念,那么OK,那么最后一个,大家很容易忽视掉的一个问题是什么呢,就是说其实SHADER啊,这个这确实要怪行业,比如说我写引擎,我写C加加语言。
我是不care你是用什么平台的对吧,SHADER这么常常用的东西,居然你给我搞了这么多语言对吧,GRSRHRSR对吧,然后apple还丧心病狂的好好的open gl es不用。
他非要去搞一个自己的metal,对不对,但是呢所以当我们在做商业级引擎的时候呢,就是跨这个平台的编译其实是很重要的,那么现在的话呢很感谢开源组织,他们做了一个就是spell那个V的。
这个这个这个开源的这个第三方的库诶,它能够帮我们在各种学着你们编来编去,包括像那个PLAYSTATION的那个叫p s cl吧,其实也可以编译,所以这个的大家在做引擎的时候。
当我们去学习SHADER的时候,我建议一开始就会尝试,把它编译成VULKAN的版本,编译成这个就是metal的版本,编译成这个其他的版本,这样的话就避免你以为对不同的平台,你在单独写一套。
因为他的debug起来是很麻烦的,但是呢就是说这个也是很重要的一件事情,所以你有了这个东西,你的SHADER基本上就能管理起来了,好那我今天呢终于这个紧赶慢赶,把我的课程的主要部分集中在这个两小时。
讲完了,最后我跟大家讲一下我们的小引擎,pilot的引擎,这个首先非常的感谢大家,就是我们肖引擎的话,上线之后很快就能收到1000,好像1600多个赞了嘛,真的很感动,这我能感受到大家对我们的支持。
就是说确实我们呃能力有限,而且呢就是确实我们是使出了我们的吃奶的劲,想把这个小引擎做好给大家,那么而且呢像一上线之后,很多同学帮我们去快速的修各种bug,我们自己那个就是我们的项目组。
同学的话也是努力的,就是尽快的把大家同学们提的问题修好,那么的话呢跟德告诉大家一个好消息,就是现在的小引擎版本,终于可以支持mr one的这个这个,这个就是apple的MR2。
神奇的mr one的那个CPU的这个这个这个版本了,那么同学们讲了一些编译问题,一些bug问题的话呢,我们这边也会快速的去处理,那么最后呢我我我最近也在想一件事情,就是说啊我们如果一起做小引擎。
大家做的很开心的话,我们可能后面会考虑,逐步的把一些就是比较复杂的一些算法,一些东西放进来,就是我想跟大家社区一起嘛,一起做个好玩的引擎嘛对吧,就做一些比较fancy的东西,比如同学们千呼万唤的这个。
比如说像什么就算比较简单了,对不对,我们要不要搞个IP2对吧,我们要不要搞一个自己的这个GI,搞一个real time returing在里面,其实你现在这个框架在上面加的东西,并不难的。
那么这件事情的话,到时候我们也会跟社区的小伙伴们一起去讨论,因为我觉得这就是开源的精神,这是我们不明第一次跟开源触电,其实真的是蛮有意思的,我因为这件事情对于我们来讲的话。
就是我们也希望能够扎扎实实地为行业,为大家做一点事情,真的我们的口号是什么,就是这个课程上完人手一个这个自研引擎对吧,那到时候中国自研引擎大爆发,这也是我们很愿意看到的一件事情。
那么最后跟大同学们讲一个坏消息啊,就是呃我们经过慎重的考虑,决定了五一节我们让自己休息一下,真的课程组实在是干豆累爆了,大家今天看到我们的PPT slice的量,也知道我们过去七天是怎么过来的。
这基本上就是已经是快爆炸了,但是呢我们会坚持,就是坚持把rendering的剩下两节课讲完,就是然后呢五一节正好那天是小长假,我们打算呢ring讲完之后,请大家允许我们休息五六天对吧,我我我我自己讲。
我说我一定要休假了,因为我周末基本上从来就没有休息,没办法休息,因为周一就要讲课,所以周末的礼拜五,礼拜六礼拜天对我来讲就是地狱模式啊,所以其实今天为了备课的话,实际上我们是要很认真的去查很多资料。
确保我们讲的东西尽可能的不要犯太多的错误,其实肯定会有是有错误的,刚才我自己讲的时候,我就发现PPT上有很多错别字,我还来不及去改对吧,所以说呢呃我们打算就讲完rendering,这一趴的时候。
五一节的时候我们好好的休息一下,请同学们给我们放个假,然后呢,五一节之后我们就开始讲更可爱的动画系统,给大家好吧好,那就今天我课程的全部,那剩下来还有几分钟,同学们有什么问题可以问我一下。
再次感谢一下我们的课程组的同学,其实课程组的同学们已经不止这些了,我后面把它名单再再变得更长一点,然后这个同学们有什么问题问我们,哇这个第一个问题就非常挑战,同学们问我说基安未来会怎么发展。
我个人认为就是在游戏引擎中积压的问题,随着硬件的发展,可能在未来的5年左右吧,可能会彻底解决掉,也就是未来的游戏引擎,它应该上来就是GI的,就是说比如说我在读研的时候。
我特别喜欢一个算法叫风投map对吧,就是那个pd haham,就是STANFORD的一个大牛,大家说他提出的方案,我个人认为是最elegant的一个GI的光照算法,然后的话呢其实我现在一直在想一个问题。
就是说哎,哇这个这个东西,能不能现在做到游戏引擎里面去了,我现在看到一些paper已经讲这个事情了,所以说我觉得随着这个就是general computer的这个,这个这个彻底的开放的话。
我觉得其实GI已经很明显的看到一个,彻底解决的这样的一个苗头了,对这也是刚才我的课程中也讲到,就是说如果大家考虑未来10年的引擎的话,那既然是一个must,需要彻底的去攻关,去跟踪前沿的一个方向。
啊这个同学们问我的问题更专业了,他说云渲染能不能解决卡基亚的这个问题啊,这个问题其实呢是一个,我觉得比较深深度的一个问题吧,我我想我其实这个问题我得首先得承认啊,我想的不够深,但是我确实是想过的。
那我先抛一个我自己个人的一个不成熟的观点,就是呃我觉得云渲染的话,如果采取端云协同的话,说不定还真的能解决,卡基亚老先生提的一些问题,为什么呢,你会发现在这个渲染方程里面。
有些计算是view dependent的,就是跟你的观察者是有关系的,有些计算呢其实是跟view没有关系的,就是空间上我就要算法的,比如说那个light problem light map吧。
包括像那个我刚才讲GIGI,有个很著名的叫SBOGI对吧,就是sparse workworks的那个worker orchestr算法,那这个东西的构建的话,那实际上他构建好一份,你有一一个人去看。
十个人,看100人去看,他都是一样的,那这样很多计算机可以share,那这样我实际上就可以把卡基亚老先生的,一些计算就在上面统一的资料,因为我一个人算一次很贵对吧,但是如果我100个人,1000个人。
我只算这一次放在这的话,他可能就比较便宜,其实在这方面的话呢,好像如果我没记错的话,有一些团队,一些很优秀的团队已经开始在探索这件事情了,啊有同学们问我的,问这个问题就比较practice。
他说游戏里面的动态日夜,怎么去解决光照的问题啊,这个问题呢,实际上在第三节课我们会讲到一点点,这个系统呢在早年有个说法叫做TD,叫tf day对吧,就是你去模拟一下,从早上太阳升起到中午对吧。
哎再到下午慢慢下垂,到傍晚出现晚霞,再到夜里面月亮升起,这一套的光照的变化实际上是非常复杂的,这个复杂还不止于此啊,就是说因为你是这个在地球的不同的纬度,不同的气候环境下,你这个光影的感觉是不一样的。
其实在以前最早我们在研究这个系统的时候,是要精确的去理解,就是说比如说在极地,在温带,在热带,在在海洋性气候的地方,它会怎么样,但是这个讲解来听说去是不是很玄乎,但实际上如果你要做一个非常沙河向的。
而且非常其实这样的游戏,你真的要解决这些问题,其实这里面的话有很多很优秀的文章,在解决这个问题,那这个问题,为什么我们在这一课里面没有去讲呢,因为它实际上你去模拟的光照。
你要和天上的就是那个sky rendering,SKYON的rendering是有很大的关系的,因为比如说我说这个天很亮,它不是一个光源,打的很亮就完事了,它周边的那个天它就会变亮对吧。
旁边如果有云云也会被点亮,其实那个就是你看一个天球吧,亮的区域和暗的区域它是有个分布的,所以的话呢包括就是呃白天和晚上的光,差别度是非常大的,如果我没记错的话,能差个大概10万倍以上。
就是如果你是正午的阳光的那个流明,应该是晚上的月光的光度的好像是上万倍以上,所以的话呢你的这个材质,所以刚才为什么讲PB2,Pb2,实际上他的PBR的light,就是这个就是基于物理的这个light。
实际上讲的就是这个道理,就是你敢不敢把真实的这种,几万倍以上的光学参数输进去,你做的结果也是对的,你因为你只有这个东西做对了之后,你才能够做出真实的那种感觉,还有就是那个艾比尔对吧。
你整个天球给你的光照,因为天球光照,其实在整个光照中的贡献度并不低的,就是说如果以白天为例的话,如果我没记错的话,这个就是环境给你的光的话,能达到你的光呢大概1/5左右。
所以说特别是你走到那种树荫下对吧,走到那种广场不是特别强的地方的时候,那个环境光是非常重要的一个CONTRIBUTER,所以的话呢在这节课里面,我们讲了一些基础的数学表达,但是呢你真的想做出一个。
日夜变换的效果的话啊,其实有很多很细腻的东西要解决,对哦对,跟大家说一下,忘了这个今天因为时间我实在太长了,所以不好意思,不能回答大家的太多问题了,有些问题的话,同学们可以在我们的B站,我们到视频上。
大家可以问我们,包括我们的很多微信群,然后我也尽可能我们去回答大家,其实很多问题都不是我能回答了,因为为什么呢,因为量太大,就是我们拜托我们的工商公司,跟我们一起来回答,然后呢,另外一个就是那个啊。
这节课呢我们暂时不布置作业,因为rendering的作业啊,这个不布置就算了,一布置就很大哈,所以呢我们可能会在整个render结束的时候,给大家布置一道作业,然后给大家更充足的时间去做它。
所以这两节课呢同学们只要认认真去听,认真去想,然后呢选去思考和选择你感兴趣的东西,另外呢利用这个时间熟悉一下小引擎,因为一旦开始需要写东西的时候。
你就需要知道在哪儿塞入你的代码,这个我经常讲的就是学引擎跟学算法不一样,学习算法你搞懂了原理,你上来就可以去写对吧,你只要下载一个,比如下载一个direct open gl的案例,你改进行SHADER。
你看他效果就能出得来,但是的话先引擎的话,你首先得搞清楚,在那个代码,那个那个那个那个那一堆中间,我在哪去塞入我的东西,所以这个地方的话呢,我希望大家都给自己多留点时间好的,那今天的话呢这个不好意思啊。
我超支了,拖堂了,严重脱单已经整整两小时了,所以今天的话我嗓子也哑了,所以我今天就先容我告退,然后呢一个星期之后继续跟大家一起比干对吧,我们再去干一个暴涨物理的PPT给大家。
然后那个就是一个星期后见那个,谢谢同学们好。
06.游戏中地形大气和云的渲染(上) | GAMES104-现代游戏引擎:从入门到实践 - P1:GAMES104_Lecture6_Part1 - GAMES-Webinar - BV1au411y7Fq
(字幕提供:Sky Vision)。
Hello,同學們好,我是王希,歡迎大家回到那個Games 104,現代遊戲引擎的理論與實踐,那個又到了一週一次,我們大家互相比甘度的時候,課程組又爆幹了一周,幹出了這一節的課程。
那麼這節課程呢應該來講的話,我個人覺得是畫面最美的一節課程,因為我們這一節課程要講那個,就是我們大自然的一切,就是我叫Mother Nature,就是最漂亮的最好看的這個世界,但是呢。
就是我覺得這節課程呢,我寫完這個課件之後我的感受是這樣的,第一就是拓膽可能是一定的,應該內容太大,我實在沒有辦法把它壓縮在一個很短的課程中,但是呢我們總共只有四節講Rendering。
所以應該是個信息量蠻大的一節課,那麼聽懂呢我們也不能保證,因為裡面有大量的數學公式,然後這一次為了準備這個課件的話,我們很多公式都是這個現場去打現場去教研,說不定中間還有一個東西我們還沒查出來,那好。
那這節課我們在講什麼呢,就是說,首先的話呢我們這節課的內容就是講,我們如何把這個自然渲染出來,這張圖的話呢是換給大標客的,我個人覺得是非常的好看,它完美的詮釋了就是說。
我們所生活的這個planet的這個星球上面的,美輪美奐的這個世界,大家可以看到日夜變幻對吧,然後那個陽光天上的雲,然後下雨,樹木山川河流,真的是非常非常的美,所以這其實就是對於我們遊戲的這個。
研發者來講,尤其是我們Graphics Engineer,我們最大的一個挑戰,或者最讓我們興奮的東西是什麼呢,就是說,這個世界太美了,然後我們怎麼在虛擬的世界裡面,用零和一,把這個世界表現出來。
這件事情其實是非常非常痛苦的,經常是策劃說我要一個什麼東西,美術說我要一個什麼東西,然後下面的Graphics Engineer就會跑斷腿,那我們這節課呢,講的是一個Games 104的精神是什麼。
教大家如何做遊戲引擎,而不是教大家如何去,用現有的引擎做出這些效果,如果你要學效果是很簡單的,但是你要是做引擎的話,那我們就需要知道,它下面到底有什麼,那麼這個世界對這個世界的理解呢。
我們首先從觀察開始,這是大家看到的這一張,那個真實世界的照片,那在這個照片裡面的話,我們可以看到很多東西對不對,我們可以看到天空,看到大量的植被,看到這種河流,看到這種,就是這個大量的這種小溪啊。
石頭啊 亂石這些東西,那麼回到我們的故事的主角,大家還記得小明嗎,我講了上一節課基本上沒有提小明的名字,但是我們的小明同學還是非常想,把他那個能把《幹翻2042》的這個遊戲給做出來。
那他今天打開自己的遊戲,他看到的情況是什麼,哎呀 實在是差得太遠了,對吧 你看,我們好像很缺那個天空,以及天空中的雲的表現,而且呢,我們地面上的植被表現得非常的差,那我們呢。
還可能那個地形也繪製的特別的差,那這就是今天我們這一節課,要解決的問題,那麼好,我先從一個相對簡單的東西開始,先教大家怎麼去畫地形,這是一個油畫,我今天所有的section,我都是以這個油畫開頭。
為什麼呢,因為確實是啊,就是寫到繪製和渲染這一part的時候,人就會忍不住的覺得失信大發,因為確實是非常非常的美,而且從幾個世紀以前吧,上千年以前,我們的祖先看到這麼美人文化的世界。
他們就有一種強大的這種表達欲,比如說我自己個人是特別喜歡,像西班牙那個洞穴裡面的那個,就是那個原始人畫的那個岩畫,包括畢加索的那個繪畫也是受他的影響嘛,因為我覺得人類對這種自然界的這種喜愛。
那種表達是一種本能,所以當我自己成為了一個有性引擎的研發者的時候,我覺得這件事情是非常快樂的,所以這次這個課程的標題啊,我取成就是說,就是啊,是痛苦challenge,但是呢,又是樂趣去表達自然之母的。
他的美,那麼其實呢,在我們的遊戲的引擎團隊裡面,我們會經常會把同學們根據他做的事情不同,我們進行分工,比如說在我們的團隊裡,我們有一個有幾個同學,我們叫他什麼呢,叫大地之神。
就是如何你把大地上的一切表達的足夠美,那還有些同學我們叫什麼呢,叫天公之神,對吧,那就是如何把天上的天光雲表現的特別美,那這種稱號真的不是說我們編出來的,而是團隊自發給他取的。
因為我們這樣的這些技術apply上去之後,真的會讓整個畫面讓我們都非常的喜歡,所以呢,我們的第一趴先從如何做大地之神開始,那首先給大家上兩張美圖啊,就是這個是這個微軟的飛行模擬器。
大家知道最新一代的微軟飛行模擬器是喪心病狂,對吧,這個我忘了他的,他的那個整個package有多大,好像是接近一個T吧,就是你是沒有辦法把它裝到一個一個一張盤裡面的。
他是整個要不斷的就是你像買了這個遊戲之後,不斷要streaming data,他跟那個病的二次地圖整個連接在一起,像這麼大的一個世界,這麼多樣的地球的地貌,他能表達。
這其實就是遊戲引擎的現在對於terrain的彙整能力,哦,這裡面跟大家八卦一下,什麼叫terrain,terrain這個詞好像是這個古代英語中的這個就地球,Earth 地球之母的意思。
大家如果玩那個星際爭霸的時候,就知道有一個種族好像就叫terrain,就是人族,對吧,就是其實我還蠻蠻喜歡這個詞,因為這個詞總讓我回想到上古的神話,所以的話地形在遊戲引擎裡面,就是在遊戲的彙整裡面。
我們一般叫做terrain,那麼這是微軟的飛行模擬器,那我們這個技術只是在彙整地球嘛,那這裡面要點名另外一個遊戲了,就是無人升空,對吧,這個遊戲當年曾經是欺騙了我們很多人的感情。
但是我還是非常敬佩這個遊戲的studio,就是他們不放棄一直在往前去越做越好,那我們可以發現就是說這樣的一個技術,他不僅要表達Earth-like的這樣的一個世界。
我們還表達就是non-Earth-like,就不像地球的這樣一個世界,對不對,很alien的就是那很外星的地貌,比如現在大家特別想做那種火星地貌,對不對,比如說金星上的那種大裂骨這種感覺。
其實都會讓人覺得特別的fantasy,所以這也是我們的地形繪製技術要表達的東西,那麼就是Games10刺客的傳統精神是什麼呢,咱們先從最簡單的開始,如何表達地形,那麼最簡單的是什麼呢。
就是這個height field叫高層圖,那麼這個height field的這個東西,它不是什麼新的東西,其實早在幾十年前,對吧,我們人類還不會有這個計算機遊戲的時候,其實我們的社會。
它就已經能夠用叫counter叫等高線,它已經能表達出我們的地形地貌的高低的變化,比如說大家看那個過去的戰爭片裡面,那些將軍面前都擺一個高清晰度的這個沙盤,包括人造衛星對地球的掃描。
它也掃描出這種高層圖,大家看在這個圖的左邊,有一個用明暗表達的這個高度的圖,大家看這個圖像什麼呢,其實像不像那個,特別是它右邊的等高線圖,我相信大家仔細觀察,它像我們在以前學的一個什麼概念,叫做分形。
分形是什麼,大家都知道這個概念,就是它可以無限的放進去,無限的自我相似的這麼一個形狀,其實大家如果學自然界的一切,無論是一片雪花,還是我們的海岸線,還是我們的山脈的走開,它其實包括山脈上的這種腐蝕。
它都是符合分形的原則的,這個規律其實是非常有用的,因為我後面會講的,就是如何讓計算機,幫我們自動生成各種各樣的低貌,其實這個數學規律是非常有用的,那麼實際上的話,當我們得到了一個地方的。
它的高層圖的時候,實際上我們對它的渲染,就會變得非常的簡單,那麼這個就是這個Hide Field的話,這個技術非常的簡單,但是大家可能想像不到,如果它和紋理和光影去配合的時候,大家和材質配合的時候。
你看這個效果,這兩張圖是我從Artstation下載下來的,其實我自己也是非常驚訝的,因為在我的印象中,Hide Field是一個相對比較古老的技術,但實際上我發現真的是勢在人為,就是說你真的用得好。
它的表現力還是非常的強,這也是為什麼到今天,Hide Field還是在現代遊戲裡面,地形渲染的主力的方法,那麼拿到這個Hide Field,我怎麼去渲染呢,其實最簡單的方法,我們每個一米對吧。
或者每個半米,我做一個均勻的網格,那麼這個時候我把每個頂點,根據我的高層圖把它進行位移,實際能形成我們想要的一個地形的效果,對不對,是不是非常簡單,而且我在上面Apply它的各種,比如說高度它的材質。
這些屬性就可以了,但這個方法我相信我們的同學們,很快就知道它是有問題的,為什麼,如果我要表達一個很大很大的世界,比如說大家特別喜歡樂見的,叫開放世界,那麼這個方法顯然是不行,如果我們表達一個一公里。
那1000×1000,比如說一米一個格子,那我1000×1×2,那我是這個200萬個三角形,現在計算機覺得還可以沒問題,但是如果我要表達一個,幾千平方公里到上萬平方公里的時候,那顯然是畫不了的。
但是我相信就是說,大家很快就會發現說這個事情並不難,你看我們觀察這個地形,在近處可以看到無數的細節,遠處我看不到細節,那麼這個地方顯然就是有大量的,這個空間可以去優化,對吧,大家記得我們在前面的課程中。
給他一直在講一個概念叫做LOD,LOD其實怪我一直沒跟大家講,它的概念是什麼,LOD全稱叫Level of Detail,就是說根據那個我的觀察,它的這個它在我屏幕上,這樣的這個像素或者是遠近。
或者我對它的信號的敏感度,我可以設置不同的它的這個就是細節,細節精度,那麼顯然在這裡面是有Level of Detail的空間,但是不同於我們在前面去講的,各種遊戲裡面的object。
大家還記得Game Object的概念嗎,那這些東西我到遠處的時候,比如說我切換成一個更低精度的模型,沒有什麼太大問題,對吧,你就切就好了,但是地形它有個小細節,就是它是一路連續過去的。
待會我們會跟他講一個概念叫T-junction,所以說它的LOD是要用心去設計一下的,這裡面的話先跟大家講一個最簡單的一個思想,就是那個Mesh的Tessellation。
就是說我對這個網格進行不斷的細分,Tessellation這個詞就是細分三角三角網格化,那麼這裡面大家看到一個很有意思的問題是什麼,就是當我在遊戲中的任何一個時候,我看過去的時候,並不是360度看的。
對不對,其實我們看到的一個東西,只是一個眼睛看到的一個展開的一個追提,這個追提叫什麼呢,叫FOV,叫Field of View,我們會發現就是說,實際上我們真正關心的是在這個FOV裡面的東西。
而不是在FOV外面的東西,所以你可以發現就是這裡面已經給大家,就是提前洩露我們的方法的結果了,就是你會發現在FOV裡面的這些三角形,就會被很細密的去細化,我們會看到很多的細節,但是呢。
FOV外面的和遠處的,我們會把它這個三角形分佈的非常的稀疏,這個效果你其實是看不出來,因為我會保證就是說,在屏幕上每隔多少個像素,你看到的三角形,這個密度永遠是一致的,這個在數據上我們是可以做得到的。
那這裡面也跟大家講一個經常大家容易犯的一個錯誤,就是最早大家剛開始在寫這個,就是那個地形的Tessellation的時候的話,很容易會忘記一個變量,就是FOV就是視角。
因為就是說大家看到在這個圖的另外三個的話,你會發現就是它的FOV越來越窄,越來越窄,你會發現,為什麼當我的FOV越來越窄的時候,我的三角形會越來越細密呢,大家想想這裡面是不是有一個原理,其實很簡單。
就是說,當我的FOV越來越窄的時候,是不是在屏幕上,我們看到的效果是什麼,實際上是這個地形會放得越來越大,這個效果在什麼時候很有用呢,大家不是經常喜歡打這個,比如說我們打PUBG打吃雞遊戲。
吃雞遊戲中大家最想獲得的裝備是什麼,就是幾倍鏡三倍鏡八倍鏡,那這個三倍鏡八倍鏡zooming的效果是怎麼實現的,實際上並不是真的,我們做了一個光學的望遠鏡,實際上我們只改了一個很小的東西。
就是把攝像機的那個參數FOV變小了,這樣的話,你的這個在屏幕空間的話,一下子那個東西就放得很大很大,但是呢,你犧牲到的東西是什麼呢,是你看的視場變小了對不對,所以說會讓你的光眼睛更聚焦。
所以在這裡面的話就是說,當我們決定啊,就是其實不僅是這個地形,包括遊戲裡的物體,我要繪製它的時候,它的精度多少的時候,我們不僅要考慮它的遠近,還要考慮到它的FOV,就是以原則上來講,就是越高倍的望遠鏡。
它的FOV就越小,大家其實在現實生活也是這樣,你們可以試一下,戴上自己的望遠鏡,你會發現你觀察的角度會越來越窄,那麼這個東西最科學的一個解釋就是說,假設你的屏幕是同等像素量的話,那麼每一個三角形。
它在小的FOV下,佔的這個像素量就會增加,所以這個知識的話,我希望同學們一定要就是牢記在心,否則的話,你將來很容易寫出一些bug,好,那有了這樣一個基礎知識的話,我們其實就可以對網格進行簡化了。
這裡面跟大家講兩個基礎的原則,第一個原則,其實在上一頁已經講完了,就是說,我們採取近處密一點,遠處稀疏一點,FOV越窄,那我就密集一點,FOV越寬放,我看的那個面越寬的話,我是越來越那個。
就是說我也稀疏一點,那麼但第二個原則,其實是一個比較麻煩的原則,我們叫做Error Bound,就是說,這其實是我們在數學上保證說,當我對這些網格進行,無論是簡化合併的時候,因為我的採樣點變少了。
那我導致的定型高低之間的這個誤差的話,不要超過我一個給定的域值,但注意啊,這個域值實際上指的是在視空間上,也就是說,比如說你的誤差是0。1米,10厘米,那麼如果在距離你,比如說10米之外的地方。
你還是能注意到的,對不對,但是如果在距離你100米之外的時候,其實你注意不到,1000米之外的話,你可能根本注意不到了,對不對,那麼所以呢,我們要保證就是說在屏幕上,你的那個是不要超過,比如說0。
1個像素,或者是一個像素,對吧,理想情況下是只要不超過一個像素,一般人是注意不到的,所以這個呢,也是一個數學上,如果大家真的下去寫這個地形的這個adaptive tessellation。
就是說基於view的,哎呀不好意思,這個地方真不知道中文怎麼講,就是基於view的dependent的這個adaptive tessellation的時候,大家會把這兩個重要的原則引入,好。
那基本的方法論我們就知道了,對不對,我相信我們的Games104的同學們應該很聰明,應該能理解這件事情,接下來呢,跟大家講一個非常簡單的起活方法,就是到底怎麼去把這個三角形變得疏密相間,其實呢。
最簡單的做法就是三角形的鋪分,基於triangle的這個鋪分,那麼這個方法呢,也是一個非常經典的方法了,就是說,哎,大家可以看到就是我們一開始的地形是一個個的格子,對吧,我在格子中切一刀。
它就變成兩個等腰直角三角形,然後呢,它這個算法就要求說,如果你覺得你的密度不夠,你永遠在它的最長那一邊,等腰直角三角形,大家說最長的那一邊是哪,是不是直角對著那條邊,在那個邊中間找一個點給它切一刀。
那這一刀下去的話,大家是不是得到了兩個等腰直角三角形,對吧,所以它的整個這個算法的核心要求就是,你永遠把一個等腰直角三角形的最長一邊切一刀,這樣你永遠得到的是,就是二兩倍的那個兩個的新的等腰直角三角形。
那麼這個結構是個什麼結構呢,這其實是一個二叉數的結構,所以這個方法也叫做binary,這個triangle based subdivision的方法,具體的那篇paper的話呢。
我們在後面那個pdf那個link上會給大家分享,那麼這個方法的話呢,其實它會產生一個很有意思的細節,這就是我們在講我們在做地形的時候,這個大家一定要學會的一個黑話叫做T-junction。
這個詞聽上去是不是特別的高大上,實際上它非常的簡單,就是說當我兩個相鄰的三角形在同一條邊上,有一個三角形的話呢,這條邊沒有被切分,它就是一條邊拉直了,但是它另外相鄰的幾個三角形的話呢。
在那個邊上它拉出了一個點,那麼這個中間的一個採樣點的話,因為它中間就是它的高度會變化嘛,那這樣的話它會導致它兩個之間的這個就會產生一個誤差,就會你會看到地形上有個裂縫,對吧,那麼這個裂縫的話呢。
就是說如果大家在做這個就是地形的這種testation的時候,如果你不去處理T-junction的話,你會發現那個地形看著大致都是對的,但遠遠的總有很多地方露出那個白邊。
因為你露出的都是無窮遠的天空的顏色,所以的話呢,這個是graphics engineer很早就去鬥爭的一個東西,那它的算法難不難呢,其實也不難,其實非常的簡單,就是說如果你發現你邊上有鄰居。
這個它的對那個邊的切分比你密,那你沒辦法,你就開始把這個邊也給切掉,直到切到跟它的那個切分數是一樣就為止,這個具體的算法呢我就不展開,但是它基本的思想就是這個思想。
所以說因為一個最簡單的一個二叉數的結構,然後呢,我永遠用無數的等腰直角三角形,我就能拼出就是在前面那一頁大家看到的這個mesh,對吧,這個mesh的話就是一個很典型的,大家看到沒有。
那個高亮的區域就是你的view能看見的區域,那個黑色的就是你沒有看不見的,就這個view好像有點大,一般我們遊戲中的view沒有那麼大,這個view大概接近於已經快135度了,一般來講的遊戲裡面。
我們view很多時候做到大概70到80度左右,好那麼這就是一個最簡單的一個方法,但是呢,這個方法實際上在我們的遊戲行業用的不是特別多,那麼這裡面的話呢,首先這個方法是很有意思的。
就是說這裡面有一個有unity做的一個demo,這個demo的話呢,它大概是50乘50的平方公里,這個面積很大了,50乘50那就是2500萬平方公里了,2500萬平方公里了。
那麼它用這個tranql在GPU上直接跑出來了,所以這個方法本身的效率啊,繪製啊,都沒有問題,特別像這種一望無銀的這種地形的表達,但這個方法呢,其實是有一個很嚴重的問題。
就是說它無論是對這個地形數據的管理,包括它這個中間的剖分算法,其實呢,不符合我們在製作地形的一個直覺,大家想像一下,我給你一個很大的地形,你最天然的思想是什麼,你是把它切成豆腐塊對不對。
你是願意處理一群豆腐塊呢,還是願意處理像那個七翹板一樣,各種各樣的三角形,所以呢,實際上啊,在現代的遊戲中啊,大家用的最多的還是基於四差數的,這樣的一個地形的表達,這個方法就非常的直覺了,大家看就是說。
我們給你一個比如說128米,或者比如說128公里乘128公里的一個大地形,我就把它開始不停的切切切切切切到最後,比如說吧,很多遊戲引擎它是以512米乘512米,大概半公里左右。
為一個我們叫做一個block對吧,然後呢一個block呢,我在切比如說切成16塊,那麼比如說是一個64米乘64米的,我們說這是一個就是patch,就是各種各樣的,你這個名字隨便你取。
但是它核心的都是說符合這個四差數的結構,然後四差數呢,它的結構也是非常的規整,所以呢,我們呢可以對它進行就是各種各樣的就是說處理非常方便,那麼它還有一個很大的好處是什麼呢,你這邊的一個個的。
比如說我們一個block512乘512,大家想像一下,我們在計算機裡面存儲紋理是怎麼存儲的,是不是好像也是一個小方塊的texture,你見過什麼時候大家把一個三角形紋理往裡面漏的對吧。
那這樣就意味著是說,我有一半的存儲空間就浪費掉了對不對,所以說這個時候如果我用D塊的方法去管理我的地形,比如說我的height field呀,我的這個材質貼圖啊所有的東西的話。
是不是這個基於這種方塊的quad的方法,是不是更加符合你其他所有的數據的規範,實際上呢這也符合人對世界認識的規範,大家去看那個,比如說我們很多地方畫那個行政區啊,畫大家的分工啊都是打個子。
這符合人的natural,所以說這也為什麼Culture,是成為現在最主流的一種地形的數據表達方式,那麼它的那個算法呢,就這裡面有一個demo,你看這是一個用Culture表達了一個地形。
那麼呢最上面就是說我們是非常這個,很多很小的一個一個quad,這個大概可能是比如說是100多米乘以100多米,60多米乘60多米,但是呢你可以把它們兩個,四個四個一合四個四個一合。
你分到了那個最大的那個塊,那個塊在有的引擎裡面我們叫做block對吧,有的引擎叫做什麼patch,whatever叫什麼名都可以,但是呢你到這個至上的時候我們就不再合併了,一般來講的話呢。
這個就是一個非常那個規範的,一個就是磁盤上的數據塊,就比如說我把一個512乘512米的這樣的一個地形,它的head field它的貼圖,它的比如說植被啊樹木啊建築啊全部打包到一起,就是這個地塊我看到了。
啪我就把所有的數據load上來了,那麼你可以看到就是假設以中心點為中心的話,它的顏色一直在變化就表示,我在那邊對它細分的精度一直在變,所以這個方法的話,實際上大家如果真的在做自己的引擎的話。
我是非常推薦大家實現的方法是用quadray的方法,而不要用全構的方法,因為全構方法它只是一個rendering方法,但這個quad的方法呢,它其實暗含了資源管理的邏輯在裡面。
包括我們下面要講到的另外一個大名鼎鼎的,叫virtual texture對吧,就是虛擬虛擬紋理的這個方法的話,就是基於這個quad的方法去做的,好那麼其實呢,這個quad的方法呢。
跟那個三角形的方法也是一樣的,它也會產生這個T junction,就是這個地形的裂變,比如說我左邊的這個東西我切了四刀,對吧我右邊切了八刀,那四刀和八刀怎麼辦,那這個時候呢我要講一個很有意思的細節了。
這個其實是一個非常聰明的一個方法,就是它不再像那個三角形的binary tree的方法說,那不好意思既然你這個你這邊,已經這個切了這個刀術比我多,那我只能在自己身上再砍幾刀,保證我跟你的一致對不對。
這其實就意味著什麼呢,你要動這個幾何的turb結構,這件事情其實是很麻煩的,大家如果你如果真的寫過這個代碼的話,你就會發現這很麻煩,但是呢就有一個大神很genius的想了一個方法。
什麼意思呢就大家看我們的那個右邊的這個圖,假設兩個quad連的很近對吧,那麼你會發現就是說一邊切了四刀,一邊呢只切了兩刀,那他對不上了對不對,他提出了一個方法叫做stitching。
stitching這個詞的意思是什麼呢,就是吸附上去,大家你們在有時候在編輯器裡面,比如說大家如果用vso對吧,或者用一些寫powerpoint的,你會發現當你移動一些空間的時候。
當他靠近那個對齊的點的時候,他就會啪就吸上去了對不對,這個其實就是stitching,那麼這個方法是怎麼做的呢,其實很簡單就是你不是比我多了,比如像剛才一樣,你不是比我多了兩個中間點嗎,那我很簡單。
既然你要和我做鄰居,我這邊只切了這個就是說兩刀對吧,你這邊切了四刀,那你多出來的兩個中間點,你把它stitching到我上面去,大家看第二張圖就是,我先把上面的多出來的那個中間點,我把它移到上面去了。
那這樣的話實際上呢,這個三角形就是那個點,實際上和上面那個點重合了,你就變成了一個就是實際上是面積為零的,一個三角形對吧,它不會影響到這兩個之間的那個,這個就是watertight的,我們叫做水泥性。
這個三角形叫什麼呢,在圖形學裡面我們叫做退化三角形,這個大家如果寫,自己寫過這個圖形學的管線的時候,你們假設寫自己的Rasterizer,你一定要處理這種退化三角形的情況,就是面積為零,我怎麼去渲染它。
我到底是給它一個像素呢,還是什麼都不給呢,好像是,我記得好像是我以前的實現是啥也不給,我就不畫你了,因為你反正面積為零嘛,那麼如法炮製,下面那個多出來的那個切分點,我把它吸附到下面那個點。
其實呢這個你吸附到上面吸附到下面影響並不大,但是呢你這麼一吸附完之後,你發現整個這個Mesh就watertight了,大家有沒有發現,就是用quadtree的這個思路的話。
我去解決這個Tjunction,實際上是非常簡單的,就是如果大家寫過這個code就會發現,這個代碼是比剛才那個代碼好寫,剛才那個代碼其實挺麻煩的,而且你可能會切好幾次,假設兩邊的話。
它有一些很奇怪的形狀嘛,它有一個規則類表很麻煩,所以這是一個非常好用的實用的一個數據結構,那麼你有了這樣一個東西的話呢,同學們想去做這樣一個地形的話,理論上你就能表達出來。
這個的話呢好像是Far Cry的這個地形,對吧大家看到這麼漂亮的地形,它就是用quadtree去做的,怎麼樣,好像我成為這個大地之神,是不是覺得離自己並不是特別遠了,對吧,好我在講的這一part呢。
實際上是這個怎麼說的,是讓大家心安暖暖熱熱身,就大家覺得這個問題我可以學,好接下來呢我們要講一些真正高能的東西了,那麼好,那這個,這part還是比較簡單的,就是說OK,除了像剛才我用那個三角形。
我用規範的這個grid去表達地形呢,其實還有一種方法,這種方法用的其實不是特別多,但是呢我覺得在現代的一些前沿遊戲中,還是有人用,所以我覺得今天我來跟大家講一下就是這個,我用不規則的三角形去表達地形。
就是我首先地形我還是用Hide Fill做出來,它的密度非常高對吧,但是呢你會發現如果我的地形中,有很多的區域是平的,你無論用那個grid還用什麼方法,我還是會浪費很多三角形。
它索性呢就是用Mesh Simplification,就是面片簡化的方法,我把一些不必要的頂點全部簡化掉,但是我會把一些頂點,把它align到這個feature上,大家可以看到就是說。
對於這樣的一個就是沙漠的這種地形的話,有大面積的平的區域,那麼它其實用到的那個頂點數的話並不多,這個右邊就是它簡化完的這個網格,那麼這個方法呢其實,我看到最新的用處用在哪兒呢。
是用在那個好像是《現代戰爭》吧,《Mortal Warfare》裡面,就是它因為有很多在沙漠地區作戰,它發現就是說無論用剛才的那個三角形,還是Cold Tree的這個方法,其實都沒有意義 對吧。
我提前就把這個地形給你簡化好了好不好,我就 你看可以看到就是說,這是它簡化完的一個結果,這個面積其實很大,你會發現它中間有很多很大的很長的三角形,你不會發現它很多的頂點簡化完之後。
很巧妙的正好align到那個,一個個突出的山脊上面來,這個呢大家以後後面,學那個就是幾何的簡化的時候,就是Mesh Simplification的時候,大家可以學到一些算法去解決它,這裡面我們不展開。
那麼這個事情非常有意思,就是說這個方法它呢實際上很麻煩,你需要做預處理,而且呢你實際上是不能,就是你在Runtime的時候是很難對它進行調整的,但是它有個好處是什麼呢,就是它在很多情況下。
畫的三角形數量,比我們剛才前面講的兩個方法要少,你比如說在這個,他們自己取的這個例子就是,如果他們用這個就是,我們的這個Mesh的,就是Cold Tree的LOD的話,它大概要畫50多個面。
它自己畫的面就比那個要少很多,幾乎少了接近一個數量級,所以你會發現就是遊戲引擎設計啊,它為什麼比較難,就是你根據你不同的內容的需求,它確實它的算法一直在變,那麼這個就是非常有意思的一個算法。
我其實這裡面我想考大家一個問題,就是說,為什麼我那邊也實現了,就是這個View Dependent的採樣,為什麼我最後的三角形數量比它還要多呢,對吧,這個其實挺難,但簡單來講的話呢,實際上是。
你在那邊的採樣是一個叫等間隔的採樣,它不能保證我的每個採樣點,正好align到你的這個數據中的信號中的這個,就是什麼呢,就是我叫做,就信息量比較大的地方吧,這個真的不知道怎麼用簡單的語言去想,所以呢。
它的採樣率,它的採樣效率肯定是低於,你為這個特殊信號定制的這個採樣,這個其實大家如果學那個信號和系統的話,是能夠知道這個概念的,但是這個方法的話呢,我覺得大家只知道就好了,並不需要真的去實現的。
因為我看了一下,好像只除了幾個特殊的遊戲會用它的話,一般來講大家都不會用這個技術,好,這些呢就是我們的地形的方法,那有了剛才那樣的一個Culture表達的時候,大家很天然想到的東西是什麼,誒。
我能不能用現代的這個GPU,對吧,從我的Rendering的第一節課我就大講特講,現在的GPU確實是我們作為一個Graphics的Programmer,for game engine的話。
我們最好的夥伴,最好的戰友就是GPU,就是顯卡,那麼顯卡現在提供了大量的這個就是說,在這個Runtime幫你去做幾何的細化生成的東西,所以呢,實際上現在遊戲引擎啊,基本上都是用GPU based的。
就GPU driven的Test solution的方法,在很古老的時候,十幾年前,二十年前的時候,剛才大家看到這些網格,真的是要我們程序員全部build好,然後呢。
把頂點想個辦法在Shader裡面hack一下,然後呢一個個的一個一個一個把它拼起來,但是現在的話呢,基本上全部是在GPU裡面自動完成了,那麼這裡面的話呢。
講GPU based的Test solution的話呢,就不得不提提我們大名鼎鼎的,從DX11來的這個叫做Hole Shader,對吧,Domain Shader,還有Gemmage Shader。
實話實說啊,這個實際上是我個人最不喜歡,那個DirectX或者上一代的圖形Driver的地方,因為這幾個,首先從這幾個Shader的名字,我就覺得特別的反人類,實話實說我每一次只要我有幾年沒碰它的話。
我就已經完全忘了這個,哎呀Hole Shader到底幹什麼的,這個Domain Shader幹什麼的,對吧,Gemmage Shader幹什麼的,其實非常的抽象,那麼實際上呢,他們做的事情呢。
實際上是為了我們做這個Subdivision Surface,去做的一個東西,比如說你像那個Hole Shader的話,它實際上是生成了一個Subdivision用的一個Patch,那這個Patch呢。
就是Patch你可以理解成就是一小塊的這個這個三角形,或者不叫三角形,就是一小塊的起合區域,這個區域呢,它是有一些控制點,控制,就是這樣的話,我能夠劃平為凸,對吧,就是比如說我一個一個Cube的平面。
我可以變成一個很光滑的球面,同時呢,它這個Shader還要寫兩份,一份是告訴各個Control Point的數據,那麼還有一份是什麼呢,就是我現在看到的這個起合形體,如果你是三角形也好。
如果你是一個Quad,是個四邊形也好,你得告訴那個Tessellator說,你把我的邊Tessellated多少次,然後呢,這個時候交給一個硬件的固定排法叫Tessellator。
它會把這個QuadTessellated成很多的細密的三角形,如果看這個圖的往右邊走一點的話,你看到那是Tessellated後的結果,這個時候呢,就上了一個著名的叫Domain Shader。
這個名字實在是,我個人覺得是真的是莫名其妙的一個名字,然後呢,它其實幹了一個事情是什麼呢,就是說,你這些點,你的新的插入的這些頂點全部拿到之後,我可以根據比如說我採樣一個高度圖。
我把這頂點的位置移動一下,對吧,這樣的話我就能形成我們想要的那樣的一個起伏的東西,其實呢,這個時候它後面還有一個東西叫Geometry Shader,什麼意思呢,就是你這樣已經被動過位置的頂點了。
它再送到它的下一道流水線,在這裡面幹嘛呢,其實呢,就是把我們經典的Vertex Shader那些東西再算一遍,比如說我的Texture UVR,我的一些需要傳遞到每個像素的一些數據再走一遍。
其實我個人是非常不喜歡這三個名字的,我自己經常覺得那個Geometry Shader,我更願意叫做Post-Tessellation Vertex Shader,對吧。
就是Post-Tessellation Vertex Shader,對不對,我也一直不理解為什麼你要把Domain Shader和Geometry Shader分成兩個Shader。
反正就是這個事情讓我痛苦了快10年,所以我每一次只要不寫這個代碼,我基本上就忘記了,但是呢,你還不得不用,為什麼,因為你一旦要做地形,還有做一些高級的東西的時候,你還真的離不開它,但是呢,非常非常感謝。
最新一代的GPU的發展,終於這個世界人民喜大普奔的事情發生了,就是說我個人非常蠻喜歡的這一代的這個Mesh Shader的概念,就是一個Mesh Shader,它基本上把剛才所有要講的活全給幹完了。
就是它你就告訴我說,你要什麼東西進來,好,我知道了,那我生成一個一小塊,它叫做Mesh Slit,然後呢,就一小片頂點三角形,頂點三角形該怎麼插織,該怎麼塗包,你就讓我去寫就好了,對吧,我就相當於是說。
這個一個Mesh Shader,把它從最早的這個Hole Shader,一直到後面的這個Geramic Shader,其實包括前面的Vertex Shader,全部看完了。
包括那個Tessellation,我們也說了,硬件你就不要做了,你的Tessellation算法我也搞不清楚你怎麼Tessellate對不對。
我們自己既然能當這個遊戲引擎的Graphics Engineer,這點數學我們還是沒有問題的,所以全部被我們拿走了,所以呢,我自己個人是熱切的期盼,就是說我們的玩家的電腦快點升級,就是全面的支持這個。
這個就是說Mesh Shader,但這裡面就是有個細節,就是Mesh Shader必須是DX12以上,那麼這就來了一個我們很頭疼的問題,就是說大家知道,當同學們的就是玩家的電腦裝成那個Win7的時候。
它是不支持DX12的,然後呢,只有到Win10的時候才能支持DX12,所以我們每天在看一個數據,就是說Steam那個統計數據說,有多少玩家升級成那個就是Win10了,那我自己一直在講就是說。
但這個數據只要降的足夠低了,我不管了,全部升DX12,實在受不了那個很傻的那些東西,所以呢,其實從這裡面上面也可以看得出來,就是說其實我們作為一個引擎的開發者,你會發現就是我們會密切的和硬件的研發商。
包括我們底層的SDK,就是Driver這一層的這個開發商,在一起去配合的,然後大家呢,越來越把這個Flexibility開放給我們,然後我們就可以在硬件上實現非常多很好的算法。
所以大家如果要做Turing的話,那你是一定要對DX11的那個就是Pipeline,以及Mesh Shader Pipeline,一定要花時間自己摸一摸,但這個難度其實並不大。
大家網上有很多的公開的代碼,而且它的原理也蠻簡單的,好,我只是藉這個機會順便吐槽一下那個DX11的那個Pipeline,我真的是非常非常頭疼那個東西,好,你有了這個東西之後。
為什麼我要講這個GPU Driven的這種Real-Time Tessellation,生成的Turing非常的重要呢,大家注意到就是我們前面講過,就是在進出的我的Turing會不會生成的非常的密對吧。
遠處很疏,這個時候如果我所有的頂點的位置都是在Runtime。
在Shader裡面自動的去調整的時候,其實我們就可以做一件非常酷的事情了,就是這個Real-Time的Deform Motoring,就是我的地形可以有動態。
那這裡面有一個很著名的就是那個拖拉機駕駛的例子,大家比如說我記得好像在歐洲Steam上有個很著名的遊戲,好像就是那個農場的模擬,還是拖拉機駕駛的模擬,這個最重要的一個效果是什麼呢。
就是我在一片水稻田裡面,我這個拖拉機開過去對吧,我得去開出很多溝出來,就是我的路會壓出很多的溝,那這裡面其實呢,它的方法其實非常的簡單,就是我假設地面一下,每一個一個個小彈簧,我一旦受到壓力的時候。
誒我的彈簧就壓下去了,同時呢我還把一點點的物質往上擠,其實這個模擬呢不用做的特別複雜,可以做的很簡單,但是呢你就可以看到一個,誒這個拖拉機開過去就有很難效果,這個效果其實啊。
我個人認為就是如果大家做現代的遊戲引擎的話,我是強烈推薦大家把它實現了,為什麼呢,因為這個方法的它的基礎,就會讓大家看到一個你們特別喜歡的效果,來我來揭曉一下是什麼效果,大家看出這是什麼遊戲了吧。
不用我介紹了,大名鼎鼎的對不對,那麼它最這個,它跟虛幻5引擎包裹在一起,就是我們現在虛幻5的能力很強,其實這裡面的這個,Deformable的這個Snowground的這個效果啊。
實際上就是Dynamic Turing的方法,但是呢它具體的實現方法就很多不同的,那麼比如說吧,比如說我圍繞的這個我自己的周邊,我有一個有一個地方,我生成了一個。
Deformable就是Turing Deformation的Texture,那在這上面發生的所有的打鬥啊,我踩的腳印啊,我都會在這個Texture上記錄下來,當我自己移動的時候。
這個Texture也跟著我走,但是我會保證它的數據一致性嘛,然後這個時候,只要我的這個地形這些東西,它全是Real Time的Tessellation出來的結果的話,其實我再加上一層Offset。
當然了我這裡面還有很多的Hack,比如說我讓材質看得更好呀,我要加上很多粒子效果,但這些都是細節,但這不重要,重要的是,你的整個地形系統,都是用這個GPU Tessellate的,然後呢。
你能夠在Runtime的時候,就是在遊戲中,給它加各種各樣的變化,比如說大家想象一下,一個炮彈砸過去,砰在地上挖了一個大洞,對吧,這種效果,是不是我們小明想做現代戰爭遊戲,是不是也很想要這個效果呢。
當然這裡面還有一些更複雜的問題啊,比如說,像雪地它為什麼好做呢,因為雪地呢,只是Visualize,或者說會減慢你的速度,但是你的人的高度,不會因為我在地上挖了個洞,我就下去了,剛才我講的那個炮彈。
在地上打了個洞呢,那個東西稍微有點麻煩,為什麼呢,你要更新它的這個物理碰撞,否則的話,你會發現一個現象就是,我在地上挖了個半米深的洞,你發現人在走的時候,他還在那個虛空中走過去,對吧,那這裡面的話。
你要真的去做的時候,還有很多其他的細節,但是我這邊的話,特別想跟大家講這個東西,就是說,你會發現就是,就是做遊戲引擎的人,有一個很快樂的一個事情,就是說,你看到所有厲害的牛逼的遊戲,你首先是佩服它厲害。
第二件事情就是說,哎,我想想看我怎麼去做這個效果,所以這種過程是非常有樂趣的,好,那麼接下來的這一part呢,就是,就是更有意思了,就是說,大師這個自然界啊,它不只是高度的這樣的單一的。
就是我們叫做只有一個單一的數值的函數,對不對,我們地上有很多洞,其實包括我們的懸崖,有這樣很多反向的峭壁,對不對,那這些東西在我們的定性中怎麼表達呢,首先跟大家講一個最簡單最土的方法。
就是我直接放個物體上去,比如說我不是要做懸崖嗎,我這山起來之後,在以前的遊戲引擎裡面,其實大量的時候,大家只是在那邊插了一個物體,這樣的話,讓你看那個山的話,哎,好像有倒溝有懸崖的感覺。
但這個方法的話呢,現在呢,也在慢慢的在被優化,跟大家講一個分享一個很小的一個有意思的一個小hack啊,這個是那個啊,哎,我忘了這什麼遊戲了,那個這個遊戲的話,它的做法,我覺得很聰明,就是呢。
當artist說我要在山上開個洞,比如我要修個隧道,對吧,這是很常見的,對不對,我過公路,穿穿過一座山,我要挖個隧道,大家如果這個山是海底隧道,它整個都是watertight,都是水面性的,那我完蛋了。
對吧,我就看見面前擋了那個一個山的一部分,他呢,用了一個很巧妙的方法,就是我把我要挖掉的地方的頂點做個標記,這樣的話呢,我在我的shader裡面,vertex shader裡面,我輸出它的位置的時候。
輸出一個就是num,就是nan,那那是個無效整數,這時候現代GPU就很聰明,他說,哦,你這個頂點的position是一個無效數的話,那它就把那個頂點所有用到這個頂點的三角形全部幹掉。
這個裡面又用到了剛才我講的一個概念,這個三角形其實是一個退化的或者是無效的三角形,你這樣的話,事實上就可以一片一片的把你的地形上開出了一個洞了,對不對,但這個洞其實呢,它不好看的,zigzag很難看的。
就是那個zigzag的意思就是一折一折一折的,但沒有關係,我們的聰明的artist,他可以拿一個物體,比如說他把那個隧道做成整個模型,往裡面一插,噗,你這時候就能看到一個隧道的效果了。
所以這種小技巧其實說,為什麼我想就是大家做,今天我們這門課一直跟大家講,就叫理論與實踐嘛,就是說理論上的how to fill是非常簡單的,大家很容易理解,包括大家知道各種算法。
但是你真的把這個技術運用在現代遊戲的這個場景的時候,事實上你有很多地方需要注意,好,那接下來這一part呢,就是純屬我個人的私貨了,首先我給大家聲明一下,就是我接下來講的這一part的話。
好像在現代遊戲引擎裡面,大家用的很少,但是呢,我個人為什麼特別希望在我們的課程跟大家介紹一下呢,因為我待會會去講原因嘛,首先大家想一下,如果我們的地形假設用體速化的方法,就是volumetric的方法。
就是在三分空間上我踩一堆的點,對吧,那我是不是就能解決剛才我講了,我打洞啊,各種奇怪的結構的問題啊,對吧,都可以去做,因為你那個打洞你中間還塞物體,但是如果我這個世界就是體速化的表達。
我是不是可以自由自在做所有的事情啊,對不對,好,那我的三分空間,我在每個點我存一個值叫全重值啊,就是那個比如說0到這個多少,0到16這個值,那麼這個值的話呢,其實代表這個空間有沒有物質以及物質的密度。
這個時候呢就引入了一個大名鼎鼎的算法,叫做那個Martin Cube,這個算法實在是太有名了,大家如果有興趣的話,去查它的原文,這個原文也是有30到40年的高齡了,那這個方法呢其實非常的簡單,他說啊。
如果你在空間上有這些works的採樣,我其實可以找到一個它的等值面,就是這個當然講起來比較複雜,簡單來講就是你每個頂點的數據的時候,我可以在你上下左右找8個那個點,然後呢我就有大概14種方法。
去切分這個Cube,然後形成一個水密的一個三角面片,及把我這個形狀表達出來,這個方法為什麼這麼有名呢,就是大家如果做過那個CT掃描,就是掃描我的身體,那麼你可以掃,其實掃描出來的數據它是一個個的點。
最後我們為什麼能看到一個形狀,實際上就是用這種方法去生成的,包括就是在那個比如說模擬中間,比如說空氣動力學,比如像這裡面螺旋槳攪起來,那麼我們可以在空間上看到一個壓強場,那我怎麼去或者叫速度場。
我怎麼去visualize一個螺旋槳,在空間攪出那個速度場呢,其實你也要用這種volumetric representation,再加上matching cube的方法把它表達出來。
那麼大家現在去講那個,比如說虛擬人數字人,大家都覺得是很漂亮的小姐姐,很漂亮的東西對不對,我這裡面給大家講一個,可能會影響大家食慾的東西,其實真正的最早的全球最早的那個數字人,如果我沒有記錯的話。
應該是大概是20年前,美國有一個研究機構,把一個死刑的犯人經過他本人的同意,迅速的冷凍下來,然後用那個磨的機器,每隔大概是好像是一毫米還是幾毫米,我忘了磨掉一層拍一張照片,磨掉一層拍張照片。
那大家想想看,我把這麼多層的照片每個像素疊在一起,我們得到了是不是一個人體的體絲化的一個表達,對不對,那這個時候我們就要用大名鼎鼎的matching cube的方法,把這個人從表皮到你們的每個內臟。
每根骨頭全部表達出來,這個是非常有意思的,所以,所以怎麼說呢,就是這個是一個非常重要的一個方法,matching cube,那麼當然了,這個方法如果真的用來做地形比較複雜。
現在相關的研究工作也是非常少的,就是比如說吧,我不可能所有的這麼大的一個地形,我都是用一個同一個精度,我肯定是也是要近出密遠出小,那麼這個疏密相間的情況下,我們怎麼去保證它的水密性。
那這裡面的話就有人做了這個工作,大概是有100多種的情況,但是看上去很複雜,其實對顯卡來講很簡單,他就查個表就完事了,那麼這個方法為什麼我是特別想講呢,因為這可能跟我個人的一個fantasy有關係。
那這裡面就介紹一個大家大名鼎鼎的這個minecraft,對吧,這這簡直是宇宙number one的遊戲啊,那麼這個為什麼這個遊戲特別火,就大家可以自由的在這個世界裡面去創造,其實啊。
我我看今天的3A遊戲啊,其實有個問題就是,你看著它的畫面很漂亮,對吧,但是它的自由度很低,就比如說在戰地裡面,你看到一個地上的這個這個這個塑料做的一個牆,你都打不破,對吧,你也沒辦法去挖賬好。
這個說實話,我覺得what is game就是說,雖然我是我是我是很喜歡做rendering啊,但是我是覺得遊戲它本身是具有互動性的,是允許玩家去創造的,所以我覺得這裡面的話呢。
覺得我覺得這種volumetric的表達,大家可以去研究可以關注一下,但是我to be honest就是說,我覺得現在的算法還是非常的不成熟,但是呢,我覺得我們keep in mind。
就等著下一代的硬件啊,包括現在有一些前沿的算法,包括我也看到了一些很前沿的工作,就是說他們是能夠做到叫全動態地形,真的你可以在地上打個洞,挖到敵人的背後偷襲別人,我覺得這個真的很酷,所以我覺得呢。
就作為既然我們是課程嘛,我希望給同學們建立一個更廣泛的一個知識體系,所以我希望同學們關注一下這個方法,好,這個地方純屬我個人YY,不屬於行業的這個典型的解決方案,嗯,好,那有了這樣的一個地形啊。
地形我們有了這個幾何的表達,接下來一part是什麼呢,我得給它上色了,就上材質了,那麼這也是一幅油畫,你大家可以看到就是,這個幾百年前我們的畫家就已經非常厲害了,對吧。
大家看到這個地形是非常的漂亮非常的複雜,有很多很多的顏色在一起,他們在不停的在混合,這樣看上去就才是比較自然的一個東西,那麼實際上有一個真正的三頁遊戲的要求的話,那我們地表的材質量是非常非常大的。
比如說這裡面是ghost recon吧,那麼他自己統計就是說,他大概有十幾種的這個生物群落,有將近140多種的自然材質,在這個世界裡面去混合,你才能看到我們這個自然界的richness。
但實際上這個數字啊,也是做了極大的簡化,我們真正的這個mother nature,就是自然之母的話,比這個要強大不知道多少倍,所以我覺得做遊戲的人,他實際上是很有敬畏之心的,就真的知道這個世界的美妙。
那麼怎麼去解決它,我們先用最簡單的方法開始,對吧,我們永遠還是從,那麼首先我們的地形不就是各種材質嗎,好我們在上一節課跟大家講了,各種各樣的材質模型,假設我們覺得這個PBR非常好。
我們就是用那個MR的這個模型,就是那個Metallic Roughness這個模型,那我就存它的base color,存它的法像,存它的這個Roughness,就是它的這個粗糙度。
但是Metallic我也作為一個,Channel Alpha Channel Codec,到那個比如說base color這個圖裡面,那這樣的話當然這裡面還有個細節,我還存它的高度圖。
高度圖待會會講有什麼用處,那麼好,那我大概有幾種材質在一起的話,我還有個叫什麼呢,叫Splat Map,就是混合貼圖,這個貼圖就是每一個Channel,對應了一種材質的權重。
那我們就可以通過Artist的畫一些筆刷,刷刷刷刷刷,誒,我們就可以把各種各樣的材質混合在一起,下面的那個圖大家看到了就是,這個非常的難看啊,就是我都不知道這是什麼東西,但是呢,它確實很好的解釋了。
什麼叫做材質混合,這就是最簡單的材質混合,但這種材質混合呢,就是它每個人渲染的結果,我把它按一個Alpha混合在一起呢,這種方法其實呢,是有問題的,大家看啊,在真實的世界裡面,我們會發現就是。
它的各種材質是有它一定的邏輯的,比如像這個裡面,我一個沙子逐漸向石頭過渡的時候,如果你用Alpha混合的話,你可以看到一個很柔和的區域,但是那個非常的不真實,你感覺就像在石頭上面蒙了一層沙子。
那個沙子的話呢,是浮在那個石頭縫上面,對不對,那麼其實這種情況和我們真實觀察到的情況不一樣,你比如像這邊,誒,它這個,你會發現那個草,雖然草和石頭過渡的地方,它是先從石頭縫之間蔓延過去的。
而不是直接長在石頭上面的,這個邏輯上是很簡單對吧,那這個時候,我們的那個Height Field就起了作用,聰明的這個Graphics Engineer就想出了一個著名的hack,誒,這不是很簡單嗎。
我就在你的過渡過程中間,如果我發現我需要混合兩種材質,我非常簡單,我呢,把你的這個Height,用你的權重去做一個調整,然後我就比較說,你的Height高,那你的權重就下降的慢一點,對吧。
你的Height低,你很快就退掉,這樣的話呢,我就能夠實現那種石頭,好像那個沙子好像入侵到石頭裡面,但是呢,又不會長在石頭上面的效果,所以大家仔細看這個圖段,你可以發現比剛才這個來回比較一下。
是不是感覺自然的很多,對吧,就感覺沙子出現的縫隙,就一個簡單的Height Map,一個簡單的,就比大小的計算,我就能形成這樣的一個效果,這個效果其實是非常好的一個效果,但這個效果有一個問題就是說。
它在兩種顏色的切換,就是兩種材質的切換,它是一個靈異切換,這個靈異切換的話呢,你再清楚看問題不大,但是呢,當你的相機在移動的時候,對吧,你會發現這種這個信息可能很高頻,它就會有很多抖動,當你在遠處。
比如說你很低的視角看這個地形的時候,那個地方呢,那個分間線反而會顯得比較sharp,那這裡面的話呢,這個我們又發揚了這個,Real-time Rendering的精神,就是一切都是Hack,對吧。
那我們就這個又來了一個大名鼎鼎的Hack,就是大家加了一個Bios,所以這個這個遠代碼是我從原作作者上考的,其實我個人不喜歡它那個,它叫那個叫什麼叫Depth,我覺得那個就是個Bios嘛,就跟大家。
我在上一節課我們跟大家講那個Shadow的時候,就講過,就是凡事不舉加Bios,就加一點點擾動,它加了個0。2的擾動,這個擾動呢,它用了一個數據Hack,這個數據Hack簡單來講就是說。
當我們兩個的這個這個加權的高度差,在0。2之間的時候,咱哥們呢也不要就是這個要麼是你的,要麼是我的,咱兩個呢用這個權重做一個差值,這樣的話呢,讓它的過渡區域啊,還是有一點點的Abido的混合。
就是它的那個顏色的混合,這樣的話呢,它看起來也是挺自然的,第二個就是說呢,它的效果看上去也會更穩定,所以這個呢,其實是一個比較常見的這個Texture Splitting算法。
就是但這個是一個很小的一個細節了,就大家如果自己寫代碼的時候,你可以試一下,不加Bios和不加Bios效果,還是有一點區別,那麼我們在這個課件中的話,也提供了原作者的這個link,大家可以去看一下。
其實就是簡單的幾行Shader代碼,好,這就是Texture Splitting,那麼在實戰中的話呢,實際上沒有那麼簡單,我們沒有沒有只有三四種Texture那個材質,實際上在一個真實的遊戲中的話。
我們動輒就是幾十種甚至上百種材質,那怎麼辦呢,我們在現代的GPU中,其實這個方法呢,也很簡單叫Texture Array,就是說我們把所有的這個,比如說它的顏色的紋理,把它pack成一個。
一個就是array的意思就是,我下面有一個一個一個的Texture,那為什麼叫Texture Array呢,大家可能聽說過兩個特別容易混淆的概念,一個叫做3D Texture。
一個叫Texture Array,這個同學們經常會把這兩個概念混合在一起,但它倆區別是什麼呢,就是3D Texture,你可以剛才我們不是講到那個volumetric的表達嗎,提速的表達。
3D Texture的它實際上,當你在對它進行任何一個點進行採樣的時候,它在當前的Mipmap,就是當前的進度下,它是要對上下左右前後八個點都要進行採樣,你可以理解成就是,我很可能會落在就是這個。
比如說我在平面上看到的XY對吧,我3D Texture我下面還有一個Z對不對,那我在任何一點採樣的時候,我可能不會落在那個標準點上,那我就我要在我的上面那一層,採四個點進行一個Binar的差值對不對。
然後呢,誒我下面的那個那一層的Texture我也得採,又進行了一次Binar的差值,然後這兩個差值的結果呢,我還得再做一次差值,才能成為我的Texture值,所以3D Texture呢。
它是一個Tri-linear的Interpolation,所以呢,它的採樣是比較廢的,而Texture Array的意思是什麼呢,就是你雖然是很多層Texture疊在上面去了,但是呢。
層和層之間是沒關係的,所以它的採樣的時候呢,它就不在那個那個Z軸呢,就不再叫這個XYZ了,對吧,它叫什麼呢,它叫Index,就是你告訴我你是採第零層的,還是第一層第二層,你千萬不要跟我講說你採1。5層。
不好意思,哥們我不處理的,你得準確的告訴我,你採哪一層,這個是不是完美的符合了,我們在這個表達這個地表材質,對吧,我有30種40種,它們之間是沒有關係的,所以對於這個混合的時候。
我實際上我的Splitting Map呢,我會存兩個東西,一個呢,是我的這個權重,這是做混合用的,其實還要存一個什麼呢,就是我到底用了哪些材質的Index,然後我拿了這個Index的時候。
我就在那個就在裡面插表說,你用了第035號材質的這個點,好,它的權重是0。3,你又用了第13號材質,對吧,它的權重是0。7,好,我們在這裡面給你混合一下,這個方法是不是聽上去很簡單很直覺。
大家如果寫過Shader Code的話,應該就知道我在講什麼,並不是很複雜,所以基本上呢,就是在早期的,Torrent會長會智中的話,我們一般都會用Text Array,去把那麼多的地表材質。
剛才那個大家我剛才講了,Ghost Recon裡面,它不是140多種這個地表材質嗎,其實我一個幾組Text Array就全部搞定了,對吧,就也不像大家想的那麼難,好,那其實呢,剛才講的都是最基礎的渲染。
這裡面我給大家順便再提兩個概念,就是說,在這個現代遊戲裡,有兩個很著名的這個就是,這個繪製的表達,就是我有個法相貼圖的時候,我會形成什麼,明暗相間的凹凸感,對不對,這個時候大家眼睛已經發現了。
就是其實我們有什麼呢,叫視差貼圖,視差貼圖呢,其實它的方法呢,其實也比較簡單,就是說,我們認為假設那個地表下的幾何,它是有凹凸的,那你當前眼睛看過去的時候,因為它的空間位置是不一樣嘛,你會產生視差。
所以說如果你看到的,比如說是0。3、0。5這個點,但你的射線在斜角看下去的話,你實際上應該看到的不是0。3、0。5,很可能是0。32、0。51,那麼我的這個Offset呢。
我是根據位移序跟那個下面的幾何Height進行,它實際上是用那個Remarking的方法,就是往前走小步小步的方法去渠道,那我就會產生一個更加強烈的立體感,大家看這個Parallax Mapping。
你是不是覺得,它好像更有立體感了一點,你想想看我們地表上如果做了很多小石頭啊,對吧,這個小的雜草啊,如果我加上這個Parallax效果,是不是看上去更漂亮一點,這是很古典的一個做法。
那麼它的這個Drawback是什麼呢,第一個就是,它的每個像素的那個運算稍微要貴一點,因為它要往前走幾步要測一下,那麼第二個呢,它只能夠產生這種視覺上的這種凹凸感,但是呢,你如果仔細看那個幾何的邊界。
它還是像那個刀切過去一樣的,光滑的,那麼另外一個更徹底的方法叫什麼呢,叫Displace Mapping,就是剛才我不是講了,現代硬件做Tessellation非常方便嘛,對吧。
我大不了就是在進出把你的網格變得非常的細嘛,沒問題的,我搞得定的,然後我根據你的Height把你的地形給你變掉,其實呢,我們現在看很多遊戲啊,大部分遊戲實際上還是Bump的匯合,但是呢。
已經有越來越多的產品在試圖引入就是這個Parallax,或者說那個就是Displace Mapping,現在的在整個Turing中用的話呢,我見到的不多,但是呢,我個人認為這可能也是個未來的一個方向。
所以給同學們去介紹一下,好,那麼,這個方法其實非常的簡單,非常的直覺,但是大家想一想,這個東西真的在遊戲中用的時候會不會有問題,其實它問題就出在什麼地方呢,大家還記得我們在第一節課講渲染的時候。
講過一個東西叫什麼,叫Texture Sampling is Expensive,就是紋理採樣是很麻煩的,我採樣一個最簡單的2D Texture,大家想想什麼,要進行這個7次差值對吧。
這個經常可以來考大家到底幾次差值對不對,我採一個最簡單的8個點要進行這個7次差值就很麻煩,那麼實際上的話呢,如果我這時候有4到5種材質混合在一般是4種啊,在一個點上4種材質,那我這個數量就全部乘上去了。
我還有一大堆的這個各種各樣的運算,實際上這個運算為什麼昂貴了,就剛才大家看下面這個場景啊,在這個場景中只要你能看到地形的地方的每一個像素,你都得衝上去,把這些這個十幾張Texture一路的採樣一遍。
然後呢再加上各種加減乘除混合運算,所以這個其實會非常非常的慢,和非常非常的費,但是在早期的時候呢,我們還真的就這麼幹,對吧,就是所以的話呢,這個Train Rendering有的時候。
在早期的那個引擎寫的不好的時候,其實會寫的非常的非常的慢,就是你會把那個Texture Pipeline給的壓力非常的大,因為剛才我講了用Texture Array的方法放在那對吧,這個方法是很好。
你覺得很簡單,但實際上我跟大家講過就是,其實現代的無論是那個GPU還是CPU,它骨子裡面還是這個圖靈機的設置,這些數據它存在那個存在那個就是顯存上的話,你可以認為它是一個二維結構。
它就會經常的來回去尋指,就噠噠噠來回跳,比如說我一會跳到003號材質,我一會跳到075號材質,一會跳到064號材質,你想想看,你就想像你的磁盤的讀寫頭是不是來回的移動,當然這個內存中是沒有這個讀寫頭。
但實際上這種叫Address的這種,這種就是這個這個jumping,我們叫這個這個詞不準確了,就是Address跳來跳去的話,實際上它的效率是非常低的,所以呢。
實際上這個Splitting Base的這個Material Blending啊,實際上是非常非常費的,那麼這個時候呢,我們會發現一個很有意思的細節,就是說,事實上,我們在遊戲的任何一個時候。
你看到的地形,是不是也就是你地形的一部分,太遠的地方我可能被你cut掉了,對吧,就算你在,我實際上可以用很粗的幾何,很粗的這個Texture就能表達,那麼,那麼這個時候,我們有沒有更巧妙的方法。
不要這麼麻煩,那這裡面的話呢,我就要引出著名的這個,Virtual Texture,對吧,我相信同學們可能有很多,如果關注過遊戲引擎或者渲染的同學,應該聽過這個詞,這個詞非常的了不起,真的非常了不起。
這個,其實實際上大概在十幾年前,我忘了是哪一年,就是那個,最早我有一個很著名的技術叫Mega Texture,就是,也是我們的大神就是John Kramer提出來的,他的意思,他的邏輯是很簡單。
就是你的一個遊戲啊,包體其實非常非常的大,對不對,但事實上,你在渲染的任何一個時候,你用到的只是它的一個很小的字體,但是你為了防,為了隨時你要去用它,你就把這些所有的東西全部裝在這了,對吧。
然後你就開始很辛苦,就相當於是什麼呢,就相當於你去,出去上課,或者說你去出差旅行,你只出去一天,你雖然要換不同的地方,但是呢,你為了解決各種各樣可能遇到的問題,你背了一個巨大的旅行包。
把所有你的吃穿用意全放在這,但實際上你會發現,你旅行三天的時候,你只用到你們的毛巾牙刷,對吧,一件喜歡衣服就完事了,那麼其實Virtual Texture的話呢,它的核心思想就是,你只需要把你用的東西。
裝載在內存中,其他不用的全部扔在硬盤上,它是怎麼做到的呢,實際上它也是基於剛才我們講的,我們對地形分成一塊一塊的,你會發現這個塊,它是永遠滿足2的密次,比如說我一個512*512的塊。
假設我的Texture一開始,最開始吧,比如說我最密的一個塊,比如說是4米4米的一個塊,我給它配一個10241024的Texture,對不對,但是呢,當你在遠處看的時候,這個地塊。
假設我其實是實際上可以8米8米,就可以表達它的時候,它的Texture的輕度啊,實際上也不需要那麼高,我還是可以用一個10241024的Texture,就能表達在這個地塊上,我能看到的東西。
這個東西是什麼呢,這個講起來有點抽象了,你可以理解成Mip,大家看這個,就是在我們的圖的這個,就是說左下邊的這一層層的這個貼圖,你會發現這裡面是一個很大的,一個火山的一個地形嘛,對不對。
實際上你可以把剛才你所有要做的材質混合,全部都可以混合好,那它一開始可能這個巨大的,比如說幾十幾萬個,甚至幾十萬*幾十萬的這麼一個巨大的Texture,但是呢,它可以一層一層一層的分下去。
在這每層分下的時候,它的假設我用均勻的尺寸,做成一個叫Tile的話,實際上每個Tile,我永遠是比如說128個像素*128個像素,那麼它的Tile的總數,每下去一層直接少4倍,對吧,其實到最後沒有多少。
那麼當我當前在這個View看過去的時候,實際上啊,我只是看到了一大堆大大小小的Tile,Depends那個Tile我用到的LOD,那麼這個Tile的我說,誒,我需要看到它的時候。
實際上我可以臨時的把這個Tile所用到的材質啊,這個Tile所用的幾何呀,這些Mesh啊,把它Bake起來,就是存到一個Cache裡面去,這就是我們叫的Physics Texture。
就是真的真正的存到你的顯存裡面,然後呢,當我去繪製這個一個個Tile的時候呢,我是通過一個Index反向的指過去的,這個地方有點抽象,如果大家沒有任何基礎的話,可能聽不懂,但它最核心的思想是什麼呢。
就是說,我把我的打了個類比啊,就是我把我的所有的工具全部放在我的家裡面,然後呢,我不需要出去修車的時候,把我一屋子的工具全部拎過來,但這一屋子工具你可能都要用到,對不對,誒,很簡單。
我有一個小徒弟給我跑腿,然後呢,我在修車,我先衝過去,說這個車我一檢查發現了它有幾個毛病,我需要扳手,我需要幾號的扳手拿幾個,我需要老虎鉗,我需要這個什麼那個,比如說起步那個那個點火器這些東西,好。
我這些信號給我的這個小的這個小的這個這個小徒弟,他就去我們家裡把這個工具拿過來,好,我差不多就一個手提袋的工具就可以把這個開始修了,但是呢,我修著修著發現,誒,剛才的問題已經修好了,但是呢。
其他的地方又出了新問題,那我就跟小徒弟說,你把這個不用的工具送回去,把我新的工具再調上來,所以呢,在我旁邊永遠放的就是一個小工具袋,但是呢,我家裡面其實有一屋子的工具,這個方法呢,其實有非常大的好處。
其實第一個好處呢,就是說,我在顯存中的空間極大的變小了,大家自己想對不對,是吧,因為我只需要用到我用到的地方,其實在數學上我可以給大家證明,它的那個就是它最高的這個內存佔用啊,是不會超過一個預值的。
因為為什麼呢,因為你每一次你雖然你看的可以無窮遠,但是呢,你永遠是以1/4的精度,所以呢,大家知道那個集數嗎,就是1/4的1/4的1/4的2/4的3/4,你整個加下去,你會發現它是有上限的。
它不會爆掉的,第二個好處是什麼呢,就是剛才我不是講說我每個texture,就是對屏幕上的每個像素,我都要做那次blending嘛,實際上這個blending呢,可以在這個tile被加載的時候,誒。
我做好做好一次之後,as far as這個tile就在這個地方的話,誒,我就不用去動它了,這樣的話,當我進行屏幕上的繪製的時候,我就可以直接取它,就是我們叫做烘培好的這個值。
這個詞有個詞叫bake叫烘培,這個方法真的是非常非常的巧妙,那麼這個的話呢,應該來講的話,是現代遊戲引擎裡面最最主流的,這個一種圖形的繪製,那個地形的繪製方法,如果你現在在寫地形繪製的話。
如果大家還在用這個方法的話,這個不好意思,你寫的是一個學院派的理論的方法,那麼如果在遊戲引擎實戰中的話,大家一般都會用vertex,這基本上已經是一統天下了,因為確實它的好處實在是太大了,對吧。
那麼就是說呢,這裡面就講了一個概念,就是我實際上是在硬盤上面,和我的內存和我的顯存三個地方來回的去調度數據,中間有一個你可以認為叫內存管理器的一個算法,它就會不斷的說,誒。
那個內存管理器就是給那個小徒弟發指令的,那個人就說,誒,你給我拿扳手,你把這個老虎鉗放回去,對吧,那小徒弟就把老虎鉗放回去,然後把扳手拿起來,這個方法呢,其實它有一個問題就是說,其實啊。
我們上在上次一刻講了,就現在的遊戲那個計算機架構啊,它實際上是通過那個總線,我的數據是從硬盤讀到哪呢,讀到我的內存,CPU指令說你讀到內存好,再從內存呢,我再去讀到我的顯存,但是實際上誰是它的消費者。
大家想一想,它的消費者是不是是顯存,跟內存其實沒有什麼關係,CPU更沒有關係,所以呢,這裡面我給大家介紹兩個值得大家關注的前沿的硬件技術的發展,一個是這個Direct Storage,它的意思是什麼。
在現在新的一些顯卡上面,它可以呢,就是說讓你這個數據啊,只是在內存過一下手,但是這個數據它還是壓縮的,就在內存中我不去解壓,因為我們大量的遊戲數據都是壓縮過的,但是呢,它不解壓了。
它直接在顯卡裡面去就GPU裡面去解壓,這樣的好處是什麼呢,就是我從這個就是硬盤到內存,內存到顯卡,都是用一個非常壓縮過的數據傳輸,這樣我傳輸效率會很高,對吧,因為顯卡反正算力很強嘛。
我上上節也跟大家講了,就是顯卡算力應該是至少是現在CPU的10倍吧,所以它就是解壓的時候完全沒有問題,但這個呢還不是最酷的,甚至最酷的話呢,哎呀,這裡面我要開始給這個索尼大法做廣告了。
就是這個DMA技術,什麼意思呢,就是我覺得你們還是太笨了,對吧,你為什麼要在內存再轉一圈呢,你為什麼不可以直接在這個這個磁盤中讀到我的顯存中間去呢,所以DMA的方法就是你直接讀就完事了。
我個人覺得就是未來的這個隨著顯卡已經成為了現代計算機的一個基本標配的話,我認為以前的那種老的這種PCIE的架構啊,可能在未來的幾年可能會真的會被逐步抬頭掉。
就是說大家實際上就可以直接通過那個就是PCIE線,我就直接往內存,往那個顯存裡面寫書,往顯卡裡面寫書去,因為大量的計算我根本不需要CPU,CPU引握不進來。
那麼包括那個就是大家如果關注一下那個NV的最新的一些顯卡的時候,他們還實現了一個就是兩個顯卡之間我通過叫D-Link吧,還直接可以連在一起,就是顯卡之間的數據交換,以前都是要回到內存,在內存轉個手。
再轉到其他的顯卡,現在說你們別別別這麼麻煩了,我就直接連在一起去了,所以的話呢,大家去做那個Virtual Texture實現的時候,如果未來他們在寫下一代的遊戲的時候。
我建議大家要高度關注這個Direct Storage和DMA,就是如果你們能檢測到這個硬件有這個功能的話,那你就直接用它,比如說你寫個PS5的遊戲對吧,你就直接上這個DMA了,這個索尼大發還好。
索尼大發很香,對吧,我們就喊幾句口號,我們繼續往下講,好,所以的話呢,但是呢,在繪製地形的時候,其實有一個非常大家可能注意不到的問題是什麼呢,當我們的地形越做越大的時候,你會遇到一個非常神奇的問題。
我們叫什麼呢,叫浮點數的精度溢出,因為大家知道我們在遊戲裡面,我們寫一個數字,比如說375。673對吧,那麼你覺得我寫了,你就得按我這樣去存,但是不好意思,你所有的信息,你寫的數字,它越複雜。
它就代表它的信息量越大,但是呢,我們存一個浮點數,比如float,我只是用了32個bit,就32個01去表達了一個數字,大家想想看,它能表達的信息量是不是有限呢,所以說當我去表達一個。
比如說從這個地球出發到月球的距離上的每個點,你想想看,如果我這個切分的足夠細的時候,這個精度是不是會越來越不夠用,而且這個精度啊,實際上按照現在這個IEEE的浮點數的這個方法的話呢。
你事實上你會發現就是它隨著這個數字啊,越來越小或者是越來越高,特別是越來越大的時候,它在那個decimal,就是在它的那個就是這個小數部分的話,它的那個精度是非常非常低的,甚至是會超過1。
那這裡面有一條曲線就會告訴你說,用浮點型的方法的話,它到後面的那個這個精度會越來越低,那麼我稍等我把這個視頻給大家再放一下。
就是所以說呢,如果我們用做圖形去計算的時候,當你的相機離物體越來越遠的,你看到這個球,就是你這是相機和球一起往外越走,你會發現越走越遠的時候,這個球一直就在抖動,這個抖動並不是球真的抖。
它跟相機的位置從來沒有動過,但是因為你的浮點數精度已經不夠了,它已經溢出了,這個時候你會發現那個每個頂點的位置就會這樣,就來回就抖動了,這件事情的話呢,在這裡面我們展示的是一個0到6萬公里吧,這個區間。
那你會發現就是到6萬公里的時候,基本上就是一塌糊塗了沒法看了,這個在我們的遊戲中是非常常見的,為什麼呢,我給你舉個例子吧,就是現在的浮點型,浮點型精度的話,如果在2到3平方公里以上的距離的時候。
你比如說你現在假設以一米為單位,那你就會變成就是幾萬點幾,比如說我這邊放一個牆,牆上面我放一個小小的窗窗台,窗台是比如說嵌進牆大概0。05米,就小時點後0。05了,然後呢,我表面再貼一層畫面畫報。
這個畫報離這個牆的距離比如說是一毫米,你會發現當這個這個牆在兩公里之外的時候,那個畫報就開始瘋狂的和這個牆來回去打架,這個是一個非常常見的一個問題,那同學們說那很簡單。
我把所有的數據全存成double型,對吧,就是用64位去存,實在不行,我用兩個double型去存可不可以。
你當然可以了,但是的話你架不住那麼大的數據,你怎麼存,這就是其實現在遊戲引擎一個很大的一個問題,那這個問題其實今天給大家分享一個很簡單的解決方法。
這也是就是引擎中常用的叫做Camera Relative Rendering,就是相機相對性的渲染,這個方法其實講起來就非常的簡單,就是我把所有的物體坐標,全部以前不是在世界坐標系。
比如說我這個牆現在它在世界坐標系的是,2000米零50。1,那個2050米,我的畫報是2050米,它之間誤差只有0。1對吧,但我的相機可能是1990米,就距離這牆只有10米,那我很簡單。
我把相機的位置強行的設計成0,那牆的位置是不是就變成了10。01米了,對不對,那個畫報就變成10。01。1米了,它之間那個浮點式的星度就完全用起來了,這個方法實際上在虛幻和Unity中。
都是一個標準的一個解法,包括很多引擎都是這個解法,但是這個方法也不一定,就是比如舉個例子,比如說在虛幻5中,它現在實現了這個叫Sub-Level,就是我把一個關卡切成很多小的Sub-Level。
那麼其實它在每個Sub-Level的時候,它又會把世界坐標系又重置了一遍,這樣也在解決這個浮點數星度的問題,大家千萬不要小瞧這個問題,因為其實當我們在做一個大型的開放世界的遊戲的時候。
我們包括一些比較複雜的物理模擬運算的時候,其實浮點數星度將會是一個非常嚴重的問題,這裡面繪製的時候我們還有很多的hack,但是你們做物理模擬的時候你會發現,超大場景的物理模擬。
它因為它的這個數值表達的不準確,最後物理模擬就會直接爆炸掉,這個就是非常有意思的東西,就包括有人專門在研究定點數的物理模擬,就在解決這個問題,那這個技術為什麼這麼重要呢,我給大家講一個簡單的例子。
就是我這邊舉了個例子就是,如果我們要做一個像星際旅行的遊戲,你一會兒在地球上,你一會兒在火星上,你一會兒也飛得離太陽很近,大家想想看你那個數值有多大,但是這樣的遊戲有沒有,有啊很多遊戲都是這種星際旅行。
比如剛才前面提到了Low Man’s Sky,對不對,那這個時候我們怎麼去解決它呢,實際上這個就必須要用這樣的一個技術來解決它,所以大家如果在做地形繪製的時候,甚至在做整個遊戲繪製的時候。
這件事情一定要注意,OK好,所以這基本上就講完了我們的地形,哎呀不好意思,我已經講了一個小時了,今天拖湯是一定的了,這個確實內容量很大,而且,呃待會我跟大家講,現在講的這一part還不算是高能的。
待會我們會講的更高能的東西,那麼好,那麼其實呢,在世界表達除了這個地形啊,貼上材質之後還有很多的細節,但這裡面的話我們就不會細講,比如說樹對吧,樹的話大家看到遊戲裡的樹啊。
實際上它是有一套很專門的技術去做的,就是說在進出的時候,你看到的真的是Mesh,到遠處的時候呢,我慢慢的用各個插片把它表達,這個插片呢會讓你感覺不到有任何error的,會越來越稀疏,越來越稀疏。
到遠到遠處的時候我就變成了標board,而且這個標board我一次就會大批,這裡面是一整套的技術,所以說其實tree的rendering啊,是一個非常有挑戰性的問題。
所以光一個tree的rendering的插件就可以賣幾十萬,就是這個道理,那麼這裡面就不得不提一個大名鼎鼎的叫speed tree,對吧,這個確實我個人認為也是目前做的最成熟的一個,那個那個樹木渲染。
就是其實是Foliage,就是植被渲染的一個中間件,那麼另外一個在在環境中經常遇到的東西是什麼呢,我們叫做decorator,其實今天我們不展開講decorator到底怎麼做的。
大家記住就是比如說地上那種草,還有這種小灌木叢,還有很多小碎石,在環境中我們叫decorator,decorator呢一般都會盡量用最簡單的mesh去表達,其實在早年遊戲啊,大家如果打開十年前的遊戲。
你會發現那個草的特點是什麼呢,就是你遠看那個草地很好看,鬱鬱衝衝,但是你走近了低頭一看,你發現那個草會隨著你的那個眼睛看著它在轉,對吧,這個這個就你看那些製作質量比較差的遊戲,你會經常看到這個效果。
實際上這是它的decorator,就是那個它的實現方法,是非常初級的,就是用那個插名片的方法,而且有的時候是用Mudependent的方法,但是呢,更高級的比如像現在3A遊戲的方法的話就更複雜了。
那今天我們不展開,但是我覺得大家在這個課程中能學會的一個詞兒,就是黑化,什麼叫decorator,翻譯成中文叫裝飾物,對吧,就這種就是你已經把地形畫完了之後,樹葉種好了,你要撒上很多decorator。
讓這個環境看上去非常的多樣性,那最後一個呢,跟大家講講大名鼎鼎的這個道路系統和這個D-Cal系統,D-Cal系統這個中文怎麼叫翻譯呢,叫貼花貼片,這個我待會再講,先講道路吧,道路呢。
其實是一個在遊戲引擎中非常重要的一個系統,但是它本身道路系統啊,講起來就非常的複雜,比如說大家關注這一次這個虛幻5的最新彈幕,它就做那個曼哈頓吧,它生成的那個道路系統,其實道路系統比較麻煩的就是說,誒。
我道路之間有穿插,對吧,我不能讓兩個貼圖直接blending覆蓋在一起,因為你會形成很多的斑馬線啊,行人馬路啊,那個算法寫起來真的是,我個人覺得是頭疼肚子疼嘛,反正我是很不愛寫這種東西的。
你有很多情況要處理,但是呢,大家知道道路系統的最常見的做法是什麼呢,叫spline,spline是什麼,樣條曲線,樣條曲線是什麼呢,就是各種控制點你拉拉拽拽,對,artist特別喜歡這個東西,就是誒。
我要拉一條這個蜿蜒的盤山公路,對吧,我要拉一條很筆直的高速公路,誒,你幾個點一拉,這個非常光滑的這條道路線就出來了,但是呢,artist是爽了,程序員就不爽,為什麼呢,因為程序員你會發現。
我在做道路的時候,我不僅要把它整個道路上的所有的這個貼圖,全部給你生成好,我還要對這個高度場進行這個叫做erosion,進行切割和腐蝕,為什麼呢,你hide fill生成的時候,這個山都是傾斜的,對吧。
那這個車是開不上去的呀,你修路的時候怎麼辦,我要把這個山挖掉,對不對,然後在那個地方挖平,對吧,所以你會發現當道路一旦拉出來之後呢,我們就要對高度場進行處理,那麼,Decal是什麼東西呢。
Decal實際上是一種小的貼片,大家經常在遊戲中可以看到一種Decal是什麼呢,比如打個比方,如果大家喜歡玩這個,繼續拿我們大明星的戰地或者射擊遊戲為例的話,你端起一個梭子衝鋒槍對槍一掃。
你會發現你打中的槍有什麼特點,上面是不是出現了很多槍眼槍洞,那些槍眼槍洞就是Decal,那一般Decal呢,我們有的時候會加上一些法像的效果。
有的時候會用剛才我講的那個叫Parallax Mapping,就讓你感覺好像那個地方還真的挖了個東西凹凸,但是那個小小的,你也不在乎過一會兒它就消失掉了,那麼其實Artist呢,在環境中啊。
會撒很多的這種Decal,讓這個環境看上去很有多樣性,所以呢,這些東西無論是道路,它的這個貼圖還是Decal的貼圖呢,它實際上在現代遊戲拍拍爛中呢,我就一股腦的給你bake到哪兒呢。
bake到我們的Virtual Texture上了,反正你這個64米乘64的地方,你是這個原來的terrain也好,材質混合也好,混合上去了對不對,好,你有道路的對吧,我把道路的文領啪也拍上去,然後呢。
你有Decal的對吧,我把Decal啪也拍上去,所以我到了渲染的時候,它就不管了,反正我就把你整個就渲染出來了,所以這個裡面的話呢,也是這個Virtual Texture一個很大的好處。
就是它把那個所有的複雜,全部放在那個bake那個地方了,等到runtime去渲染的時候,它的成本其實非常低,而且做完一次之後,只要這個tile一直在的話,它是不需要更新的,所以這也是非常好的一個地方。
好,所以講到這兒的話呢,基本上我們整個大地講清楚了,對吧,所以你可以,這些東西全部做完,你可以做大地支撐,這是一個非常簡單的一個地形編輯的一個過程,大家可以看到就是。
我生成了這樣一個Hide Field,然後呢Artist用手開始,Paint各種的Texture,因為其實這些東西的話呢,你其實用手全部是可以編輯的,比如說我這個地方是個翻裝的表面。
那個地方我可能是一個砂石的表面,但是這個方法的話呢,是現代做編輯的一個常用的方法,但是呢,我大家應該也聽說了,就是在現代遊戲中,我們越來越多的用程序化的方法生成這些東西,這裡面給大家看一個Demo。
大家可以看到就是說,我用Procedure的方法,就是程序化的方法,我可以生成這種流水對山體的腐蝕,就是你們經常看到的山脊,我可以生成道路,根據山的坡度,它的這個表面的材質,比如它是石頭還是土地。
我可以生成它的植被,包括它的海拔,它的高度,我可以選擇,比如說從這個闊葉林到針葉林的這樣的過渡,所以做這個遊戲引擎是非常有意思的,就是你都會發現,你到後來你會成為一個博物學家,你真的需要理解和學習。
很多自然界的各種各樣的規律和道理,所以說做完遊戲引擎的同學,一般來講都是比較博學的,這個不是吹牛,這是真的,所以我這也是為什麼,我特別希望就是,無論你將來是否真的寫引擎代碼。
你是應該學一些遊戲引擎的基本知識,所以基本上這些東西知道了,我覺得大家如果真的學會了,真的會做了,可以封你為大地之神一階了,對吧,好,但是呢,這事沒完,字幕:J Chong,我可以出去找你了,二胡。
06.游戏中地形大气和云的渲染(下) | GAMES104-现代游戏引擎:从入门到实践 - P1:GAMES104_Lecture06_Part2 - GAMES-Webinar - BV1i3411T7QL
因为接下来呢有一个更难的问题了,就是这个sky和天空,哎呀,我现在已经讲了将近一个小时20分钟了,那我今天我不知道两个小时能讲完,因为接下来sky这个东西啊,真的是就是让你又爱又恨。
我想跟大家大家先爱一爱啊,先这个就是打打气,天空真的很美对吧,我觉得就是一个游戏啊,它的整个一个氛围,我觉得天空和他的这个语音实际上起了绝大部分的这个影响力,真的你的情绪很多时候就是夕阳残雪对吧。
我的情绪就上来了,那比如说像这个horizon有一点那种异性的这种感觉,比较a脸的这种感觉,那么包括像这个老头环对吧,人家是特别善于刻画这样的一种情绪和气氛,对,这也是阿里特别特别喜欢的一个东西。
那么回到我们去表达这个sky的时候,你会发现它里面有两个元素,这一定要分开来,一个是什么呢,一个是天空sky对吧,就是大气,你看到的大气是什么样的,然后在大气层里还有一个东西很重要的东西。
就是特别visible的东西是什么呢,是cloud是云,天空和云是不能混为一谈的,因为天空它是一个抽象的一个球,你可以认为就是到大气层的上限,大气的上限是什么呢,就是霍夫面,大家听没听过这个概念。
就是它是离地表向上100km,我们经常讲,就是那个比如说埃隆马斯克嘲笑那个就是杰夫beos和那个谁,那个那个维维机航太空的那个两个两个人,他们说你们那不是太空飞船,因为你还没飞过100km呢。
你飞过100km,你才好意思跟我讲,你叫太空飞船对吧,那么那么呢但是云的话呢离我们很近,大概只有几百米上千米对吧,那么你当你移动的时候,你会感觉到语音的巨大的体量感,它是一个体量动力。
这两个东西是截然不同的两种表达方法,那其实还有一个东西是什么呢,是fog是雾,但是呢我们今天那个研究了半天,我们觉得这个fog的话呢,我们后面会放在效果里面去讲。
因为就是fog它不只是天空的大气现象的一种表达,实际上也是一种非常重要的一种,就是artist控制的效果,所以今天呢我们就把天空和云讲清楚,这个听上去是不是很简单,如果大家画画的话。
你会发现画天空画语音都是最好画的,寥寥几笔非常写意对吧,很有感觉,所以你怎么画,但是对于我们的游戏的这个这个这个引擎的开发者来讲的话,这绝对是这个头大的东西,接下来我们先讲这个大气对吧。
你可以看到这里面我用的刺客信条确实很漂亮,美得不得了,那传统异能天上的大气真的是随着日出日落对吧,你看到不同的角度,它有各种美轮美奂的颜色变化,那凡事不许怎么样呢,上拟合呀对吧,就像我上次讲材质的时候。
我也不管你下面到底是什么,这个物理的实实际是什么,我不懂,太复杂了,但是我可以观察,观察之后呢,我找一个模型去拟合,你对吧,这样不灵风雅了,所以我一直认为这个方法就是这个这个就有点像大世界的这个布灵风。
就是咣咣咣给了你一堆公式,你也不用管它,这边就两个参数,一个参数是什么呢,就是你向上看的那个角度到天顶,就是那个zis那个天顶的夹角是多少,但这个一般是零到这个零到派对吧,这个角度还有一个是什么呢。
就是你现在看的高度和太阳的夹角是多少对吧,那个它这里面是用了伽马对吧,好,你只要把这两个角度给我诶,我给你查一个表,诶,要把不是查个表,它是算了一个解析解,哎,你就能算出颜色。
这边他给出了一个ground truth是什么呀,他真这个老哥真的是拍了一下,然后呢他在游戏中也生成了这个结果,大家看看这感觉是不是还是可以的对吧,简单粗暴爽,如果我现在做过手游的话。
假设我这个就是是个无良坑爹的这个手游的话,我觉得这个方法也可以,就就混混也就拉倒了,但是呢它的好处就是非常非常的简单,但是它的坏处是什么呢,它的坏处就是说第一个呢你只能在地表,你没有办法做一个什么效果。
就是诶我从太空中飞过来,那个是什么感觉,还有一个就是它所有的参数啊,全部是写死的,你想你这个天空不可能是说永远是那一个一个形式吧,比如说你这个下雨的天,所以呢当我们要真的按3a游戏的标准去做天空的时候。
你会发现这个模型就不集中了,好接下来的部分就开始非常的高能了,我觉得我今天很可能我我看看我能不能讲完啊,ok那首先大家要学一个概念。
就是这个participating media这个词我都不知道中文怎么叫翻译,它,这个就是像空气中有很多的这种小小的这个东西,然后混合在一起,这个透明罐又不又不透明的,这么一个东西,这里面有很多的例子。
那么其实我们看我们的大气层啊,它实际上有两种粒子构成,一种粒子是什么呢,就是各种气体分子对吧,比如说氮气啊,氧气呀对吧,比如说甲烷,二氧化碳,著名的couple dixx型。
就是二氧化碳这个单词我学的最深,就是因为我最近老是听什么温室效应对这个词,每天的耳朵就过去了,其实温室效应最最火的应该是甲烷好,这个第二个是什么呢,我们叫气溶胶对吧,astral这个词儿呢是什么意思。
就是说诶我的空气中的灰尘或者是形成了一种小的这种气溶胶的分子,那么这些东西的话呢,它也会对空气形成折射和反射对吧,那这些就是我们的形成了我们光在这个厂里面走的,所有的这个就是我的戒指是什么。
就是我们周围的大周围不是真空的哦,里面有很多东西,正是因为有这些participating media的话,我们才会产生各种各样复杂的光学现象,那么这个里面就诶这个风尘看着是不是有点吓人了啊。
这个方程确实是有点吓人啊,就是说呢他在讲就是说啊这个光啊到底适合这个participant media,是怎么交这个怎么去在一起交互的,那么首先一头一束光射过来,你第一个效果是什么,诶。
我中间有我的杂质,对不对,我会把你的光给吸收一点,就吸收的效果对吧,我每往前走了一个单位的距离的话,我有多少的光被吸收,那是不是有一个常数对吧,这个就是吸收的一个常数。
一般我们叫做什么那个啊叫sa阿尔法对吧,西格玛阿尔法,那么后呢还有一个是什么呢,就是说哎这个光啊打中我的例子之后,我开始向四面八方开始散射我的能量对吧。
那么因为光就像你光打中了一个一个一个气体分子的时候,他就开始无差别的像四周方向去去去散射,那个叫什么叫out scing,就是说我我把你的能量往外散失的部分。
这个地方我就有一个就是sigma这个这个这个s skettering,然后呢它会跟着光的方向是有关系的一个方程,还有什么呢,哎我这个气体啊,假设是高温的气体,打个比方,比如说那个火焰对吧。
我还带点自发光,或者是我通了个电对吧,比如说我的一个闪电自发光,但其实自发光说实话,当你写方程,你去耍酷的时候,你可以把这个加上去,但是呢呃你不加也没问题,其实我至少you as far。
as i know,在游戏中好像很少有人真的这么干,因为前面这这这几项已经是让你头疼肚子疼了,最后一项那是最蛋疼的东西,叫in scattering,什么意思呢。
你在空气中的一个小的这个这个一个一个空气的一个介质,实际上你的光是不仅仅是你自己被阳光直接照到了这个行为,还有你周边的那些气体分子都被点亮了,对不对。
然后呢他们的他们的出射光就是他们的of scarring,又会打到你的身上,唉我的天,然后呢你要对你还记得我上次在讲那个b r d f材质的时候。
我说卡基亚老先生最让我这个这个不满的地方就是他给我的全是积分,而且全是球面上的积分,这个真的是很头疼,但是呢你要算他的那个in sketching,就是来自四面八方的天空的光,来的时候。
这就是在球面上的所有的光的贡献做了一个积分,哎呀我的天,这就是一个很复杂的积分,然后呢你把这四种效果合到一起,就形成了一个著名的叫rtf,就是radio transfer function对吧。
就是这个这个这个这个叫什么这个辐射传递方程,这个方程呢实际上我在这边写的是一个很简单的一个一倍方程嘛,但实际上呢在三维空间的话呢,它是一个梯度方程,那么那这个t的方程讲起来就比较复杂了,我们就不讲了。
那个大家如果在大学里面学过什么拉普拉拉拉斯算子这些东西的时候,就知道我在讲什么,但是说实话我也就是最近这两天我在备课的时候,我把这些东西全复习了一遍,我备课之前我基本上全忘记了,我说啊我的天呐。
怎么这么麻烦呢,对吧,我这个待会给大家解释,就是大家别怕,你需要知道这些概念,但是呢你不用记住这些公式,我我保证你绝对不需要记住好,接下来我们继续往下啊,好那么我从眼睛看过去,远处的一个点就是m我。
我现在眼睛在p那我看到的这个光的现象到底是由什么东西构成的,这个方程写起来又是各种玄乎对吧,它原则上来讲的话就是从m点,我一次一次一个一个点,我去算它的这个光被吸收的部分,光被散射出去的部分。
其他地方散射的光又再进来了,这个时候我其实呢会有两个值,一个值叫什么呢,叫那个transmittance,就是通透度,什么意思,就是说我在m点的看到的东西,比如说它是个蓝色的东西。
它大概有多少会保留到我在p点看到的东西,这是一个路径积分的一个结果,还有一个东西是什么呢,叫做它的这个skettering function,就是说你在这个你在你过来的时候,我又叠加了沿途的所有的例子。
它无论是从上下左右射过来的光,最后通过他的各种散射,又到我的眼睛去了对吧,那这个这个沿着这个路径的积分的话呢,就是它的scattering part,基本上你你知道了通透度。
你知道scanning power,你在那个m那个点,你放个什么东西,我知道它的光场的话,我就大概知道我看到那个m点是什么样子。
这个方程呢就是著名的就是这个volume render equation v r e对吧,你说这个呃这个我们的先贤们是不是很厉害,两页p p t两组公式,但实际上大家不要怕。
就是这个呢r t f是表示一个梯度,那你对这个梯度的积分啊,就是这个v r e,那不懂积分怎么办,没关系,不用知道了,因为这些东西呢到最后我们全部给你预测到好,待会我们继续往下讲,大家在这一定义里面。
只要记住两个概念,就是假设空气中有这个有很多participating media,就是中间有这种啊,不是真空的,有很多这种空气体的这种杂质的时候,你其实有两个很关键的变量,就是当一束光照过了。
第一个变量就是说在远处看到一个东西,它有多少能透视到我,就transmitters,就到你能到我的眼睛的部分对吧,那么第二个呢就是说哎你因为光打到这个空气的这个分子里面,你乱七八糟的散射到最后诶。
沿着这条光路方向给我的眼睛有多少能量,that’s it,就这样很简单好,那我们继续研究我们的大气的真实的物理学啊,这里面就很高能了,这个真实的大气物理学啊,它实际上有两个主要的参与者。
第一个是什么太阳,太阳是一切的贡献者对吧,太阳的是一束光射到地球上,大家注意啊,太阳光你看到的是什么,是白色的对吧,但事实上呢太阳光是有大量的不同波长的光组成的,只是我们的人眼经过亿万年的进化。
我们把这个波长的组合定义成白色,仅此而已对吧,实际上它的波长很多,各种波长,第二个是什么呢,就是刚才我提到就是大气中有两类东西,一类是气体分子对吧,它的尺寸呢是小于这些波长的,一般的小于这些波长。
还有一类是什么呢,是这个就是气溶胶分子,它一般是接近于这些光的波长的,那么好了,它们的性质就完全不一样了,那这里面给大家介绍两种完全不同的散射模型啊,一个呢叫做really scattering。
这个翻译成中文叫瑞利散射,好像叫瑞利散是吧,这个名字取的好像个女生的名字,但实际上我也不知道这个名字为什么这么叫,可能是个发明酒的人的,那么的话呢它的特点是什么呢,就是当这个空气中的介质啊。
它尺寸远小于光的波长的时候,那么这个光啊就几乎会在四面八方几乎均匀的散射,不太具有方向性,其实还是有一定方向性,但是我会具体的讲,但是它有个特点是说对于越短的波长,它散射的越厉害,对于越长的波长。
它散射的越越越,那个就是越小,什么哪些波长短,蓝光紫光对吧,紫外线,紫外线嘛,对不对,那么哪个波长长呢,那可能就是这个比如说红光这些东西,那么还有一类散射是什么呢,叫密散射。
密散射这个哎呀真的叫叫米氏散射对吧好吧,就我们叫它米式散射,我真的不太记得他中文名叫什么了,然后呢这个它的特点是什么呢,它是由气溶胶,就是它的它的尺寸是接近或者大于那个波长的时候诶。
它就有一定的方向性对吧,它就是你沿着光的方向一般会略强一点,但是它有一个区别是什么呢,就是说它呢对波长不敏感,管你什么波长,我我都是一视同仁,这就非常有意思了,我们先讲这个瑞利散射,锐意散射。
这边是它的一个就比较假设光啊,沿着这个大家看左边那个图啊,右边这个图当光沿着方向过来的时候,它其实散射的这个分布啊,像一个什么,大家看像一个花生,对不对对吧,两头稍微大一点,中间稍微扁一点。
这也符合它的光学原理嘛,那么还有一点是什么呢,你会发现短波长蓝光的它的辐射度会高很多,对不对,但是呢这个长波上红光它的反射度就比较低,这里面就引入了一个大名鼎鼎的这个这个方程。
这个方程呢叫做这个fafunction,什么意思,就是说这就是我我特别想讲啊,就是这个呃这个数学家是很了不起的一个物种,就是你看到这个公式铺天盖地的很复杂对吧,大家不要怕,实际上它就两个部分。
第一个部分呢是它的就是叫face function,就是它的几何形状,这个几何形状你说它复杂吗,其实很简单,就是一加cos theta,大家学过那个就是高中的代数,你把cos c它的平方加上个一。
你得到的就是这个腰果的形状,大家仔细画一下就知道了,就是极坐标计算,所以我觉得这个方方程啊在我看来就是还你看着它很高端,但其实还是个拟合对吧,他就骇客了一下,说我大概就这样。
但这里面的话呢它引入了几个很有意思的参数,第一个它有一个number number,是什么光的波长,它这里面你会发现就是一除以number的四次方,意味着就是当光的波长越短的时候。
它这个散射的强度是不是越高对吧,第二个呢就是说它这个光啊,它这个是受制于什么呢,里面有个变量叫做h就是你会发现这个方程里面有三个变量,一个是number one。
我讲的是波长sa就是你跟它这个光的之间这个夹角,这个夹角的话呢,它是ice tate,就是它在旋转的时候是不变的好,但是呢h是很有意思的一个变量,大家一定要记住海拔高度,大家想想看大气的密度是什么变化。
是不是在海拔为零的时候,浓度最大,越往上它是有一个接近于线性的对吧,越来越稀疏,但这个到底是线性还是非线性就不重要,重要的,因为搞同学的人,我就还一样,我们就假设这个线性就是。
那么我们会认为你跟空气的密度在地平线上的这个区别到底是多少,我们呢就那个大案,就是说一个标准单位体系里面的空气的密度,和你在以真实的海拔高度的密度的变化,这样的话我们现在做什么。
比如说你从珠峰上开一架飞机降落到那个海平面上的时候,你看那个效果其实在里面你就会发生这个变化,所以呢这个方程你去理解它,就是所有左边那么长的一个东西,他到最后你会发现。
对于任何一个这个给定的这个海拔高度和空气密度来说,它就是一个常数,而真正沿着方向在变化的就是那个叫fafunction,那是一个方向,那个方程非常的简单,它实际上只跟一个角有关系对吧,那么有了这个方程。
我们去理解一个很有意思的光学现象,就是为什么天空是蓝的,你看硕图心学的人,他就是很有意思,就是我们真的是个博物学家,就是你会发现这很简单,就是当太阳直射的时候对吧,大量的蓝光它会呢在大气层里被散射开来。
然后呢经过多次散射进入眼睛,红光的是直接照在地上的,但你你不会抬头直看太阳,你往旁边看天空的时候,就天空来回bounce的,因为really散射的时候,那个蓝光的你们来回bs技能眼睛。
那为什么你到傍晚的时候天空是红的呢,因为那个他很斜,很多蓝光它照到在大气层边缘,直接往大气层外面去散射了,所以呢天空中蓝色的部分越来越少,反而红色的部分就多了对吧,但这里面和外面还有一个吸收线。
也会加剧这个红色,待会儿再讲怎么样完美的解决了天空为什么是蓝的对吧,这个这可是这个怎么说呢,难倒了我们人类物理学家上千年的一个问题啊,好那么密散射的话呢跟它不一样,历史你看啊。
这是我们看出来密散射的这个方程,这个方程是这个形状,我觉得真的是很神奇啊,我觉得是一只大带鱼还是大章鱼,我也不知道,反正就是这样一个很奇怪的一个形状,但是呢这个问题难不倒我们的数学家,数学家。
凡事不许上礼盒对吧,你看这个方程呢就比较复杂了,它其实啊左边那一夸啦,也是跟你的高度,海拔高度跟你的空气的密度有关系,ok我把你全部变成一个常数,不用管它,然后呢我要模拟那个形状。
它呢你可以看到它一堆cos c它的变化,但这里面它引入了一个非常有意思的我,我叫做gre parameter,叫g这个g很有意思,就是说当g等于零的时候,你会发现啊。
他这边的这个face function会退化成跟瑞利散射一模一样的,一个一个一个一个就是花生豆的形状不会这么复杂,但是呢当你的g大于一的时候,它就会越来越趋近这边的形状,但是g呢其实是可以小于零的。
呃大于零啊,当g小于零的时候呢,它表示的是说往往那个光线的相就是相反的方向反射的越多,但是一般来讲我们在用的时候,基都是大于零的,这里面只跟大家讲一个数学的东西,这个东西呢大家不要怕。
因为它实际上就是一个拟合方程对吧,它的计算也并不复杂,那么这个g呢我们一般会开放给我们的artist去调整,这个月是原则上来讲的话,就是不同尺寸的particle。
它的记忆会一直有变化好这就是我们的整个一个数学体系对吧,那这个那个这个密反密的散射呢,其实也是我们最重要的一个效果,比如说吧大家看到的雾雾是空气中的小水珠嘛,那么它其实就是个气溶胶。
那你看到雾为什么是白色的,这里面白色的太阳光照下来,所有的波长无差别的散射,最后你看到就是白茫茫的雾对吧,所以务实很多时候是没有颜色的,那么像那个我们看到的那个傍晚的日运的话。
也是因为逆闪是因为它是带有方向性的,所以说你看到这个光就差汇集到你的眼睛去了,所以在那个太阳旁边,你会看到那个how halo是光晕的,这个现象也是个点,包括你在雨天雾天看到那个路灯也会看到这个效果。
也就是密散射好,这个讲起来是不是很复杂,是的很复杂,因为你如果想做一个高水平的游戏引擎的话,这都是你必须要解决的问题,好了呀,这个就很麻烦了呀,那么还有一个很重要的现象是什么呢,叫做光的吸收。
能量被吸收,我们刚才讲了,刚才我们一直讲散射对吧,但其实还有个吸收吸收呢,这里面就讲一些物理学有意思有意思的原理呢,比如说我们大气中的臭氧和甲烷,它们呢都是吸收长波的高手。
那么它可以吸收这个这个红红色的光,所以呢比如说像那个就是那个海王星,为什么看起来是蓝色的,就是因为它表面有很多甲烷,所以当太阳光照过去的时候,它的红色都被吸收走了,所以我就剩下蓝色,你能看见了。
那么其实这个臭氧很有意思,我自己那天我们在我们在做备课的时候,还在说,诶,我记得那个臭氧是吸收紫外线的吗,其实你看v k p d啊,他也说它吸收了个uv嘛,就是那个紫外线。
但是呢我觉得可能是在可可进化波段,它吸收的是那个红色多一点,但是在不可见的波段的话,它有另外一种形式,那这个就更复杂了,我们今天不展开,但是呢当我们去计算大气的现象的时候,我们确实要考虑吸收效应。
但是呢在这里面我们要做个假设,什么假设呢,就是当我给出一个大气的模型的时候,我会认为臭氧和甲烷是均匀的分布在这个这个这个大气层里面,实际上不是对吧,臭氧层是在天上的,但是呢我们算的时候耍流氓。
我们就把它均匀算,因为这个这个模型实在太复杂了,好好了,这就是我们的整个大戏的物理模型,大家感觉怎么样,是不是基本上要爆炸了对吧,觉得这个这个怎么可能解呢,这个确实很难解。
而且这里面有很多的两重积分在一个地方,那么这里面再讲一个很著名的概念呢,就是说叫single skettering和multiscare,叫单次的这个散射和多次散射,其实它通原理上解释是非常的简单。
就是说当我眼睛看到一个远处的一个点,我看到的所有光线是沿我的视线看到的,所有的大气粒子被太阳光照亮,然后呢散射到我这个方向的这个点的能量的加在一起就是家和拉倒,这其实不是价格。
它就远处的那个点的能量还要被中间就是就刚才讲的transmitters,就是还要通过一个通透度进行这个积分到我的眼睛的结果,这就是单词的scattery,这件事情是不是已经很复杂了,对不对。
但是实际上呢我们去看大气现象,它绝对没这么简单,为什么在这些沿途的这些粒子空间的话,我们还有很多其他的例子,他们从各种角度去照我的眼睛对吧,比如说上面的一个一个一个一个例子,他虽然不在我的视线上。
对哦它不对,它是它,它虽然不在线,但是它可以照亮我路径上的一个一个点,那个点沿着我这个方向又一个能量的这个反射,这是什么呢,我们叫做multi scattering,实际上真正做大气现象的话。
最让人难受的,最让人头疼的就是这个东西,你想做一个美丽的天空,不好意思,你没有,这个效果是不息的,大家看这张图,左边这张图的话就是只有single casketchy,你看这个天空样子。
我觉得还是蛮好看的对吧,还可以,你可以看到就是太阳在地平线以下天上出现了那种诶有点这种暖色调,然后再向那个冷色调的蓝色慢慢过渡,但是你会发现山的背面是一片死黑,为什么呢。
single scattering的话,它基本上那个地方是没有光的,但是真实的大气是怎么回事,如果大气中有很多的例子的话,这些在你头顶上的这些空气也会被点亮,然后他光会散射开来。
然后呢又再把你面前的这些这个山背后的空气又给点亮了,所以你会发现虽然阳光照不到伤背面,但伤背面其实是有亮度的对吧,这个但这个大家注意啊,这个跟我们讲的那个gi不是一个道理。
因为积压指的是说我背后假设有个山的另外一面,它被照亮了,这个这个山的背面的光也反射过了,但是gi但是这个multiscattering指的是他是他没有清晰的面,他是无时无无刻不在的这种连续的。
就叫participate media,就是就是这个怎么比方呢,就是充满空间的空气,就像以前那个经典物理学家讲,就是充满空间的以太阳,每个以太分以太那个原子都在这里面干了很多的这个复杂的事情。
然后你一般把他所有的行为积存放在一起,这个时候你才能产生我们想要的这样的一个光学效果,这件事情听上去真的是很蛋疼,但实际上如果你在做今天这个时代的3a游戏的话,这是我们必须要解决和面对的问题。
好那这个问题怎么办,那前面我首先给大家介绍一个非常著名的一个,一个也是大名鼎鼎的算法,你看只要著名的算法都叫marching,这叫remarching,这个像这个算法呢其实非常的简单,就是沿着一条视线。
我把沿途的效果一步一步叫marshine,就是走路嘛一步一步的积分起来,那么比如说刚才我们讲的那个single skettering,就是单次散射的结果的话,是不是我沿着我的视线的方向均匀的踩很多的点。
然后呢我算太阳照到这个点上,这个离子的强度是多少,和它的方向,我根据他的scattering就散射方程,你把我把你的me啊,really啊,方程先算一遍,我现在算出说你头像我的这个光度是多少。
然后我沿路就这样积分下去,我是不是就可以算出来我的single sky那里面讲的还少了一个细节,就是远处的还要经过一次transmitters,就是说它是有通透度的计算的,但这个不展开了,它的核心思想。
就是说我就沿着一条射线直直接积分下去,实际上我们在算所有的大气效果的话,用的都是这个思路,嗯啊天呐,已经一个小时40分钟了,我怀疑我今天要奔着两个半小时去了,这个ok反正我看到同学们很希望我脱单。
那今天我们到时候看上b站视频的时候,我们看能不能切成两段,因为否则这个视频就太长了,好那么你有了这样一个remarching这样的一个数学工具的时候呢,其实我们就可以用我们的最著名的方法。
我记得在上节课,上节课我们反复强调的什么叫计算复杂,用空间来算对吧,就叫做就是用空间换时间,我们可不可以把这些复杂的计算预先算好,然后呢把它存在一个表上,然后呢到到渲染的时候。
我只是根据我现在视线的方向,太阳的角度,我查一个角就可以查得到这个想法,是不是很直接,对不对,那刚才我讲的就是你大气中的光学现象,其实只有两个最重要的部分,大家还记得吗。
第一个部分叫做transmitters,通透度对吧,也就是说我现在看到远处离我那么远的东西,我大概能看到你的30%还是70%,还是99%,对不对,这就是通透度,还有一个是什么呢。
就是scattering,来我这边的散射度是多少,那我们先算通透度怎么算,其实这里面我觉得我们要引入一个很著名的模型了,叫做pre computer atmosphere,atatmospa。
这个scattering就这个方法是非常非常经典的,这个是应该是brunton那个老先生在2000,不是老先生,这个人可能很年轻啊,大概2006年左右做了一个算法吧,就是说他想了一个办法。
就是我把空间中的任何就是地表,地球表面的任何一个点,我算它的海拔高度,在这个海拔高度呢,我存两个值,一个值就是你的视线和天顶之间的那个夹角,就是那个theta对吧。
我我用你的扩散theta进行参数化的表达,还有一个是什么呢,就是说诶我现在跟海拔高度的区别,然后呢你从这个点往大气层去看,因为我现在只能算通透度嘛,所以说我不需要知道太阳在哪里。
我只需要知道就是这个通透在哪里,那你从这个点出发,一路走到大气层的边界,一般我们设定为就是以地球中心,假如地球是6440米的半径的话,那应该是在6540米的那个千米的那个地方啊。
不算6440千米的那个半径的话,那么它应该在6540km的那个地方,就是1百米100km的后封面的那个地方,那么我这根线跟它的交角,就是我看到那个它的镜头,你应该看到的是通透是多少,这个是有点意思吧。
就是比如太空中有个东西的话,假设没有太阳,我们可以看到那个太空中的星星,说明什么,虽然大气层很厚,有100km,但是它是什么,它还是通透的,这个大家能理解吗,那么好,我其实呢就用这么一个简单的方法。
我就可以把整个大气层的通透的这个方程就表达出来了,那么好了,但这个时候呢我假设在远处,我有一座山,或者有一个光,有一个粒子的发射的光到底有多少能透到我的眼前,就在这张图中的话,你可以看到我们设置两个点。
一个是x v就是你眼睛所在的位置,还有一个点是什么呢,是叫xm,就是你中间有一个物质点对吧,middle的那个点不一定是mid,就是中间那个点,然后呢你会发现啊,实际上你有这个表,你可以去查。
在这个从xv就是你眼睛那个位置到大气层边界的这个通透度,把它呢做分母,它的分子是什么呢,就是从那个m点沿着同样的一条线到大气层边界的通透度是多少,然后呢你把这两个tto这样一个分子,一个分母一除诶。
你就能得到他的通透度,这里的具体的数学推导我不展开了,但这个方法真的是非常巧妙的,就是说他用了一个简单的二维的方程,把一个四维的值就给算出来了,因为一个简单的除法。
这个具体的同学们有兴趣可以推导一下对吧,但但是作为作为我当年就是我基本上知道这个东西了,我觉得太牛逼了,然后就大胆的去用了,就假设它永远是对的,对吧好,那么这个时候我有了通透度之后。
接下来我就可以算什么呢,我就可以算他的,大家刚才特别特别蛋疼的single scattering,就是你那个single scattering呢,就是单次散射确实很复杂,但是呢你有了通透度。
你就沿着那个那个刚才给的那个方程啊,你就一路一小步一小步积分,你是一定能算出来的,它真正的难点不在于计算说从a点到b点的这个这个,这个这个散射的强度的难度。
而在于是说我对于整个地球上这么大的一个就是3d的空间,我在各种各样的可能的视角,我在各种各样可能的太阳的方向,我怎么去对大家进行表达,这件事情是很复杂,那这里面的话呢。
我认为最重要的一个思想就是一个参数化的思想,什么意思,就是说我还是在地球表面离海拔高度选择一个爱h高度的地方,我呢朝一个方向去看,那这样的话呢我可以得到一个叫天顶角对吧,我的天顶角一个参数化的表达。
然后呢这个我会一路这条射线会达到大气层的边界,所以那个我不需要知道我的终点在哪,我我我因为是个球嘛,所以我永远知道那个大型的边界离我多远,只要我知道我的角度还有一个什么呢,太阳现在挂的角度,注意啊。
这个时候你看的这个角度和太阳卦的角度和天津的方向,它是个什么角,它不是个平面的角,它是个立体角,所以这里面我们就得到了三个角度量,第一个是太阳到天津的角度,大家想太阳到中午的时候。
是不是离听点越来越近对吧,那个cos的那个那个就是那个那个词儿,我叫n n格玛,还叫什么,whatever,就是它等于一,对不对,但是它太阳越靠近那个地平线以下的时候,它那个值就趋近于零了,对吧,好。
你呢看也是呀,你看天空看看天顶有个角度,然后呢看见旁边也有一个角度,那好那这个角度你也给算出来好,我们把天顶的轴线确定了,确定的话,那这个时候第三个量是什么呢,是我的视线和太阳之间的这个夹角。
在这里面是用fi去表达了,你会发现如果我们这是一个完美的球形的话,所以他在任何一个点上,他的天顶方向就是它的那个法线方向对吧,那你无论怎么转,太阳和你的相对位置怎么转,只要这个球上的大气层。
它是虹膜基尼的虹膜镜子,就是就是说它的各项同志的吧,它其实不不是红的,就是各项各个方向,假设是等等价的变化的话,实际上我只需要去存这三个角度的信息,我就能表达所有的从我现在这样看过去。
看到太空的点的这样的一个沿途的散射值,这个这个东西大家回去可以推一下,其实非常的简单,那么我再沿着高度进行一个采样,我就一路的这样去采,然后用这样的一个简单的方法,我们呢就可以得到一个四维表。
对这个里面是四维表吧,这个就比较复杂,但是呢感谢现在硬件我们有什么呢,有texture ray,大家还记得我们有texture re对吧,其实这里面不应该应该用3d texture,为什么呢。
我沿着他现在他的package的时候,沿着海拔高度依次进行采样,那么呢比如说我1百米踩一个,2百米踩一个,3百米踩一个,但是我人可能是在175米,这个时候我可能就在1百米2百米之间去采这个人。
因为这个信号全是低频的,所以差值是没有问题的,然后呢我在x轴的话,我把这个天顶角,我把这个我们和太阳的角度pk在一起对吧,反正这里面这个这是一个规划的一个细节,但这个大词你看你能明白。
实际上我前面通过各种复杂的计算,我实际上是把这个世界上的光啊,如果只有一次scattering,就一次散射的话,我全部就存下来了对吧,用remix的方法,那我有了这个通透度的分布图。
就是大气的这种就是光过来的这个通透性的transmitters的这个图,我又有了这个一次散射的图,我把一次散射所有的空气的点都会被散射的点照亮,对不对,我用这个照亮的点,再通过通透度再做一次积分。
是不是能得到就是二次散射的图,那么我可以做二次,三次,四次五次,其实理论上你可以做无穷次,但一般来讲我们做3~4次基本上就够用了。
那这个时候我们是不是就可以得到一个叫multi sketching的这个look up table,它的结构啊其实和这个表是一模一样的,因为这是一个完美的对这个就是这种光学现象的一个参数化表达。
但是呢只是你ma sketching的话呢,就是你会两张图看上的区别是什么,就是你每加一次这个那个multsketching,它这个图会看上去亮那么一点点,但是到后面这种变化你基本上已经注意不到了。
所以这就是很著名的这个computed atmosphere的这个sketching,算法的核心思想,它本质上就是说我用预计算的方法,预计算是用什么方法。
是用remarching的方法去把这种大气里面的这种散射现象,通透to这个现象全部变成了表格,然后呢一路给你算好,这样的话在我绘制的每一个点的时候,我就可以用这个效果嗯。
那么其实呢这个方法你看上去很复杂,但是呢当你把所有的一计算全部做完之后,那你在run time,你去用它的时候,那就真的是非常简单,而且的话它真的能够模拟日落日出的效果,这这几个游戏都是大作游戏啊。
比如像非法对吧,像那个就是极品飞车,这都是呃,这这边paper的话呢,就是戴斯的做的这个东西,就是大家可以看到就是这基本上已经达到了state of 2的效果,就是现在很前沿的一个效果,非常的漂亮。
那么那么一计算呢,实际上你一个关卡如果这些参数不动的话,就比如说你大气的参数不动的话,你太阳动,你人动,你一会儿坐飞机从地面到就从地表起飞到天空中都没有问题,他这个确实做的非常的强大。
那么当然这里面有个细节我就没有去讲,就是说呃远处我不仅看到天空的颜色,实际上远处一个物体我要加物效,其实这个方法呢在这里面有一个小的细节,就是在这里面就是说它实际上是那个我先算。
我当前看到大气层的边缘的时候,注射的这个这个这个sky就散射的这个这个能量,然后呢从你那个远处的物体的物理点,你散失的能量,然后呢你的能量又要被那个就是那个transpency的这个能量被减弱。
这两个的一个差值就可以算出来,说我的远处的山他接受了多少的天光,到我的眼里面,这个讲起来就比较复杂了,我就不展开了,但是你会发现就在远处的时候,比如说天假设是蓝蓝的,你看远处那个山。
它也会变得有点越来越蓝,而不是一个简单的只是变暗,其实就是这个效果,那么用这个方法的话呢,也能够完美地实现这个方实现这个效果,那么所以呢这个方法其实真的是非常经典的,就是那个brunton这个方法。
我认为是非常经典的一个算法,那么它有没有问题,其实呢呃它还是有很多的问题的,第一个呢就是它的计算是非常的费的,就是说你刚才可以看到就是我要做很我对每一个思维的表,我都要做一次remarching对吧。
然后呢就是说呃我们在比如说打个比方,比如说我们在移动端的这个手机上,这个计算就很蛋疼,现在我在pc上,我有computer shader,我可以算还可以,但是也是需要大概比如说呃几毫秒吧。
甚至有可能到一秒,但是呢我们可以把它分散到很多,真逐渐松的,比如关卡加载时我就算一下,但是的话呢当artist的说,唉你把这个大气算好了,我不干,为什么呢,比如说我要表达一个效果,是刚才还是蓝天白云。
突然开始要下雨了,那下雨的空气中有很多小水珠对吧,然后呢这个大气的折射和散射就会发生变化,那个时候你会觉得有点雾蒙的感觉,这种这个两个效果呢之间是要均匀的过渡的,每一帧都要插值的。
那这个时候你就很麻烦了,因为你就相当于说每一帧你都要再把刚才那个表再算一遍,刚才那个算表也很麻烦对吧,你怎么算呢,包括我们的artist在会在在编辑这个环境的时候,我们要经常调这个数值。
这个方法他也会很麻烦,你动不了,另外一个的话呢,在run time的时候,虽然尼德已经是用空间换时间了,但是大家仔细去推演一下,你会发现其实他要做很多次的高维表的差值,而且高维表的插曲呢是非常费的。
就是说啊,因为比如说我我硬生生的把一个思维数据pin到三维的数据的时候,其实我很多interpolation需要我手动去做的,比如说我要取一个值的时候,我要在四个点取值,然后再自己做差值,我要几次的。
而且刚才给大家讲的就这么大的texture啊,这个泰勒不大了,但是我的memory会降不来降不去,然后作为一大堆的数学运算,所以呢它其实很复杂,所以这里面的话呢这也是我们104课程的一个精神嘛。
就是说我们会跟大家讲一些点一些非常前沿的一个方法,这里面的话呢我们要浓重的去讲一下,就是今天那个在游戏行业大家在用的一个方法,就是也许我们可以用更简单的方法,但是呢是能解决这个问题。
这个方法实际上在啊今天的ue里面就用了这个方法,就是它是强调的就是如何叫a scalable,and这个这个就是production ready的这个sky and at the field的一个rendering technique。
这个方法我不展开,不讲的太复杂了,跟他讲一个他几个很有意思的一个思想,这个思想我觉得他们大家特别需要学习,他先做了一个非常非常大胆的假设,他说啊你在空气中最麻烦的是什么呢,算这个散射嘛对吧。
就msketching就是一次二次三次散射,但是他说散射这件事情特别的低频,对空气中的一个分子,你来自四面八方散射,你可以近似认为它就是在各项分布是同样的,这个假设是不是很大的,对不对。
但是这个大胆假设有一个很牛逼的属性是什么呢,就是说如果你来自于四面八方的光的是均匀的,那实际上这些光入射到你的点上,你再反射回来的话,是不是就是一个百分比的衰减对吧,也就是说光是四面方向均匀的进了。
然后呢你不管用什么方程散射,你就算是个什么情况,你你最后散射的各个方向都是均匀的,那实际上你就是个能量衰减的问题对吧,也就是大气分子被加热了,然后呢我们散射出了比损失了30%的能量。
所以呢你只要算出一次到两次的这样的一个散射,你就可以算出一个百分比,然后你会发现再往上的话,每次都是百分比的一个级数,这个级数就意味着什么,意味着说我可以用一个最简单的高中数学知识。
我就可以算出他无数次方次的时候,就是multiscaring的这样的一个贡献度,你想这个方法是不是很流氓,但这个方法真的就就work了,他就这么干了,所以就不用像我们那么麻烦的。
就是每一次算它的反射散射的时候,我们都要全部再做一次路径积分,搞得一塌糊涂,对就他就他就没有这个事儿了,那么第二件事情是什么呢,刚才那个卢卡表不是很麻烦吗,思维嘛对吧。
他都在想说哎呀你既然这个世界要动态,我就省一点事嘛,就比如说第一个我假设你的位置就不变了,你假设我每一帧都算,那你的高度,你我我对每个海拔高度去采样,对我有什么意义呢,没义对吧。
那我就把你们的这个h这个维度给它干掉了对吧,第二个就是说太阳我每一帧都算你太阳在每一帧的时候,它的位置不是固定的吗,对不对,好,那我把那个太阳那个维度就干掉了,最后他就用一个非常简单的方法。
就是说诶我一个是天顶角,一个是360度环角,我就把你这个天空的这个multsketching的反射就全部给你算完了,这个真的是非常的了不起,但这里面这个看到图应该是sk jsk scarring。
那哦这个这里面这已经是它的结果了,这个时候他还又算了一个东西,它是这样的,他就说ok我大气中的这种沿着路径的这种透明度的积分,对不对,那我就一路算过去吧,我就一路做过3d texture。
根据距离的远近,这个时候呢诶我又形成了一个积分,这样的话我整个天空的modescaring所有效果,这个图前面那个图有点错误,前面那个图应该只有single single sketching。
实际上啊它实际上那个表里面可以有msketching加上那个无效的效果,所以这个想法其实非常的简单,但是的话呢它就是符合我们前面讲的那个迪士尼精神,就是它并不是物理上完全正确的一个方法。
但是呢他对于我们的艺术家来讲是非常非常友好的,而且这件事情还有一个好处是什么呢,就是它能够让我们的艺术家可以创造各种各样的奇怪的星球,打个比方,比如说我天上有两个太阳对吧,不是一个太阳。
一个月亮都在照我,我看过太阳,太阳那边有日晕,看月亮,月亮那边也有月运,那这样的效果怎么办,或者这个地方的气体的效果是一直在变的,就是刚才我讲的这个,比如说一会儿下雨,一会儿起雾,一会儿怎么样。
他都能表达,所以这里面给大家看一下它的效果,这个是一个现在的慢慢慢慢的越来越多的公司在在用的一个方法。
那么它的好处就是在硬件上,实际上的话是非常的高效,而且呢跟那个brono那个方法呢,我个人觉得差别没有特别大,但是他自己也讲了,在有些情况下,就是比如说那个空气中的那个就是散射度过高的情况下。
比如说就是特别特别浓的这种大气的情况下,它的误差会有点大,甚至会出现色偏,那么好给大家看一下它的效果,大家可以发现就是说它能够表达很多动态的效果,这是一个很a脸的星球。
大家看到天上飘的都不知道什么什么星体,因为我们是什么,我们是做游戏引擎,游戏引擎是干什么的,就是我们在完全的创造一个想象中的世界,所以呃earth虽然是我们的母亲,但是我们要从earth上学的一些算法。
让它能表达各种各样就是beyond earth的东西,所以我个人的话是非常喜欢这个算法的,我觉得我个人觉得这个方法是非常有潜力,所以这个呢也是目前比较前沿的一个做大气的一个方法,同学们如果感兴趣的话。
我觉得作为你的毕设大作业是一个非常好的一个选择,就是难度其实并不像大家想象的那么大,而且有大量的代码可以去下载,但是你把这个东西真的吃透的话,你会发现非常的有意思,好好的,那我们基本上想到这一趴呢。
我们就把这个天空讲完了,我已经讲了快两个小时了,我后面这把会讲的比较快了,其实确实要抓紧时间了,那么接下来呢就是那个云语音呢,这个东西呢实际上是非常了不起的,其实人类对语音的观察是几百年前的最开关。
因为最早我们要关注天气嘛,对气象学家最早意识的语音是有三种类型的,一种是什么呢,一种是层云,就是那个status,就是一层的很很薄的一层云,然后呢就是那个umulus,就是说层积雨越来越厚对吧。
还有一种鱼是什么呢,叫serious,就是说卷云就是小小像卷羊毛样的,那么其实你会发现就是说我们在做这个图形学的时候,真的你不小心,你还得学很多气象学的知识,其实大气中的云啊。
它基本上就这三种的东西在组合在不同高度对吧,在低空的时候,你看到的就是层云和积云,然后呢到中空的时候呢,就是这个这个就是大概在几千米的时候,你看到叫高空的残余和高空的机云。
然后呢再往上的话就是高空的这种卷的层云和卷的这个基因,就这些东西,那么这个东西看起来很简单。
怎么去表达它,这里面的话呢我给大家去讲这个最经典的方法,最简单的方法是什么呢,就是用mash硬生生的表达这个方法,大家不要笑啊,这其实早年真的有人这么干过,但这个可能更偏学术一点,就是artist。
你去放几个大物体书,我大概想要这种形状的云,然后呢他用各种各样的noise啊,腐蚀算法呀,哎最后真的给你形成了一个语音的这样一个集合,但这个方法呢实话实说就是几乎基本上没有人去用它。
我们在过去的十几年甚至更早的时候,大家怎么做鱼大家我现在有很多同学能想到很简单,我们用大量的插片,半透明的插片,各种阿尔法的混合对吧,我们就能形成这样的云的效果,大家现在如果打开10年前的那些网游啊。
更早的游戏的时候,你会发现那些语音就基本上这种方法去做的,看着嘛像个天上飘的巨大的棉花糖,然后呢你觉得他不是云吧,他也是项羽,但是你看着总是那么差那么点意思,对不对。
那么既然我们要立志做这个3a游戏引擎的话,那肯定这个方法是不行的,那所以呢现在在主流的游戏中,最常用的语音的表达方式呢是用一个就是volumetric,cloud modeling的方法。
诶你看这里面又来了warning magic对吧,刚才我在讲地形的时候,我就吐血的推荐说,我们要理解一下什么叫用那个vocal的方式,就是volumetric。
就是用体积的每一个vocal的方式去表达空间,表达形体,你在做云的时候,你不理解这个方法,不好意思,你就真的做不了了,ok好那这个方法的好处是什么呢,就是它是全动态的。
全是在runtime用用那个cpu生成的,它那个云可以表现出很多的变化,因为呃它的形态也很多变,而且还可以还可以云可以飘移各种各样的效果,但是它的唯一的唯一的问题是什么呢,这个算法非常的复杂。
而且呢还很expensive,就是语音要做不好的话,会把整个游戏的效效效率下降非常非常多,但是呢架不住啊,就现在游戏对效果要求越来越高兴,大家基本上都在用这个方法去做一些3a级的游戏好。
那这里呢因为时间的关系啊,所以说我不会讲的特别的细,但是给大家讲一些他最基本的一个思想就好了,那么首先的话呢就是说他用一个叫visa texture,videtexture,有两个部分构成。
第一个部分呢就是说诶我随机的这个语音的分布在空空间的分布,第二个呢它的the texture channel里面存了一个0~1之间的值,其实代表的是语音的厚度,刚才我不是讲了那个陈云对吧。
然后那个就是陈云和积云之间的混合物,叫那个street umulus对吧,然后我们在这umulus就是我们的基因,那好就是0~1的值,诶我的云的厚度越来越不一样,然后你会发现就是说到那个值调整的时候。
同样是那个空间上那个云,你会发现它的厚度是越来越厚了,对不对,所以一张visa texture,这个texture很有用啊,比如说啊我们要想这个云飘起来怎么办。
我们就把这个via texture进行平移,这个语音是不是在天上就飘起来了,对不对,如果让这个语音有些变化的时候,我是不是可以对那个texture进行一些扰动,进行一些各种各样的变化。
这个语音也就发生了变化了,所以这件事情是非常有意思的,就是这是我们的magic好好,这里面我要给大家介绍两个大名鼎鼎的,就是noise function,我相信很多同学在做别的同学都听说过,就是噪音。
噪音是我们很讨厌的东西,对不对,但是呢在其实在信号处理,在这个图形学中,噪音是我们的好伙伴,那这里面有两个著名的方程,一个叫noise,那个pretty noise,就是那个哎中文不知道怎么说了。
反正叫pinnoise,然后呢他是一个非常了不起的一个方法,就是哎呀这个不展开讲了,其实关于poynurse,我觉得讲个20分钟都可以的,就真的很很聪明很聪明,就是用了一个多项式的时间。
就能形成这样一个像棉花絮的这样的一个效果对吧,那么那个另外一个很著名的叫word noise,warning noise呢,它它的近亲是什么呢,就是我们叫做玩i话,就是空间玩any分割什么意思。
就是说我给你很多点,我把我在空间把它分割成一个个以它那个点为最近距离的一个cl,这个东西是个什么东西啊,大家如果用电子显微镜啊,用显微镜观察那个很多的生物现象,比如说以细胞核为中心,它形成的细胞壁啊。
它就是一个玩让你划分,所以very noise呢,你把它反过来看,它现在形成很多那种泡泡絮的感觉,所以pretty noise,你会觉得像那种棉花丝的感觉,但是呢very noise。
它生成的是一个絮状的那种感觉,所以这两个noise方程是我们最常用的两个方程,当然还有其他的方程了,我们今天不展开,你有了这些,为什么这个地方我需要noise function的。
因为你刚才不是要声称云吗,你给了我一张texture,我一开始啊给你生成的云啊,其实是很无聊的,他就是诶这张图好像给错,哦对了,它是个柱状的一个一个图,这个看上去不像是云,是天上飘了很多白木头,对不对。
那我对这个这个形体用各种各样的noise进行腐蚀,这个里面有一大堆的加减乘除的太可,今天因为时间关系,我就不展开,因为我光讲大家就会觉得很抽象,简单来讲的话,就是说我用高频给他用。
先用低频用各种层次的lose noise对它进行,把一些地方给它咬掉,然后呢我再用高频把它一些细节加上很多的细节,这个时候你就能形成一个很像语音的效果,这个效果其实呢从那个刚才我讲,从数学上讲的话。
它可以模拟一个近似分型的效果,因为我不可能在run time每一帧去算个分型嘛,所以说我们用了这些大量的noise方程,让你形成了你想要的棉花絮的效果,这个算法其实真的不难,大家如果有兴趣的话。
可以自己去写一写,那么但是非常好玩,就是这真的就是shader,the hack,就是你的shader,你改行代码里面有很多很奇怪的magic number,你一动诶,那个云的形态就会发生很多的变化。
那么好,你有了这样的一个语音之后,你怎么去渲染它,这个地方是一个比较高能的部分,今天我不展开,但是呢这个云啊他不会真的形成一个面片给你,因为你想那个云的面表面都是那种zz的东西对吧。
那那那上百万上千万的面都会生成,那根本画不出来,这个时候就要请出我们著名的叫remarching的算法,就是当我从眼睛看上去天空的任何一个位置,我就往上打,我就打,看看我能不能打到你生成的那个体积。
云那么好,这个时候呢就有细节,就是我们会假设所有的语音是在某个特定高度,所以我根据我的相机视角,我第一步尽可能打的离云近一点,但是呢我接下来的步长也比较大,可能是50米,1百米,我就往前走。
但是我一旦hit到第一个云的时候,诶我之后就开始耍流氓了,我把它步骤就变得非常小,比如10米1步或者是20米1步,我直接一直到我飞出这个语音的边界,然后在每一个点的话。
我去算它的大气的光的通通透和它的散射,那个散射就scattering,而且scattering还要算multiscattering,这个具体在雨里面怎么去算,这个就是那个schattering的话。
实际上呢是一个另外一套技术了,这套技术呢其实呃比刚才我讲的那个sky要简单,为什么呢,因为如果我在这边的话,再去做的非常复杂的话,计算机是不允许的,第二个的话呢,语音的话呢,它因为通透度很低。
所以呢我们可以做很多大量的这个假设,就是对这个方程进行简化,就像刚才我在讲的那个就是那个最新的虚幻五,做那个就是天空的那个方法嘛,他为什么我个人很喜欢这个方法呢,就是因为他做了很多合理的假设。
所以大家以后如果做return rendering的话,一定要大胆假设,所以呢它就可以实现就是real time把这个体积云给绘制出来,所以大家可以理解是你在游戏中看到那个云啊。
并不是真实的在天上飘了个面片,它实际上是存在你的gpu里面的一个3d的虚拟的texture,然后我们是用remarking的方法把它解析出来的一个结果,这个想象就抽象。
但是呢这个算法本身呢还是比较expensive,所以呢我们一般会用第一的速率的去采样嗯,但是呢这个方法虽然有大量的假设,而且呢听上去呢又有很多noise,但是它实现的效果真的是非常了不起。
我给大家看一下它的效果,这就是用这个方法生成的云对吧,它不仅可以模拟很多复杂的云本身的光学现象,还有太阳在语音中间的通透啊,透视这种效果,而且语音本身呢可以模拟各种各样的transition。
就是说从薄到厚的,厚到薄的,然后呢各种风吹着它的洞,所以这其实是相对于就是说啊,十几年前的我们的游戏引擎技术来讲的话,是一个革命性的变化,所以今天的游戏引擎这个是属于标配。
你必须要做这样的一个语音的效果啊,大家觉得这个怎么样,画面是不是很美,反正我个人是非常喜欢,所以做刚才讲的天空啊,做这个云的话,我们一般称之为叫什么呢,叫天空之神,感觉是不是有神的感觉了。
好基本上呢就是哎还好,我基本上勉强控制在两个小时之内,我把今天的课程讲完了,本来我们还有一趴讲fog的,幸好在上课之前,我们临时决定把它给砍掉了,否则发今天的课程就收不了尾了,那么跟大家汇报一下。
就是呃我们的polo的引擎现在还在,首先非常感谢大家很积极的参与我们的引擎的这个一起的这个讨论啊,不更新,那这里面的话呢pio引擎的话呢,其实我们在过去的一周还是做了很多很多的工作。
就大家修掉了很多的bug,同时的话呢就是说同学们也积极的跟我们做了很多的contribution,这些东西起来,其实我自己这边的话也在想,就是后面可能我们会单独的录一些视频,就是有些同学跟我们讲说。
拍的引擎虽然已经很简单了对吧,但是如果我技术比较薄,我没办法不知道从哪下手,我到时候可能会跟大家一起做一个walk through,或者叫123这种视频,跟大家讲一下怎么去看这个pta的引擎代代码。
包括我们也希望就是在未来啊,就是在未来的12年里面,我们和大家一起慢慢慢慢的把,刚才我们在课程上讲了一些非常有意思的算法,比如说那个terrain的算法,比如说天空天空的算法,包括云的算法。
我们也在我们的小影中,大家一起来实现,我不知道同学们有没有兴趣啊,大家可以在弹幕或者留言告诉我们说,如果大家有兴趣的话,我个人觉得这是很好玩的,帮助大家一起在这样一个这个小引擎里面。
把这些前沿的算法都实现得了,这样的话我我们的那个那句话就不是空想了,人均一个对吧,自演引擎,所以po引擎的话呢就是我们的课程组的话跟大家一起去去去干下,去,继续去做。
那么另外一个给同学们讲一个就是我们这边的一个思考,就是说啊我们现在发现我们课程的信息量真的是太大了,基本上我们是跟大家去比干那个过程简直就是互相伤害对吧,你们每每周要听到我们这种拖堂的课程。
然后那么大的信息量,然后呢课程组也是死去活来,我跟大家分享一下,在过去的72小时,我大概只睡了十个小时,十个小时左右,那怎么说呢,跟大家分享一个我的一个一个一个能力啊。
这很像我当年写cio paper的时候的经历,就是我们那时候研究出来的时候,如果你不得不熬夜通宵做东西的时候,最高效的方法是每天凌晨12点到三点休息三小时,这样的话你起来的时候精力是可以充沛的。
你可以连续战斗大概4~5天左右,所以在过去的72小时,12小时也就三天的话,我就切换到这个叫每天三小时睡眠的模式,然后才把这个ppt我们团队才干出来,但是这样的话真的是实在难以为继。
包括这次我们想到五一长假的时候,我突然发现一个很有意思的事情,就是说我们实际上可以把我们的课程分成一个一个,比如说三四节课成为一个章节,我们每三四节课之后呢,我们休息一周,这样给同学们有时间去消化。
去体会,甚至提问,我们也可以给大家做一些简单的视频,给大家讲一些大家关心的问题,然后呢再去讲后面的东西,就是说如果大家没有意见的话,我们后面的话可能按这个方向去去讲,这样的话节奏也会更好一点。
另外一个就是呢我们每一节课程准备的时间会更加的充分一点,因为确实作为我们自己来讲的话,既然开了这门课程的话,我们还是态度非常的端正,就今天的这个p p t中的话,每一个公式,每一个符号我们都是检查过的。
都是用公式编辑器自己打过的,就真的是推演了一遍,所以公式不要打错了,虽然在课程中我给大家讲说,你不用管它,公式都很简单对吧,但实际上你打开课件的时候,你会发现的公式其实还真的是彼此关联的。
那么因为毕竟是作为一门课程嘛,我们特别希望就是说这个前所未有的课程,能够成为同学们真的能够最快速的最高效的理解现代引擎,它的这个前沿,它的全貌的这样的一个一个通识课程,所以的话呢我觉得咱们把节奏控制好。
就是每隔几节课休息一下,可能会是一个更好的节奏对吧,就像我们在国外这个一个叫什么semester,就是每隔几周诶,我们有一个小学期停一下,我们休息一下,再去再去那个往后做。
基本上我们的作业呢也会采取这种节奏,就是诶三四节课一个小章节,我们布置作业,然后呢留一留一周时间,我们准备下一阶段的课程,大家做作业,这样也节奏也比较好好,那基本上这件事情的话呢,也想征得大家的同意。
那个大家如果没有意见的话,我们后面的可能按这个方法去安排好,那就是今天呢我的课程的全部了啊,这个我们好像又创了拖堂的新的记录,现在应该是差不多是接近130分钟了。
好的接下来还是留几分钟就给同学们提一下问题,就大家关于今天的课程有什么问题问我,啊这个第一个问题很有意思,同学问我说本节课程讲的四叉式的管理。
和前面的课程中那个game objects 4杀四杀数管理是不是可以共用,哎这个同学真的非常的聪明,是的完全可以共用,所以四叉树为什么好,就是它可以把游戏里面的很多东西统一管理起来。
就都可以用这种配置的思想,就是可以在硬盘,在那个磁盘到主内存到显存之间来回调度,因为当我们真的做一个像开放世界的游戏的时候,你会发现基本上每个东西都可以把你的显存或者内存给炸掉,好。
哦第二对第二个同学的问题是哎呀,这个问题很有意思,他跟我说体积云的渲染会不会耗时啊,是的,刚才其实啊体积云它是它其实在我的理解中啊,它的生成其实还好,因为noise方程大家如果真的写一下。
就知道它的效率是非常非常高的,很快你就会在一个morning texture里面,3d的texture里面腐蚀出了一个云的效果,但是当你去做它的渲染的时候,你去做这个remarsh。
然后呢你要算它的所有的skettering,虽然这些curing的方程我们都做了很多的简化,你还要把太阳这些东西全部带在一起考虑,而且这个语音呢刚才我没有展开讲,其实那个云的颜色还要受到大气的影响。
大家想想看那个远处天边的云,它是不是要从天上这个天光中还要吸吸收阳光,这样看上去才自然,所以这些乱七八糟的东西加上去的时候,你会发现每一个像素你都要做这么多,很奇怪的,因为每个像素就代表了一根锐啊。
一根光线,大家如果学过retracing,就知道屏幕上看到每个点就是你的视线射出的一个光线,你都要做这样的一个因素啊,大家想想这是不是要死了,但是呢这里面有很多呃耍流氓的方法。
比如说我对屏幕进行down sampling,比如说我只是用1/2的尺寸,也就是1/4的像素算完,然后呢把它进行一个blue,把它贴回去对吧,那么包括那个我们后面可能会给同学们介绍的著名的这个大力水手。
dlss s d r s的话,也是能够帮助我们节约很多这样的cos的方法,啊有同学开始跟我抱怨了,这个同学第三回合的问题是说后期课程难度怎么样,会不会完全听不懂啊,是这样的,就是说其实呢我自己的体会啊。
rendering应该是最难的一趴哦,我我前两天我在跟林奇就严令奇严老师在讲,我就说哎我们俩课程要联动一下,因为如果在我的四节课中呢,有些东西大家真的听目标的话,我会推荐大家去听他的课。
就是说呃其实确实绘制这个东西啊是蛮复杂的,因为它这里面有大量的数学在里面,包括大家刚才也听到了,今天我们就画个天空,我们把整个光学物理学的东西全部给撸了一遍对吧,然后再加上数学又做了一堆简化。
还是这么复杂,所以呢但是呢其实如果你真的去做,真的去用的时候,你会发现啊,在这么多前人的工作之上,你真正把它看懂了之后,实现起来其实并不难,那么那么简单来讲的课程难度的话呢。
就因为我们在这个rendering这一趴的话,我们一般会跟大家讲一些就是state bar,就是现在真正在用的这些技术,一般来讲一个行业发展了30年之后,它不会太简单。
故意很多简单的方法其实都已经被淘汰掉了,他基本上都要求那种很极致的效果,所以的话呢会有渲染难度,那这个课程的话呢,我也会尽可能的把这些复杂的算法,把他的思想,把他的思路教给大家。
把一些关键的卡点交给大家,但是的话呢就是说呃,他应该不会影响你对他的宏观的这个思维方式的一个理解,所以后面的难度呢我的预判是会比rendering略微下降一点,这rendering确实是有点难。
啊接下来有个同学问我一个问题了,也很很很很专业了,他说这个大气散射计算的终止条件是什么,这个地方的话呢,实际上在我们的实践中,我们就说multisketching,你算到三阶四阶拉,倒不要再算了。
再算就死人了对吧,那基本上就是一个硬性的order算的,这并不像物理学说,比如说你的这个电子低于某个值了,我不算了,因为这个是一个非常理论的模型,但是在游戏引擎的实战中的话,我们一般是不敢这么算的。
对好的,那今天的话呢,因为我拖堂拖的有点厉害了,已经是这个啊两个小时15分钟了,那要不今天我们先这样,那个再次谢谢大家,就是说参与今天的课程,然后那个希望我们和大家一起把这个课程越做越好好的。
那我们下周见,咱们继续比干。
06.高动态范围成像与手机摄影 | GAMES204-计算成像 - P1 - GAMES-Webinar - BV1KS4y147tp
啊时间差不多了,我们先说一下,就是那个作业的事,就是前两天我们把上周末把作业布置下去了,第一个嗯难度不是特别大,是写一个基础的sp啊,有些同学会问到,就是有一些我们会给一些基础的参数。
这些参数就是大家不要被这个参数局限住了,这个参数给大家的只只是一个初始值,是需要大家去调了,去调去看它的效果的,最后呃其实也不是很局限于呃,像我们slides里给的一些就是最后的一个结果。
就是大家可以自由的发挥,就可以调到让你视觉上最满意的一种效果,黑电瓶啊,大家可以呃就调到小数位啊,这些都是没有问题的,就是大家可以仔细调一调这些参数,去看一下到底是什么样的效果。
嗯而且这个我们最后交作业的时候呢,就是啊这个作业可能会比较大,就大家就是在系统里面只是提交一个压缩版的一个报告就可以了啊,还有交一个就是有比较清晰的图的一个报告的时候,嗯。
就建议大家我会给大家share一个one drive,因为那个系统也不是支持,也不太支持特别大的一个嗯这么一个文件的一个上传,就是大家以命名规则,待会会在群里发出来,嗯然后。
在整个系统里面呢就放一个压缩版的一个报告啊,这样的话大家也记好,打分也好做一个记录,啊第一次作业也是有关i s p嗯,然后就是第二次作业啊,会在第一次的作业基础上做一个延伸啊。
会让大家实现一下比较高级的一些算法吧,还有一个就是嗯比较复杂的一些去噪的算法,上一节课我们讲到了一个方法比较简单,嗯,其实呃我们需要再补充一下。
去把一个bm c d或者是not call me lome去实现一下啊,这样的话就大家对这个东西会有一个更深刻的理解啊,就是前两次作业就实现了一个呃效果比较优质的一个呃,i s t的pipeline。
这个怎么去做,它其实大家慢慢做完之后都会有一个比较深刻的一个认识,然后这前两节课之后,就是现在我们是已经是第六节课了啊,第六节课之前呢,其实我们这六节课都是一个比较基础的内容,从下节课开始。
我们开始会开始就是覆盖一些啊,整个光学的一个部分,就是它那个imaging tbox是分一个光学部分啊,像我们的相差分析啊,还有我们这个点破的函数怎么设计啊,这一个有一个image to box呃。
这个image top讲完了之后,因为,我们光学对计算成像来说是做一个调制嘛,嗯然后呢就需要用算法来解调算法的部分就覆盖啊,像一些物理学的算法和一个基于deep learning的算法。
还有a d m m或者是prom operator,呃,会给大家在就是三个算法里面啊,去挑那么两个去详细的讲解,然后大家可以根据这个讲解来实现一个啊,比如说对光学的点矿的函数的一个逆变换。
或者是实现一个就是呃single pixel camera,这样来作为第三次作业,就是这每个作业都是划环相扣,就希望大家能够紧跟这个步,伐就是真正的把计算成像这门课学好理解透啊。
其实这个后面就无论是大家做学术还是做一个上应用,都会有一个非常好的一个应用前景,今天给大家讲了一个主题啊,是一个hdr里面体,这个在当今的一个就是手机的计算摄像里面是非常重要的一个课题。
也就是我们的信噪比并不高,性价比并不高,所以说后来就是呃大家会发明出了非常多的方法,有那种等长曝光的,比如说报是几张图片,通过等长曝光去拯救它,是noise,那本身位数也比较高,可以是12位,14位。
且可以一定程度的实现一定的hdr,然后再通过他买品可以显示到大家手机上,而实际上还会有一个一样的不等长的曝光来实现这么一个hdr啊,但是这个burst中间的一个过程呢会有很多的好像alignment呀。
或者是像在tm creature里面处理一些细节,这个大家需要注意。
今天这节课呢就我们会从一个就先给大家简介一下,这个现在的一个流行的一个image format,这个花那么两页slides去讲一下,然后就开始给大家讲。
今天的主题是整个hdr成像在我们的手机摄像里面是怎么实现的,因为其实hdr成像里面有非常多的方法,我想提高满井容量呃,去做的多帧融合,去做食欲的调制,空域的调制嗯,还有像一些特殊的神像细节。
但今天我们讲的就是呃大家最常见接触的最多的一个手机成像,这么一个hdr到底是怎么实现的,也就是所谓的大家所说的一个多曝光如何啊,当我们就是做完融合之后,拿到一个非常高位的一个啊。
很多位数的一个就是hdr图像了,但是这个动态范围又特别大,这个大了之后怎么办呢,就我们要怎么样显示到我们一个八位或者十位的显示器呢,这个时候就需要把它的一个动态范围进行压缩。
但是压缩的时候我们又想尽可能的保留亮处和暗处的细节,这个时候就需要做汤卖品,然后还有一些介绍了一个两个经典的一个,在手机里面成像里面应用的一个算法,就是一个新的叫the next slug。
一个tomap的一个concurvature ti的一种方法,还有另一个就是著名的hdr plus,也就是burst alignment这么一种方法,哪来的。
嗯这节课就接近了非常多的一些优秀的一些size,还有lynx,还有fdm,还有lv,还有像google research的一些呃经验,首先给大家就是讲一下这个常见的一个image format。
就是我们日常生活中啊,这一常见的一些就是图像,它到底是一个什么样的一种表现形式,比如说哈就是我们最常见的叫t i s f或者tag image file,tag image file。
这个也叫嗯标签图像文件格式啊,它是一种比较灵活的绘图模式,主要用来存储啊,像那种照片呀啊或者是艺术艺术图像之类的一些图像,它是一个比较高质量的一种图像的一种存储的一种格式。
其实这个太这个这个这个t r f f或者tag image呃,和那个p n g啊,它的一个代名词呢其实就是非常高的质量,嗯,它是一个没有压缩过的一种呃一种一种图吧,可以上显示嗯上百万种颜色。
而且但是没有压缩过呢,所以说啊它的占比就会比较大,但质量就比较高,所以说用途呢就是像呃出版印刷呀,喷绘啊,写真啊,呃这种需要就肯特高质量的这么一个用途,当然它的一个也可以存储一个透明的通道。
就是来作为嗯,比如说我们像设计素材的这么一种需求,另外一种就是常见的格式,就是beat map,也就是b m p格式的,它也是没有压缩的,就是纯绘图,还可以有每个像素里面就是rgb 3个通道。
382 14位这么一个图像格式,还有一个最常见大家日常生活中接触最多最多的叫japc,就是叫jin photographic experts groups,这种是大家日常生活中最常见最常见的一种图像。
它支持一个非常高的一个级别的压缩,但是嗯这是一种有损的一种压缩格式,所以说通常说jpeg因为呃经过压缩,它体积比较小,所以说就很容易的在我们的网络上啊去传输啊,特别是在显示在网页上啊,去加载网页的时候。
唉这种jpg图像就非常有优势,体积小嗯,结算也不是特别复杂,它编辑码啊基本上就是呃做一个d c t啊,或者是呃做一个量化啊,这么一个比较简单的那一种便利吧,然后gr f这个其实大家都很熟悉啊。
这个gr f就是大家经常会看到那种搞笑的动图啊,其实啊它最大的一个特点就是这个东西它是动态的,而且动态之后呢,它体积又比较小,这个gf为什么到了今天,虽然它存图像质量不是特别好啊,但是直到今天。
就是依然有很多的新的这种动画的一种图像格式出现之后,但是这个gf还是表现出了一个很顽强的生命力啊,这个就举个简单的例子,像我们的一个png格式,我们压缩一个png那个代码其实挺大的。
就是大概有500k的这么一个代码,还要加上z lib这种一种压缩方式,但是gr f本身的编解码,大概你写个千万行代码就可以,完全就可以很容易地实现,就是它的编解码比较容易,然后加上体积比较小。
又可以播动画,其实嗯这个东西是非常好的,那另一种就是我们网络上常见的叫p ng png呢,就是跟jpc不一样的地方,就是png它的压缩是无损的,然后呢除了无损之外。
还是可以呃保留一定的一个就是透明的通道,这个透明的通道就可以作为像大家图片编辑的素材啊,就需要有透明效果,这个时候就比较推荐使用,看它的缺点就是它的体积会比jpeg稍微大一点,它压缩率没有解pk这么高。
然后下面就收到一个饶土,就是大家相机啊,特别是单反相机拍到这么一个绕土,cr two啊,啊,像dng啊,还有像比如索尼相机的一个点a r w,这都是一个绕图的一种格式,它是一种完全没有压缩过的一个图像。
为什么要绕呢,然后就是就是生的嘛,就是没有经过加工,所以说这个饶文件,它是保留了我们整个呃数字图像传感器的一个最原始的信息,像iso的设置,我们上节课已经看到了一个点绕图像的一些呃matter设置。
光圈快门这些,信息,然后本身它又是rggb最原保留最原始的图像,他就可以理解为嗯,像我们在一个模拟摄影时代的一个底片的这么一个东西,就经过对底片加工之后,我们最后才能拿到一个呃比较好的一个最后的图像。
然后最后说一种叫ex r格式,就是大家做图形学的时候,经常会遇到这么一个ex r的格式,其实ex 2呢有时候也叫这个open ex 2,它是一种开放标准的一种高动态范围图像的模式。
嗯其实这个用来存储数据啊,或者是呃存储一些高度发尾的图像,这个它就有一个比较大的优势,它除了,像呃现在我们常见的像八位啊,12位的图像,它可以存16位或者32位的一个flow的形式的格式。
那通道也可以随意改变,就是大家存三个通道,四个通道,五个通道,十个通道哎都是没有问题的,这就是e x r格式的一种优势,这个open ex呢最早是由这个叫工业光魔这么一家公司开发的。
它是一个呃最早是用在这个最早用在一个电影里面,叫叫哈利波特嗯,哈利波特与魔法石,可能是那个电影算是最早运用到ex r存储这个我这个电影文件的,然后从那个之后就是open 0 gx 2,逐渐就。
成为了一个很多电影里面去存储这个高端化学图像的一个工具,就是它的一个这ex格式的,可以把一些很高光,像那种defuse在漫反射呀,像阴影啊,就是透明通道呀,rgb啊。
这就是如果我们对渲染的时候渲染出那种图像的画面,高光啊或者是漫射呃,就是觉得不好的时候,就是我们可以人工的去通过这些通道进行调整,来产生出来一个更完美的一个画面。
也就是我们这一个多通道的那么一个多位数的这么一种就存储方式,会有一个比较好的优势,然后另一些就是呃像打印里面常见的eps,就是这个是一种矢量的一种表示方式,它可以直接记录他一个线条,就是文字的存储啊。
嗯像都可以有那个是贝塞尔曲线,不知道啊,这个都可以直接去用过,这通过这些方式啊,这个eps格式来存储出来,还有一个就是大家就用到了pdf,这个都是通常在文档里面用,嗯,它是一个pdf。
是一个非常好的格式,它是很接近一个标准的一个呃规格,就是大家无论是操作处理显示啊,都是一个比较有优势的这么一种格式,啊最后一种就是svg,这个叫scannable vector graphics,嗯。
它是没有一个损失或丢失的,它是嗯它也是一种矢量图,就是可以呃对对,这种在那个网页上显示呀,这种都会比较有的优势,那下面讲一个今天的正题,就是high mac range美景,我们知道这个动态范围啊。
就是实际上简说简单一点就是最亮和最暗之间的这么一个关系,就是我们就是更粗略的来说,就是对比度,就我们能展现出来或者是捕捉到最亮的亮度跟最暗的就是那种亮度,两个之间的比值,实际上就是动态范围。
我们自然界的动态范围是非常大的,其实呃最大的时候可以做到40个stop,就是上节课我们讲到呃,这个一个stop就是二的,就就是两倍,就40个stom吗,就是40多个stop就是二的40多次方倍。
这个动态范围是非常大的,所以说呢捕捉自然界中这么大一个动态范围的一个呃,光线的一个分布是非常困难的,所以说这个同学们就发生了这种非常多的一种方法,来实现这么一个东西,首先为什么要捕捉a t点。
因为呃我们那个传感器啊通常是十位,12位,14位,相比我们自然界里面40多位这么一个大动态范围,这个嗯范围是实际上是很小很小的,就是我们只能捕捉到一个12位或者14位这么一个小通道的范围。
这个举个简单的例子哈。
就是我们当然你看现在我们这一些灯光已经过曝了的情况下,这些灯光已经过曝了诶,但是亮亮的地方呢我是一点没拍到诶,这个时候你能说它它动态范围,小王其实他已经有了一个14位的一个动态范围了。
但是它还仅仅能表示出来从最亮到一个呃就比较亮的一个位置,但是它暗的地方仍然是排不到,那这个怎么办呢啊同学们可以说哎这个我可以增加曝光时间,对我们就来继续增加曝光时间,增加曝光时间之后。
我发现这个暗部的细节明显的变好了。
对不对,但是有一些灯光呢这个时候已经过曝了,就我更亮的细节的地方损失了,暗地方稍微好一点,但是暗的地方也不够亮,当我们继续的这个增大我的一个曝光那两个stop的时候。
所以说但是这个亮部的地方就是它a完全过曝了,这个时候啊,就大家觉得划不来,是不是划不来之后要怎么办呢,它受限于我们的那个传感器的动态二,对不对,让它变得更亮了。
那会儿哇,好家伙,这个亮的都已经完全看不清了,不好意思,这是上一个是零四stop,这个已经亮了,看不清了,所以说这个但是暗的地方又变得非常清晰,诶,这个是怎么办呢。
每一张图像都只能捕捉到它一个相应的一个动态范围,唉所以说有一个聪明的人类就想到出来这么一种方法,诶,就是我可以把这多张图像融合起来,来实现一个更大的一个动态范围,这个这个思路就是呃非常简单粗暴。
但是又非常有效的一种方法,然后呢通过一定的汤白品,大家也可以啊。
真正的把亮的暗的细节啊都同时的展现出来,因为这个我们对一个很高档的范围的图像,如果只是简单的啊去把它一个对比度拉下来之后,就是比如简单做一个skilling,我们感觉到很多亮的地方。
暗的地方并没有做到一个非常好的效果,所以说就是我们要把一个大动态范围的图像,完美的展示在我们一个小动态范围图像的显示器的时候,简单的一个student是呃做不到这一点。
所以说呃这个我们获得hdr图像之后,要显示出来还要经历的一个过程叫做tmp,我们怎么样去做一个好的一个tomaking,来更加的增强它的一个细节。
来让我们的整个图像更加完美,更加漂亮,唉这就是我们这节课的一个任务。
说到这个hdr成像呀是为什么呢,就是我们这个本身传感器的这个一个。
它是有一个叫量子井这么一个东西,就是也叫well capacity,就是这跟我们它这个井的容量跟这个像素大小是有关系的,它总是有一个上限在那个地方,那比如说我们一个4。
25微米的一个像元尺寸的一个传感器,他可能大概能存12000个电荷,就是它的一个井容量就是12000个电荷,6。5微米稍微大一点的像素就可以到4。5万个,这个这个电荷到11微米的像元呢。
就可以乘到a80080000 个电荷就越大,这个像素越大,除了我们之前讲到的一个性价比更高之外,它那个满减容量是变得更大的,但是呢就是我们这个平时用到的一个图像传感器啊,它为了一个面积的问题。
就是我们想让面积更小,这样的话它成本就可以做到更低,这个时候诶我们动态范围其实也是被压低了,除此之外啊,这个井容量啊也不能无限的变大,因为变得非常大之后,比如我们要一个像素,一个像素做一个1微米。
就是100微米,一个像素,这个行不行啊,能做出来,但是这个时,候它整个积分变得就是不是线性了,就光电效应在往里面积分的时候会变成一个非线性的一种效应,这个时候对我们后端的sp处理就变得非常困难。
所以说这个总有一个就是没有办法让完美的那么一个折中在这个地方,然后除了这个之外,就是减容量之外,他还受到一个a d c的这么可造成的一个影响,就实际上嗯我们大部分的一个hr成像的系统。
很大时候啊它的动态范围都局限于噪声,比如最亮的时候是6536,就按的时候是零,但是我有噪声的幅值到了十诶,那你这个对比度就是6536比好的十,对不对,其实这个噪声它也是一个噪声受限的系统。
同时它也会受这个我们魔术转换a d c的一个量化的这么一种影响,其实都限制了我们中的动态范围,这个其实就我们知道这些在动态上面,是有限的,但是没有想获得这么一个hdr图像,哎这个时候要怎么办呢。
就刚才讲了啊,就是我们想要把这么一个比如说像八位啊或者十位啊,14位,12位的这么一种呃图像合成一个像16位,18位,24位,32位的这么一个更大的范围的动态范围的图像。
这个时候我们就需要呃一个最简单的一个方法,就是多次曝光融合,那我先看一下这整个的overview啊,就是呃要做一个hr融合呢,首先我们要把这个camera response curvature。
也就是我对亮暗的一个响应关系能拿到,因为这个响应关系如果是线性的话,就变得非常容易处理,但是如果经过一定的sp之后,比如说是一个jpg图像。
他的这个这个camera restaurant curvature变得非线性了,这个时候处理就需要我们提前把这个呃图像的一个呃。
就是camera response curvature调到一个线性的状态下,再进行一个增长范围的融合,这样的话就可以获得一个比较好的连续性的一个效果,然后第二个呢就是我们要做融合嘛。
我们就需要获得一系列的这么一个ldl的图像,来获得一个hdr图像,或者是32位的这么一个hdr图像,最后然后呢就是通过啊这个convert。
我们把这个就可以转化到真实的absolute radiance,或者是globe,通过global skin来存储这么一张图像,当然也可以啊进行一个logo套卖品啊。
然后去增强一下它亮的按钮的细节来显示出来,这个这个response curvature呢其实挺简单的。
就是大家,就是我们可以用一张饶图,也可以用一张jpeg图,但是我们要知道它这个响应的曲线,我们可以用一个cabbation chart来实现这个东西,就是这个这这个东西叫色卡呀,叫比色卡皮塔。
除了颜色块之外啊,我们会下面会有一些灰度的块,就是代表了一个不同的一个灰度值,因为这些灰度值啊本身是一个线性分布的,唉我们就把这个呃像素块对应的值,就我们图像拍到的那个值,无论是jpg还是呃饶图啊。
嗯可以通过这个值来做一个呃这个pixel value进行一个对应。
如果诶如果发现是线性的牢狱,它肯定是线性的,它不能完全是线性的,它基本上就是线性的,大家看基层认为是线性的,而这个时候大家就比较容易处理它一条直线,但是经过一定处理之后,比如说jpg诶。
我这个时候他就是拉拉亮出了一个mile t,也拉出一个highlights,而低处的时候呢,它也也不是一个飞行用的,这个时候我们要想变到线性域里去处理,就要把这个图像呃,先拉到一个新星域。
这样的话就可以把这个jpc的这么一种呃,这个this response curvature拉成一条线性的一个玉,也就是说我们通常拿到了一张就是jpeg图像诶,我要先把它变到线性域。
就是做一个这么一个函数的逆变换a,然后再进行融合,其实这个这个a s d r融合其实就是非常简单粗暴。
也就是把一,个线性空间里面的一个就是线性的一个camera response的,一个一系列的这个曝光的图啊,融合在一起对吧,然后拖了一个hr图像,但这个融合怎么做呢,就我们在变完之后,变到线性域之后。
唉我们就可以对这些一系列的这么一个线性域的一个图,通过这么一个加权,这是一个高斯的一个加权,唉我们这个每一张图的系数啊,是根据这个中心这个亮度有关的,偏差越远,就是说你最后算到的系数越小。
离这中间的mile to越近的时候,哎我们就算到这个权重越大,最后通过这么一个呃权重的加权,最后简单粗暴的就把这个hdr图像融合起来了。
然后我们也可以对一些在其他的color channel用同样的一个权重进行融合。
这样的话就可以获得一个就是像样的一种效果,但是我们这个时候究竟对他来说是怎么融合呢,其实呃我们要是本身是定义一个就是list quare objective。
就是一个欧盟,我们要尽可能的就是优化我这个线性的hdr图像,跟我嗯各个权重之间的各个权重就是我跟不同曝光之间的一个差吧,也就是,但是我们这个地方为什么要由这个对数图像呢。
就是我们用了一个叫对数加权的这一个东西,因为这个对数加权是因为呃考虑了人眼的感知特性,就是它做人的一个视觉效果是比较好的,就是我们要最后要在不同的一个就是exporter time下。
然后解那么一个优化函数来,最后嗯实现就是算到呃我实际的一个hr图像到底是什么样子啊,说了说到这个人影的对手响应啊,就是我们还想到其实现在是有存在这个对数传感器的,就是它本身这个传感器的响应啊。
就是有一个对数响应,这个大家课后可以查一查看一看,那我们把这个objective方程o写出来之后,然后我们要想把这个hr图像截出来,怎么办呢,就我们要对这,因为这个明显嘛它是一个凸函数。
就相当于一个嗯简单一点理解就相当于一个一元二次函数,虽然它是一个比较一个线性方程嘛,但实际上我们这个解他的时候就可以用一个最小的乘法,或者是呃大家偷懒一点,因为它是凸的嘛,它整个是一个凸的这么一个形状。
我对它求导,然后等于零,就是它的,极值对不对,然后a我们就可以对它求导,对这个d o b d log x,因为求导它变量是log x啊,记住,让这个导数等于零。
最后我们解到了就是这个嗯hdr图像呢就是在对数域里面,他这么一个加权来获得的这么一种图像,这个就实现了一个hdr的merge。
然后还有讲到一个概念叫叫relative跟这个absolutely readings,就是仅仅是给了一个相对的一个radi,但是我们最后拿到这个hr图像的时候呢。
呃是可以根据一个参考的一个radiance,来达到一个真实的这么一个radiance的值,嗯,这个也就是一个系数问题,大家就可以注意一下,这个可以直接获得这个radiance的值了。
就刚才讲到了这个hdr图像是怎么获取的,就我们通过一系列的mod啊啊,或者给一定要的权重,通过在log space域嗯,我对它一个求导取极值,然后就可以把这个hr图像解出来。
但是这个时候我们要想把它就是比较好的这么大一个32位的图像,这个我们要想完美的展示在我们这一个八位的这个l dr display。
因为我们知道我们这个图像显示器就是这个display a monitor,它通常一个八位的红色通道,绿色通道跟蓝色通道都是一个八位的这么一个图,但是我们比如说我们获得了一个32位的一个a7 r图像。
这个时候诶怎么把这个32位的图像显示出来呢,就我们的显示设备的动态范围,是远远小于这个acr成像结果的动态范围,所以说对这个这个结果其实也就是这个结果的一个增加为太大了,就说我们这32332次方。
这比一这个跟那28x256比一,那个是差太多,所以说这个时候我们要显示的时候,就需要做一个动态范围的压缩,对不对,就是简单一点,就是刚才讲到了,我们做一个线性压缩。
我直接把这个32位的图压到一个0~25之间,诶,这个时候好家伙,这个很多细节就会丢掉,但是就只能保留到一些非常high contrast的一些,就是很很高对比度的一些范围的细节。
其他的一个对比对小呢在这个压缩过程中也都已经看不到了,所以这个怎么压缩呢,其实这种常见的解决方法大概有两类,就是第一类就是一个做一个全局的动态压缩,比如说像呃使用像类s的曲线,或者是rx的。
或者是a c e s的像素调整,就是这个像素调整呢本身就与像素的这个intensity有关系,但这个时候,这种话比如直接做一个呃伽马呀什么之类的,这种方法速度快,很直观,那可以避免光晕啊。
或者是饲料逆转,但是这个时候这种玩意儿非常容易破坏,就图像通道之间的白平衡也会丢掉局部细节,第二种方法就是大家所说的这个局部的一个动态范围压缩方法,就是local糖卖品像素的调整。
跟淋浴的一个亮度分布有关系,也是局部的方法,可以保留更多的细节,但是计算十分耗时嗯,很容易引起噪声,并产生一些光晕的这些问题,所以说这个嗯大家在这个方向做了非常多的研究,就是local糖。
白品我们就要保留细节,但是又不想破坏它的分布,那也想不要产生光影,造成这个时候啊,大家就是进行了非常多的一些成果,当然也取得了一个非常就是好的一个效果,并实现了一些呃工业应用。
就是我们可以看到啊这个hdr图像的时候这么一张hdr图像,我这个亮的地方太亮了,这个时候我就拍不到,就是我显示不出来这个亮部的细节,这个暗部的地方呢又太暗了,太暗了,也没有办法显示,对不对。
这个又有光暗的地方,又有饱和的地方,这个就是显示的不是很尽如人意,诶大家就是讲了,我们这个做一个简单的伽马,可不可以,我比如说直接我在一个图像上开个呃,2。2方分之一这么一个根号就行不行,诶可以。
但这个时候就会有问题啊,就是我们在直接开伽马的时候,就它的白平衡会被破坏掉,也就是我们这个呃颜色就是就显得很苍白的那种颜色的感觉,就是颜色也会发偏发灰,诶这个时候大家觉得嗯这个不是很完美,对不对。
哎不是很完美,之后大家就有想通到这个我们色彩就是我不想被色彩受影响了。
这个我们把这个色彩分离开,是不是就可以了,所以说有的同志们就很聪明,我可以变到外语v语,我只对这个y亮度做一个糖白屏,诶,我保留这个彩色的通道,这个时候我只对这个亮度和伽马,对不对。
但是这个时候呢你做完伽马之后,他最后所实现的一个intensity details,还是会有丢失,就是我亮度的地方还是会有丢失,这个时候嗯也不是很完美,是不是,所以大家也还是呃想获得一个更。
好更好的一种方法,这个怎么做呢,所以说这个时候人们就有一种这种基本思路,因为前面讲到了就是把呃这个亮度跟这个彩色的通道分离,但是分离之后呢,就是大家会发现这个细节会丢失,这个怎么办呢。
然后再延续这个思路,再往下去扒一层,就是我们可以使用各种滤波的手段,就把这个hr图像分解成基础层,就是也就是base层跟细节层,details层,唉。
我们这个细节想要就contrast的细节想尽可能的保留,但是呢又对基础层做一个对比度的压缩,这个压缩之后的基础层跟原来的细节层相加,就呃得到跟保留了细节层的一个定增范围的图像。
但是这个就会带来一个问题啊,就是我们怎么样分解这个基础层跟细节层,然后呃如何对这个技术层做一个动态范围压缩呢,你分离的方法是,那当我们分解这分分离这个基础层跟那个细节层,是有比较多的一个思路啊。
其实这个低频的地方就是平滑过度的地方,高频的地方就是我们亮度突变的地方,就是也代表了一些contrast跟纹理的信息,简单一点我们就可以用一个呃高斯滤波,但是这个高斯滤波平滑过后嗯,就丢了非常多的细节。
这个平滑过后的图像我们细节丢掉了嘛,就可以作为一个基础层,然后呢我们这个用原图减去这个平滑图像哎,就是丢失到细节层,就可以看到细节层,当你用不一样的滤波器啊,就可以得到不一样的分离。
说这个我我这这这个就讲这个用bletter filter,就用保编渠道的一种方式来对这个输入的hdr图像,它那个intensity呃来进行一个细节跟一个details。
跟那个base layer跟基础层的一个分离,就我们做一个快速的双,倍滤波用上保镖一场渠道,对不对,然后我们对这个贝斯的也就是低频的一个层做一个呃,就是动态上面的压缩,也就是这个let go的压缩。
然后这个details层了诶,直接保留,最后把这个d t l跟logo再融合在一起,再把之前的一个彩色通道加上,这个时候又可以比比较好的保留intest的一个contrast。
就可以比较好地保留这个颜色,然后同时又对一个低频的一个大动端行业进行一个压缩,最后就实现了一个比较好的效果,然后引申到这个地方啊,其实这种方法大家可能在别的地方也看到过,但这个时。
候就对应着就是hdr系统显示的方法,这个之前就是呃我们这个是我们当时是我们实验室啊,最早定了一种叫bpack technology,它也是基于这种思路。
就是我们就是他只是做了一个动漫高动态范围的一个显示器,因为我们现在日常的显示器啊,就很多时候就是背光的时候,对不对,但是我们的思路是,我们想要通过一个低频的这么一个更大的动态范围。
来展示这么一个hr的效果,所以现在大家市面上看到了很多的a7 r的一个lcd的显示器,有种技术叫动态背光,就我们,后面这个显示器面板后面有很多个呃小的一个led点亮阵列,然后前面是一个我们lcd层。
这个时候就相当于在低频做了一个动态范围的一个放大,也就是说我们可以用这种方法来实现一个hdr的显示,就来显示更大的动态范围,就是让肉眼真正的可以看到更多更亮更暗的信息,那同时它也是在一个低频域呃。
来就是进行动态照明的,所以说这个时候啊就可以很好地保留它的一个显示的一个细节,这个叫技术叫bacchnology,大家可以去搜一下。
唉这是一个呃用这个用batter filter做一个local tmap的一种呃效果图,就大家可以很清晰地看到这种细节是被很好的保留到了,就是我们在这个基础层次细节上分离的时候啊。
已经用到了一个双边滤波器,当然这个还有一些比较更先进的方法,就比如说这个local reaction filter,就是这个嗯是可能是工业里面一工业界应用了一个就是最先进的方法。
就已经是我们知道有一些公司已经对这些产品,就用这些方法对一些产品进行了落地,就他可以嗯最大程度上的就是实现一个比较平滑的这么一个亮的,暗的一个拉伸的这么一个细节。
就把亮的就是细节跟暗的细节尽可能的多的保留出来,那下面给大家讲两个,就经典的一个手机图像处理的这么一个修手机里面,计算上演的这么呃classical的一个method,比较新的一种方法呢。
就是就是我们会有什么问题哈,就是就我们在比如说拍一个夜景的时候,就是不一样的一个tc位置嗯,就是在一个夜晚上,我如果太亮的话,这个烫水拉太亮,哎,这个时候这个图看着好像白天一样。
这个时候究竟是白天还是夜里呢,但是我如果我这个图太暗的时候,就是很多就是暗处的细节是没有办法拍清楚的,对不对,所以说这种问题就比较难解决,量调亮了也不好,调暗了也不好。
然后但是我们调节的创客vature的目的是什么,第一个目的就是我们要压住就暗处的噪声,因为我们知道暗处的噪声虽然小,但是我信号也小,我其实s n r就是一个一个psr,就是我那个心噪比是变得更低的。
所以说造成显得就大,那第二个是我们这个汤要把这个这阴影部分的细节尽可能放大,对不对,我们想要呃让整张图像尽可能的曝光在一个middle town那个位置,而不是呃那个过量或高的位置。
但是同时我们要保住这个亮部的一个信息,所以这个这个套是怎么获得呢,这是google团队最新的一个呃论文。
这叫the npc look,这个这个大家他们自己称叫npc look的一个paper,实际上是一篇sequars的paper,叫c你extreme dark,大家可以翻一翻,后面会给出链接。
像传统的一种手机处理的方法叫hdr plus,这是叫hanive,也是google pencil团队呃,跟也就是马克老魏老师的团队里面做了一种baseline的一种方法,它是呃融合了13张。
曝光了一张图,总共花了啊,就是1/15秒,它大概的一个图像效果是这个样子。
当加了这么一个new tmap的一个在这个baseline里面诶。
就是我们就把暗处的细节拉得更亮一些,对不对,那把亮出的细节就是也是保持住了,但这个时候我们就发现而通过这种方法直接调这个comment,唉我就发现这个暗处的噪声啊是比较大的,但是这个是我们不想要的。
对不对,如果我们想要这个抑制这个噪声,最简单的一个思路就是延长曝光时间,对不对,通过延长曝光时间,我们就通过积分之后,这个就经过一定的积分,然后就可以把这个噪声心脏比提高来抑制住嗯。
这个后面的一个那个后面的这么一种噪声吧,但是这个曝光时间太长,比如说像这张图有个1/3秒,这个1/3秒,无论是人手抖一下,还是这个相机在运动,那这个这个噪声啊。
就跟这个呃这个motion blur也就产生了那么一种天然的一种矛盾,就我想要保这个没有motion blur,这就造成大,但是想要,噪声小,这个就motion blur,因为这个时候大家就很难受。
对不对,所以说这个时候这个googpixel团队就做了一个呃,就是把这个motion blur,就是motion deep,就再放在那个末日里面,就我们可以我们可以看到。
做了一个motion debra之后,我们这个整个的图像质量就会有一个明显的提升啊,这个时候我们可以看到这个图啊,还是有问题,我这个即使我们在融合的过程中把这个motion不给抠掉了。
但是嗯它这个整个烫就整个颜色其实并不是很真,它是有些偏红的,其实这个对我们很多就是暗,就是暗夜视频或者是暗处拍照的时候,它的颜色就是它的白平衡是非常困难的,就说说现在有很多论文啊,还是很多企业呀。
就这种集暗处或者是非常暗的一些地方来做一个比较好的拍片,白银衡通常是用一个呃,小的神经网络来实现这么一个呃白平衡的一个ti。
所以说当时这个google pixel团队就做了这么一个auto white balance,这么一个work就可以比较好地实现一个呃暗处成像的一个色彩。
先给大家看一下结果,然后再给大家呃揭露一下这个到底是怎么实现的,就我们可以很明显地看到这个hdr plus就是比较传统的一个呃。
13张图的一个位置,就是比较短的一个曝光,跟这个长曝光加上motion debra加上autoy balance这么一种新的方法啊,这两个都是google googpio团队做出来的。
但是我们可以看到呃,经过了34年的这么一种发展,这个技术可以得到一个非常好的效果,也就是我们在拍一个很暗的一个场景的情况下,我们就可以拿到一个非常好的一种提升吧,这个是怎么实现的呢。
就先说这个呃比较经典的一个classical local tming,就是嗯这个这种这种方法叫一个呃最经典的一种classical的local tmap,就是叫premiere,premise。
就是金字塔,我们在金字塔为什么要做金字塔,要诶我们可以看到这个每下采样一次,我这个频率其实就咔嚓掉了一半,我这整个无论是拉普拉斯金字塔还是一个高斯金字塔。
我最后啊实际上就是在不同的频率之间进行做一个融合,然后这个图呢就是我们可以就通过把这个hr图像作为输出,我们先构建一个一个拉的一个一个金字塔,然后我们那个wmap呢可以用一个高斯的一个金字塔。
然后把这个进行一个融合,融合之后就可以拿到一个最后的一个final comp image,这个就可以消除边缘一些不好的一个效应,这个大家可以参照一下,看07年嗯,matrix嗯。
还有一个1年paris和14年的outbrea,这三篇论文就大家可以看一下呃,不一样的一个金字塔下的一个融合是怎么实现的,来这个就刚才讲到了,我们这个曝光时间长。
就我们input burst,burst就是拍一串图,就当我们拍了一串图之后,我们因为我们物体不可能是静止的,它一直在运动的,我们想要啊通过这么多次曝光来进行融合了之后,我就拍那么一串图像。
把这一串图像就融合在一起,对不对,嗯,然后这个时候我们会通常在这个,比如说我要拍13张图,就是google plus,就是hr plus,就拍13张图,我们会挑一张比较好的一张图。
当一个reference就一个图,但是呃就是论文里面大家倒腾着玩的时候,嗯可能就是选,那么可能选个最好,的一张图就是优化一下诶,选一下哪个图,评价一下哪个最好,但是实际嗯就是生产过程中呢。
就是大家就是在企业里面要把这个产品零件产啊,就不可能去花那么多计算资源去给你找一个最好的参考图诶,这个时候大家就会啊,通常就是可能就选一个前三章里面一个最好的,就就就就就这么算了,其实效果已经挺好了。
就可以忍了,这个时候他通常是在牢狱做的,因为饶狱里面它是一个噪声分布才是线性的,就我们的响应也是线性的,这个时候处理是最容易的,当然这个也会受到一些motion bo的一个问题。
大家就可以找一个reference frame,就是motion不知道最小的一个reference frame,然后把其他的地方往这个reference frame上去做line啊。
这个就跟呃图像编辑码了这么一种块匹配的这一种方法就是近似,大家去找这个不同帧之间相似的块,然后去把那个vector去计算出来去,然后最后把这些相似的块呃,在一个三维空间中去做一个啊,就是平均嘛就可。
以这么这么理解,这个思想跟这个编解码就是说h264265 啊是基本上是一致的,就是这个时候这个也就是大家嗯可能就是看各个厂家就是标榜的时候,就是3d降噪,其实就是这么一个简单的原理。
那这个时候大家通常就会一些做一个cross to find的一个alarm,就是我们这个图像啊,就是boss的boss拍的时候,他总会多多少少会受一些运动啊,手抖的一些影响,就他那个图像并不是像素。
并不是按严格的这么一个嗯排布,就是来一一对应的,所以说这个时候我们要想要设置一个cross flegnment,就是现在出的一个呃,就是这低频的一个领域里面是对齐,然后在一个相应的搜索窗范围内。
把这个呃那个匹配那个快去找到,找到之后,然后再去呃做一个就是这么一个融合,平均,相当于然后在这一个低频范围内找完,再一层一层的嗯,去找一个更高频的一个那里面的一个alignment。
然后这次找高频的一块儿的一个匹配,这样的话呃就是可以最大程度上节省计算资源,这个如果大家学过这个图形学的时候啊,这个思想就跟这个mip map这个方法是一致的,所以这个不只是这里哈。
这个金字塔在各个地方都用得非常多,就简单一点啊,大家可以看到这个unit,这也是一个crossf这么一个一层一层下载一样的一种方法,这个大家有没有想过这个为什么要做这个下载一样呢。
实际上这每一层下采样就相当于我的频率低了一半,实际上也就是相当于我在频谱之间去找它的一个特征,就是在低频高频的特征的一个这个融合跟拆散拆解再融合,就这么一种思路,这个无论是在这里面图像融合呀。
还有像弥补map呀,嗯还有倒是到底是这个unit呀,这个整个思想都是一致的,但是这种思想也一会在图像分类里面,这个整个特征的提取啊,分类啊,也都是用,到这种呃这种一层一层的一个金字塔的一个思想。
那这个东西已经占据了产业界跟学术界呃非常大的一个一个份额。
唉这个说到正事了,这个我们找了一个就是最最最没有谋生不了的这么一个参考图对吧,我们可以看到上面那个参考图的各个细节,然后下面我们就要把其他的一个图像往我们这张参考图上去一个alan。
去找一个相似匹配的一个块,然后去然后也可以做一个简单的维纳滤波去呃,接底边一下去逆一下,这个时候再把它融合在一起,这个怎么做呢。
这个我们通常是把这个整个图像就是分成一个这个叫tifa base的merge。
这个跟那个b m c d的这种想法是挺一致的,就是我们先把这个啊,这比如说把这个分成16x16或者32撤销的一个小块,诶,我这个小块里面我做一个dc t或者是一个f t的变化,就把它变化到频域。
然后找到一个相似的一个匹配块,在一个不同帧之间找到一个相似的匹配块,然后匹配块这个可以把它默认在一起,然后做一个平均就可以很大程度的降低它的噪声啊,这个啊不跟那个bm c d不同的是。
这个是在针尖之中找相似块,这个针尖之间长相的话,因为我们运动啊它都有规律,它这个整个运动的一个vector是比较好容易估的,就我不需要在一个很大范围内进行搜索。
所以说这种类型的一块匹配思想的一个3d降噪啊,就相对bm d是比较容易实现的,因为我们那个搜索范围不是特别大,当然我们是呃思路是大概一致的,我找到匹配的块,把这个融合起来,融合起来之后嗯。
然后把那个低频加上做一个逆变换,就把这个原来的位置融合进去,这就是呃大家这个3d降噪的这么一个思想。
比如我们把第一张图做一个reference frame,其他的一个图呢就相当于呃在这些块之间做一个家庭平均,这个它是按一个小那块匹配的一种方式进行交易,平均啊,平均完之后a噪声变小了。
我把这个把它默认回去,那这就大家可以看到就可以拿到一个比较好的清晰的,然后噪声就比较低的这么一张图像,这个做这个3d降噪啊,就是有一个缺点,特别是工业界里面就不是很喜欢的一个缺点,就是它需要存图。
我可能要缓存好几张图,但缓存图呢就需要用ddd r d d r呢就会有功耗,说这个3d,降噪其实在一些比较严苛的,就是需要高速低延时啊,就是低功耗的一些场景下嗯是比较困难的,但是它的成本其实也不低。
因为我们要存这么多图呢,就像可能是单独挂一个dd r唉,这个时候就会比较贵,当然嗯这个它也带来了很多无与伦比的好处,嗯就是它的噪声真的会非常好,因为我们用到了很多真的一个一个图像了嘛。
其实它的搜索也比较容易啊,这个就是后来因为bmcd已经算是一个单张图里面的最好的算法,后来又有蝙蝠就变ford,也是在三维空间里面去做一个类似的一种,方式,但后来后来还有非常多的一种方法。
但这本身这个bd已经嗯到达了一个挺巅峰的一种位置,就是这么多年,在基于块匹配思想呢,呃一种方法在产业界中仍然是得到了一个最广泛的一个应用,这当然讲到了。
就是刚才讲到的都是在绕力的一个处理,这个绕力这个墨子完处理之后,我拿到了一个呃12位,14位,一个比较高位的一个图像之后,哎我们还是要通过嗯这这么一个传sp的一个papi。
来最后实现一个更加好的一张图像,这一这个跟我们上节课讲的一个ip基本机制呃,这个就做了一个一定的简化。
大家可以对比一下这个hdr plus跟这个新的这个boost photography for heared and law,light image of mobile phones,这是一篇呃。
这两篇都是西瓜和西瓜fa上的论文,就对比的一个不同的情况,就是,atm h加plus用的就是全都是没有过曝的一张first,然后这个the united size呢就是用一个更长的burst。
然后在中间做一个motion blur,然后再进行做一个快匹配,嗯其实这个时候因为曝光时间更长了嘛,然后就把motion blur去掉了,然后就拿了一个更漂亮的一个夜景的一个图。
当然这里面还有一个非常重要的技术,叫叫他们自己实现了一个用神经网络做了一个auto white balance,这个时候因为解决了就是在夜景里面这个颜色会失真的这么一个问题,好这节课就到这里了。
就今天给大家分享了一个就是你常见的一些image file for mates,就我们讲了一个简单的方式,叫做hdr,就是margin就是不同呃,曝光时长,然后把默认在一起。
然后实现一个更大的一个动态范围,但这个动态范围显示呢,我要把它压缩到我们这个显示器可显示的一个范围内,来,尽可能地保留亮处和暗处的细节,最后给大家分享了两个经典的一个手机摄影的一种方法啊。
就是长曝光去去底部,然后再做一个auto buy buy,然后老的hdr plus呢就是短曝光,就and a poser短曝光来融合在一起,大家可以选一个这两种方法都是选一个参考图就融合在一起。
区别就是一个是长曝光,影视短曝光,然后还有没有一个差一个auto white balance,最后经过在这我们牢狱里面处理完之,后,来经过一系列的这个finish pipeline。
就是后面的i s p,最后实现一个比较好的效果好,今天的课就到这里,大家有什么问题可以提问一下,这个我可以给大家进行解答。
大家有什么问题吗,啊对了,这个作为第二次作业诶,可以给作业中间的图像结果吗,这个可以嗯,让就是助教同学给大家就是发一些这种中间的计算结果,其实这个大家都可以想象到,其实没有特别难的一些环节啊。
这就是与大家有哪些同学就哪些在中间的一些结果,你不是很理解的,就是你能想象不到的那种结果,比如说这个可以举个例子嘛,啊助教同学尽可能的给大家嗯找到一个比较好的一个参考,对调参调参没思路。
这个问题呢就是这个整体的你是需要一步一步的来,就是我们要先把这个线性空间里面去做好,然后再去呃去马赛克,去完马赛克就可以进行在整个图像的调整,就是无论是lga呀,做local tmap啊。
我们可以做一个local main,就是我尽可能的让亮处暗处它的细节更加美好,我给了一个最自由的参考图,大家可以往这上面考,想一想哪个环节到底是怎么实现的,这个大家也是这个第一次作业。
好像也不大可能去实现,就是最后参考图那种效果,就大家先把这个流程跑通,然后第二节课先把基本的参数大概知道是怎么调的,然后第二次作业啊会给大家讲一个就像hdr margin这么一种方法。
然后之后就通过mod之后再去调它一个参数,可以调到一个更好的效果,这个中间结果会让助教给大家分享一下,大家可以就及时去问助教,同学还有什么问题吗,好既然没有更多的问题,感谢大家来到gz 204呃。
大家回头好好做作业,下一节课呢嗯可能会让给大家一个gas lecture,就是可能不一定是周五晚上,可能是周六上午,就具体时间我会给大家再确认一下。
就是我们会邀请一个来自berkeley的康利同学来给大家分享一下,这个we found sensing是一个什么东西,就是去做标签拨弦调试,波形调制是有非常多的应用。
这个玻纤调制就可以测整个透镜的面型啊,啊可以测这个大气的扰动啊,可以让星星是怎么闪的,来通过这么一个分享来给大家呃,就是更加的吸引下一个兴趣,这也是作为一个呃后面的一个光学的一个引子吧。
因为呃这节课之后就会给大家嗯,让伊万老师给大家分享1~2节课的一个啊这个display的这个内容,就是再加这个简单的一个pipeline,学完之后最后要显示出来怎么display。
这个display内容要给大家实时补一下,对这个开门想要曲线是每个开门,这是啥意思,对这个实时渲染里面也会用龙虎套卖品,因为我们这个渲染过程之后,他会拿到一个非常大众的范围的。
图像我想要做一个比较好的一个显示嗯,就要把亮的按了,同时显示清楚,就会也需要做一个local tmap,就现在很多很多显卡或者是游戏,我已经支持这个logo卡卖屏了。
这个我记得一个是叫什么赛博朋克2077,那个时候暗处的细节做的不是很好,然后就会呃按的地方看的不是很清晰,但后来随着技术发展,我们首先是有了一个retracing。
就是实时的一个retracing的一个技术,就是全局光照这么一个技术,让图像显得更亮,然后再加一个logo,糖奶品,把亮的按了,再那么优化一下,就是最后大家有打游戏的,时候显得这个这个非常漂亮。
啊详细虚线,你这个你不是你记错,这个问你最后处理的时候是带绕域,直接就是线性的了,那个解pd有他自己的一个标准的相应期限,大家直接查公式就可以了,如果要是公式查的觉得不准的话。
大家就可以拍一个啊这么一个就是色卡呀,或者是灰阶卡,因为汇集卡那个值都是呃线性一一对应的,然后找到这么一个这么十几个点呢,我们就可以拟合这个函数,把这个曲线给拟合出来,按标准的一些图像格式下jpg呀。
它是有自己的一个标准的一个tcp ature绕一就更简单了,饶就是线性的,就不需要标,啊对给大家说一下这个大家叫黑电瓶的时候啊,就不一定非要嗯就用到我就是整个图里面给的纸,大家叫黑电瓶的时候。
可以很仔细的调一调,可以调到小数点后几位,大家可以看一看,这个要细细的调一调,黑电平亮了,暗了都会影响色彩啊,还有最后的结果的一种感觉,这个也不是一个固定值,大家都可以去调,可以试一试,好在今天感谢。
再次感谢大家,同学们来到game 204啊,今天的时间也到了。