hdrp对ao的做法是gtao(Ground Truth Ambient Occlusion)的做法。通过AmbientOcclusion.cs,执行Render的时候,Dispatch,在里面PrepareRenderAOParameters创建ao的参数,包括执行的computeshader的内核。
GTAO获取ao信号
RenderAO执行gtao,执行到Runtime/Lighting/ScreenSpaceLighting/GTAO.compute。GTAOMain中通过GetPositionVS获取NDC空间信息。fovCorrectedradiusSS存储与ndc的z轴负相关的信息,也就是越远,这个值越小。
然后按照配置的_AODirectionCount执行循环,沿着观察方向在配置的切片_AODirectionCount上寻找两端未被遮挡住的角度,称为水平角HorizonLoop。
HorizonLoop两边的水平角获取
HorizonLoop中_AOStepCount循环获取每隔一定距离获取他的ndc坐标
然后减去原本的中心ndc坐标,然后获取最大的水平角。
两边都执行获取水平角记录在xy轴上
法线投影到切面得到ao
然后需要将将物体表面的法线投影到切面上
将所有切面上得到的值进行积分,就得到最终的AO值。
gtao抗锯齿
计算出ao后第二步是在c#中执行DenoiseAO,执行到Runtime/Lighting/ScreenSpaceLighting/GTAOTemporalDenoise.compute,这一步是类似taa的速度上的抗锯齿,
因为之前保存过速度信息,所以这里DecodeMotionVector(LOAD_TEXTURE2D_X(_CameraMotionVectorsTexture, closest), motionVector);可以获取到速度贴图信息。然后通过当前uv减去这个速度贴图参数就是上一帧的数据prevFrameNDC = uv - motionVector;
然后UnpackHistoryData中获取上一帧的AO,mvLen速度参数,上一帧的depth。
通过当前帧与上一帧的变化权重更新历史ao。
以及输出当前帧的抗锯齿的ao
模糊和升采样的四个周边信息准备
最后通过UpsampleAO,执行Runtime/Lighting/ScreenSpaceLighting/GTAOBlurAndUpsample.compute
这里会执行模糊处理以及升采样处理。
执行BlurHorizontally,
里面获取周围横向7个ao信息以及7个深度信息,获取相互间的差值,然后执行SmartBlur
SmartBlur里面主要对左右的判定然后取均值模糊。
BlurHorizontally会记录下AOCache2。
BlurVertically则是相反,获取纵向的ao均值信息。
然后LoSSAOs记录周边的模糊后的ao信息
然后通过_OcclusionTexture记录ao周边的ao权重值,这四个权重值是升采样时可以获取到的从一个像素到四个像素的其他像素的权重信息。
BilateralUpsample在这里基本上需要5个权重:每个低分辨率像素4个,当4个都不匹配时,1个进行混合。过滤器强度为1/DeltaZTolerance。因此,0.01的公差将产生100的强度。从低到高深度的完美匹配将产生10^6的权重,完全取代任何噪声过滤。当高分辨率深度缓冲区中有许多小孔导致低分辨率深度缓冲区不准确地表示时,噪声滤波器旨在软化闪烁的影响。
上面这里9,3,1,3是16个权重信息,对应的是说LowAO中的权重信息比值。得到权重信息WeightedSum。