百人计划(程序)3

第四章 高级扩展

一、Bloom算法

  • Bloom算法介绍

        1.Bloom概述:Bloom效果可以用来模拟真实世界中,摄像机的一种图像效果,它可以让画面中比较亮的区域扩散到周围的区域中,来达到一种朦胧的效果,并且能让我们的眼睛感知到这些区域是比较亮的。

        2.实现思路

                ①通过一个预先设定的阈值去提取原图像中比较亮的区域

                ②利用高斯模糊对提取后的图像进行模糊处理

                ③将模糊后的图像与原图像进行一个混合,得到最终的Bloom效果

         3.前置知识:

                ①HDR与LDR

        (1)LDR(Low Dynamic Range,低动态范围):JPG、PNG等格式的图片,以及日常生活中使用的手机、显示器、摄像机这些设备的输入与输出均为LDR,因为LDR只能存储RGB范围在0到1之间的值,但在现实世界中,只用0到1范围内的值去表达真实世界中的色彩是远远不够的,意味着会存在精度的丢失。

        (2)HDR(High Dynamic Range,高动态范围):HDR允许我们表示超过0到1之间的亮度值,进而可以更加精确地反映真实的光照效果,实现Bloom效果的第一步就是利用阈值去提取原图像中比较亮的区域,如果不使用HDR的话,我们就只能提取亮度小于1的区域,并且像路灯发亮的亮度值可能会与某个区域的亮度值一致,这样就会导致这个区域也出现Bloom效果;但如果使用HDR的话,则可以提取亮度大于1的区域,这样就能让更亮的区域产生Bloom效果,所以,提取较亮区域有时候是针对开启HDR来实现的。

                ②高斯模糊

        高斯模糊(Gaussian Blur):它是实现图像模糊的一种方式,它的本质是通过高斯函数去定义一个卷积核,这个卷积核叫做高斯核,再利用这个高斯核对图像进行卷积运算,得到“平滑”后的图像,也就是俗称的模糊。(图像处理课设)

  • Bloom算法实现

  • Bloom算法应用

二、SSAO算法:屏幕空间环境光遮蔽算法

  • SSAO介绍和原理

        1.AO:即环境光遮蔽,全称Ambient Occlusion,是计算机图形学中的一种着色和渲染

技术,模拟光线达到物体的能力的粗略的全局方法,描述光线到达物体表面的能力。

        2.SSAO:屏幕空间环境光遮蔽,全称Screen Space Ambient Occlusion,一种用于计

算机图形中实时实现近似环境光遮蔽效果的渲染技术。通过获取像素的深度缓冲、

法线缓冲来计算实现,来近似的表现物体在间接光下产生的阴影。

        3.SSAO原理

                ①获取屏幕中像素的深度缓冲(用于重构像素相机空间中的坐标(Z),来近似重构该视

点下的三维场景)、法线缓冲(相机空间中的法线信息,用于重构每个像素的“法线-切线-副法线”

构成的坐标轴,用于计算法线半球中的采样随机向量)

                ②通过深度缓冲值计算像素坐标

                ③在着色点法线方向的上半部分随机采样点(随机向量用于判断和描述该像素的AO强度)

                ④计算随机后的坐标信息(多次采样),并比较随机采样点的深度值和着色点的深度值,对AO进行加权计算

                ⑤合成AO,后期处理优化(模糊等)

*法线半球(图1):黑色表示我们需要计算的样本;蓝色向量表示样本的法向量;白色、灰色为采样点(很明显,采样点的多少影响最后的渲染的效果),其中灰色表示被挡采样点(深度大于周围,说明采样点被遮蔽的光的部分比较多),据此判断最终Ao的强度。

        图2表示法向球形采样(后背抛弃),原因是该方式采样导致平整的墙面也会显得灰蒙蒙的因为核心中一半的样本都会在墙这个几何体上

图1
图2

补充:游戏后期特效第四发 -- 屏幕空间环境光遮蔽(SSAO) - 知乎 (zhihu.com)

  • SSAO算法实现*

        1.获取深度&法线缓冲数据:

        2.重建相机空间坐标

         PS:重建方法较多,附上参考链接:https://zhuanlan.zhihu.com/p/92315967         

        本例实现使用其中的“从NDC空间中重建”方法得到样本在相机空间中的向量,乘以深度值得到样本的坐标。

        3.构建法向量正交基

         4.AO采样核心

  • SSAO效果改进

        1.随机正交基(增加随机性)

         2.AO累加平滑优化

         3.模糊(该方面只展示下前后效果对比)

  • 比对模型烘焙AO

        1.三维建模软件烘焙AO方式:通过三维建模软件(如3DMax),设定好渲染参数,对模型(单一选择模型实体),烘焙AO到纹理。

                ①优点:

        (1)单一物体可控性强(通过单一物体的材质球上的AO纹理贴图),可以控制单一物体的AO的强弱;

        (2)弥补场景烘焙的细节,整体场景的烘焙(包含AO信息),并不能完全包含单一物体细节上的AO,而通过三维建模软件烘焙到纹理的方式,增加物体的AO细节;

        (3)不影响其(Unity场景中)静态或者动态;

                ②缺点:

        (1)操作较其他方式繁琐,需要对模型进行UW处理,再进行烘焙到纹理;

        (2)不利于整体场景的整合(如3DMax烘焙到纹理,只能选择单一物体,针对整体场景的处理工作量巨大);

        (3)增加AO纹理贴图,不利于资源优化(后期可通过其他纹理通道利用整合资源);

        (4)只有物体本身具有AO信息,获取物体之间的AO信息工作量巨大(不是不可能)。

        2.游戏引擎烘焙AO方式(Unity3D Lighting):通过Unity的Lighting功能(主菜单/Window/Rendering/Lighting Settings)进行整体场景的烘焙,AO信息包含于此。

                ①优点:

        (1)操作简易,整体场景的烘焙,包含AO的选择;

        (2)不受物体本身的UW影响,Unity通过Generate Lightmap UVs生成模型第二个纹理坐标数据;

        (3)可生成场景中物体与物体之间的AO信息;

                ②缺点:

        (1)缺少单一物体的细节(可调整参数提高烘焙细节,但换之将增加烘焙纹理数量和尺寸,以及烘焙时间);

        (2)受物体是否静态影响,动态物体无法进行烘焙,获得AO信息。

        3.SSAO方式:

                ①优点:

        (1)不依赖场景的复杂度,其效果质量依赖于最终图片像素大小;

        (2)实时计算,可用于动态场景;

        (3)可控性强,灵活性强,操作简单;

                ②缺点:

        (1)性能消耗较之上述2种方式更多,计算非常昂贵;

        (2)AO质量上要比较离线式烘焙(上述2种)不佳(理论上)。

  • SSAO性能消耗

        1.AO法向半球的随机采样:

        2.双边滤波的多重采样:

三、实时阴影

  • 阴影概念

        1.阴影:当来自光源的至少一个点在空间中被遮挡时,就产生了阴影区域。

        2.阴影体(Shadow Volumes):空间中黑暗部分的集合。

        3.阴影映射(shdow map):在场景中没有被光源照到的地方。

  • 基于图片实时阴影技术

        1.平面投影阴影:根据光的方向,把物体的每个顶点投影到平面上。(相似三角形)

            缺点:只能投影到平面;投影物体必须在光线和平面之间。

        2.曲面投影映射:

                ①把每一个阴影投影体设置一个相机

                ②把阴影投影体渲染到阴影纹理中

                ③在渲染阴影接收者时,把上一步的阴影纹理进行合并混合

         投影阴影——在unity中的实现:

        2.阴影映射(Shadow Mapping)

Shadow Map:从光源的位置渲染得到的深度图
摄像机视角图

                ①具体流程:参考(https://www.bilibili.com/read/cv15744331/ )

        从光的位置渲染深度图片,使用一个来自光源的透视图和投影矩阵得到深度图/阴影贴图(shadowmap),投影矩阵和视图矩阵结合在一起即T变换,可以将任何三维位置转变到光源的可见坐标空间。                      

         从摄像机位置渲染物体,例如片元P,使用T变换将P变换到光源坐标空间,深度值大于ShadowMap中记录的深度值,则片元P位于阴影中。

                ②Unity中的屏幕空间阴影映射:

  • 阴影映射的优化

        1.阴影映射自阴影问题

                ①原因:因为阴影映射的分辨率有限,离散的采样点以及数值上的偏差可能造成不正确的自遮挡效果,也被称为Z-Fighting/阴影粉刺(Surface Acne)。

                下图左图,阴影映射纹理采样时,物体着色点表面落差较大的两端的对应的阴影映射的值是一样的,这种误差导致自阴影。

                提高阴影映射分辨率(不行,因为现在很多游戏的可视范围很大,阴影映射的分辨率增加比不上场景;很多平台对纹理的最大尺寸是有限的。)--->深度偏移

               ②解决方法:设置容错阈值(深度偏移 Depth Bias / 法线偏移 Normal Bias)

                   Peter Panning:设置的深度偏移过大时,会出现阴影与投影体之间脱节并漏光的现象。

                 深度偏移:

        夹角中采样的阴影映射值是一样的,蓝色的点是摄像机视角下的物体表面采样到的深度值,把红点阴影映射的深度值加上这一段误差的深度值,则此时的阴影映射的深度值就等于摄像机视角下的深度值, 就不算在阴影区域里了。(疑问:如何判断是物体表面,而不是阴影区域???)   

        但对于红色采样点上半部分,加上一段,阴影很有可能脱节(?)。

        总结:很难适配到整个场景,只能尽量微调来适应场景;

                   深度偏移会使该像素向光源靠近;

                   在unity中需要个Bias赋值,单位是阴影映射的纹素,例如当你的阴影映射分辨率是512,1个单位的深度偏移就是1/512,bias是在逐像素渲染中,阴影深度测试时使用,对物体的发下没有影响。

                 法线偏移:也是为了解决阴影瑕疵,但是是沿着表面的法线方向向外偏移。

                ③Unity中实现自阴影的优化

        在生成阴影纹理时,即阴影映射使用时,是相对应的。unity是在生成阴影纹理的阶段做的bias,因此是反向去偏移,就是需要减去误差值。性能高,但没有特别精准。

        2.阴影映射走样问题(导致阴影锯齿)

                阴影映射有两个阶段:初始采样(渲染阴影映射阶段);重采样(从摄像机视角对阴影映射进行采样的阶段)

                ①初始采样的问题——透视走样:

                        原因:a和b的阴影映射分辨率是差不多的,但透视后b的阴影出现了走样。

                         解决方案:

        思路1:因为我们在使用shadowmap时,相机是经过透视投影的,但生成shadowmap时并没有经过透视投影,所以我们在生成shadowmap时就进行一次透视投影。

        思路2:尽量减少近平面和远平面之间的像素差距,Unity中的级联阴影映射就是用的这个思路。

                ②重采样误差:

四、抗锯齿

  • 锯齿产生的原因

        在几何阶段到光栅化阶段逐像素时,选择需要的像素导致出现锯齿。

        解决方案:让边缘的像素的颜色和背景色混合渐变。

  • 基本的抗锯齿手段

        1.SSAA超采样抗锯齿(Super Sample Anti-aliasing):

        最早期的全屏抗锯齿,超级采样抗锯齿就是把当前分辨率成倍提高,然后再把画缩放到当前的显示器上。

        这样的做法实际上就是在显示尺寸不变的情况提高分辨率,让单个像素变得极小,这样就能够大幅减轻画面的锯齿感了。不过是由于对整个显示画面的放大,因此它消耗的显示资源也是非常大的

         2.MSAA多重采样(Multi sample Anti-aliasing)

                ①概述:在光栅化阶段,判断采样点的颜色时,增加了采样点,最后根据光栅化阶段记录覆盖的样本的百分比在片元着色器中输出最终的颜色。

                布置的采样点越多,抗锯齿效果越好,但是计算的性能消耗也会增大。

                ②缺点:

        1、MSAA在与HDR一起使用时可能会产生问题,必须进行专门处理。

        2、由于MSAA是在光栅化阶段对图元进行超采样,因此它只能解决几何走样现象(即物体轮廓地锯齿),不能解决着色走样(高光闪点)问题。

        3、延迟渲染无法支持MSAA。

  • 抗锯齿升级版

        1.TAA时间抗锯齿(Temporal Anti-Aliasing):

                ①具体实现步骤:

        1.把多次采样的过程分布到每一帧中去,每一帧都平均前面几帧保存下来的数据。(像素就只用采样一次)

        2.每一帧会有一定的偏移,继承了MSAA采样。

        3.用motion vector保存每帧移动的偏移。(视角移动之后,原先的部分只有一部分重复,这个时候要计算移动的方向,再用矩阵去判断哪些地方是重复的可以复用。新出现的地方就要从第0帧开始重新计算,不与之间的结果平均。)

                ②效果更好,速度更快,但计算更复杂。

        2.FXAA快速近似抗锯齿(Fast Approximate Anti-Aliasing)

                 ①步骤:

                        1.利用边缘检测有效的模糊混合(在画面完全渲染后进行处理,利用卷积进行描边,即边缘检测,然后把边缘提取出来进行模糊,最后和原图混合)。

                        2.在后处理完成不依赖硬件支持。

  • 抗锯齿速度排序

  •  更多抗锯齿

 【Metal2研发笔录(七):抗锯齿之基于A11 Imageblock特性的增强MSAA - 知乎 (zhihu.com)

五、DOF景深算法

  • 景深概述(Depth Of Field)

        ①景深(DOF):是指在摄影机镜头或其他成像器前沿能够取得清晰图像的成像所测定的被摄物体前后距离范围。光圈、镜头、及焦平面到拍摄物的距离是影响景深的重要因素。

         ②原因:

  • 景深的作用

        1.选择性的突出或者强调画面中的一部分,例如某个物体或者某个人物,吸引观察者的注意力到画面中清晰对焦的部分,而忽略其他的模糊部分的细节。

        2.强调所拍摄场景的深度,增加画面的层次立体感。

        3.艺术意境的表达。摄影师可以利用景深效果,营造出虚幻、梦境、或者神奇等意境。

        4.表示主观的视线。在电影学中,通过调节浅景深的镜头,使之对焦在不同位置上,来表示某个人的主观视线的转移。

        5.交代人物之间的关系。在电影学中,通过景深聚焦位置的变化,来表达前景和背景人物之间的关系。

  • 移动端景深效果实现

        1.景深是在光栅化阶段后的屏幕图像后处理阶段,在帧缓冲中可以返回shader中对图像进行整体处理。

        2.制作思路:模拟景深制作一张mask → 渲染一张模糊场景 → 渲染一张正常场景 → 合并图像用景深mask做一张插值

  • 高级景深效果思路拓展

             ①景深渲染中出现的三种情况的示意图以及相对应的滤波核;(a) : p 点在背景区域(扩散滤波) (b) : p 点在前景区域(聚合滤波) (c) : p 点在聚焦区域。

                对不同区域进行不同的滤波处理/插值算法。

                ②缺陷:

                        颜色泄露缺陷

        后处理时,对焦区域之外区域的模糊处理过程中,将模糊的背景颜色叠加在聚焦区域之上,或者前景聚焦区域的颜色混合到了模糊背景中。(解决:使用扩散滤波,将每个像素点的颜色扩散到这个像素点的模糊圈的范围中)

                 模糊不连续缺陷

        焦点在背景区域时,前景会有截断的现象。(背景的光圈为0,焦点的像素为0,前景区域大于0,过渡就会很生硬)

        解决方案:前景和背景进行区分,把前景的模糊单独拿出来计算,制作一个mask再与背景进行混合。

                 散景的模拟(Bokeh):

        散景效果在背景有高光时最为显著,比如夜景灯光、镜面反射高光等,因为高光区域亮度会比场景其他物体大,一般会超出拍摄时设定的相应范围,造成强度值的溢出截断,在进行景深渲染时要做特殊处理。

        在背景滤波的基础上,使用点函数来模拟散景效果,因为光源在不同参数下成像效果不一样,所以选用不一样的点函数。

六、雾效——大气散射

  • 大气散射

        1.实际效应:大气散射是对现实世界大气现象的描述,其影响包括不限于白天和傍晚天际线的大气颜色不同丁达尔现象的产生人眼对于地球大气层的视觉感受。而对于追求“真实”的CG领域来说大气散射则显得尤为重要,决定了大气层的真实与否。

        2.分类:

                ①瑞利散射:影响天空颜色的主要因素。瑞利散射函数是一个经验公式:λ是光的波长,n是空气折射率,N是海平面处的大气密度ρ(h)是高度h处的相对大气密度,即相对于海平面的密度,可以理解成h处真正的大气密度与海平面处大气密度的比值。

                ②米氏散射:日常生活中随处可见的丁达尔效应实则就是米氏散射的现实作用。自然体积光的部分具体实现也有很多办法,例如光线步进,广告牌等等。

                ③拉曼散射(由于拉曼散射对于大气的影响在计算机中结果计算贡献过小因而图形学领域少有人研究拉曼散射。)

        3.实时渲染领域大气散射相关的发展:

                ①非预计算实现大气散射阶段

                ②预计算实现大气散射阶段

  • 大气散射基本过程

        1.散射的分类:外散射和内散射

         2.简单的大气散射模型:

                ①数学化描述:太阳的传输大致有两个阶段,一个是宇宙阶段,一个是大气阶段宇宙阶段我们假设是真空条件,并不会减少光的传输量。而c到p的过程中是会发生光照衰减的,会减少光照量。定义一个透射率函数:

                散射函数:(只由瑞利散射函数推出)

                 总结:该数学模型的问题:  透射函数过程描述不清,光线的行为过于简单。

                ②想象一下现实世界的光线过程,是无数条光线来到了人眼之中,而无数条光线也进行了无数次的散射。所以先假设有无数条光线也就应该有无数个散射点

        用平行光进行近似,为了计算简单,就不考虑太阳光的偏转的,都设定为一样的光照方向。ds的处理让离散近似为连续。

        总结:到这里,已经建立了一个大气散射的最基本的模型。并且每一条光线的散射事件

也仅仅只有一次,这样的散射事件,称之为:单散射。

        遗留问题如下:1.透射过程如何  2.米氏散射如何进行  3.多重散射如何进行。

  •  大气散射原理推导(关于米氏散射和瑞利散射进行一下简单的推导)

        1.瑞利散射函数:

                ①函数方程:

        2.米氏散射方程

  • 大气散射非预计算实现

        1.确定渲染模型

         2.散射相位函数的实际处理

         3.密度积分:

         4.内散射方程:

         5.表面散射方程:

  • 大气散射预计算实现

        1.Lut图:

                LUT英文的全称是Look Up Table,其简称就是Lut表,本质就是一张颜色查找表是一种降低GPU运算量的技术,通过事先把颜色值存储在一张缓存表中,当需要运算的时候,直接从这张表去拿索引对应的颜色值,本质就是拿存储空间换运算时间的算法应用,常用的领域其实图像调色的领域,而在计算图形的领域也有不小的应用,例如之前米哈游就公开的卡通渲染技术当中就用到了Lut技术。

        Lut被分为1DLut和3DLut。本质区别在于索引输出值所需要的索引数,1D的自然就是用单个变量进行索引,而我们的3DLut自然就是用三个变量进行索引,大气散射计算的Lut自然也应该是3D的。

 

         2.最终散射函数:

        总结:初始化场景的相机远平面要保证足够的距离,不然会有奇怪的现象。例如黑条等等。同时为了提高效率,也可以降低对Lut的采样。

 游戏魔法编程:unity实现完整大气散射 - 知乎 (zhihu.com)

 七、基于屏幕空间的溶解

技术分享:《Trifox》中的遮挡处理和溶解着色器(上) - 简书 (jianshu.com)

技术分享 :《Trifox》中的遮挡处理和溶解着色器(下) - 简书 (jianshu.com)

猜你喜欢

转载自blog.csdn.net/weixin_56784984/article/details/128506136