URP把后处理分成了两个pass,finalPass只在相机抗锯齿模式为FastApproximateAntialiasing时调用。
开启条件,在ForwardRenderer判断
lastCameraInTheSatck。这名字有误导性,取的值是RenderingData的resolveFinalTarget,而resolveFinalTarget是在InitializeRenderingData函数设置的,取的值是requiresBlitToBackbuffer,InitializeRenderingData被RenderSingleCamera调用。requiresBlitToBackbuffer会在scene相机渲染,以及stack的最后一个相机设为true。这个参数的真正意义,我的理解是表示这个相机是否要渲染到屏幕上,如果要渲染到屏幕,再去判断相机是否开启后处理。后处理已经把画面渲染到屏幕上了,所以finalBlitPass不需要执行。bool applyFinalPostProcessing = anyPostProcessing && lastCameraInTheStack &&renderingData.cameraData.antialiasing == AntialiasingMode.FastApproximateAntialiasing;
applyFinalPostProcessing:为true的条件,相机开启后处理,并且lastCameraInTheStack为true、抗锯齿模式为FastApproximateAntialiasing。applyPostProcessing:只要相机开启后处理就为true。如果lastCameraInTheStack为true,会设置渲染目标rt,并设置是否需要对sRGB做转换。PostProcessPass,驱动各个后处理shader
数据
MaterialLibrary:定义实现各个效果的material。PostProcessData:ScriptableObject,配置shader和贴图。在editor可以创建ScriptableObject的实例,但是并不能编辑shader,可能是个未开发完的功能。ShaderConstants:缓存shader名字对应的id。RenderFinalPass,渲染final pass
var material = m_Materials.finalPass;
获取material,用于后续渲染。
if (cameraData.antialiasing == AntialiasingMode.FastApproximateAntialiasing)
material.EnableKeyword(ShaderKeywordStrings.Fxaa);
逻辑上来说判断抗锯齿模式是多余的,只有fxaa才会用这个分支渲染。
SetupGrain(cameraData, material);
SetupDithering(cameraData, material);
如果对应效果开启,设置shader关键字或贴图,shader用的是finalPass。这俩并不对应具体的shader。
Render函数
Render函数里有个有趣的写法,int GetSource() => source;类似这种,在函数内定义函数。
这个函数按顺序渲染各个后处理效果,简单看下流程。
cmd.Blit(GetSource(), BlitDstDiscardContent(cmd, GetDestination()), m_Materials.stopNaN);
最先渲染的是一个特殊的NaNshader,可选的,作用是将不合法的颜色值用自定义的颜色输出,应该是调试用的,判断颜色是否合法的代码在CoreRP的Common.hlsl文件。DoSubpixelMorphologicalAntialiasing(ref cameraData, cmd, GetSource(), GetDestination());
处理SubpixelMorphological模式的抗锯齿,消耗较大,移动平台使用要看情况。DoDepthOfField(cameraData.camera, cmd, GetSource(), GetDestination(), cameraData.pixelRect);
对scene camera不开启。Gaussian和Bokeh两种模式DoMotionBlur(cameraData.camera, cmd, GetSource(), GetDestination());
对scene camera不开启。是相机的运动模糊,物体运动是没有效果的。DoPaniniProjection(cameraData.camera, cmd, GetSource(), GetDestination());
对scene camera不开启。帕尼尼投影,一种圆柱形投影,效果是扭曲两侧,突出中间,在渲染大视角的时候提供更好的效果。后面的都和UberPost shader相关
void SetupBloom(CommandBuffer cmd, int source, Material uberMaterial)
先按分辨率大小计算模糊次数,每次水平竖直分别模糊,没吃降低一倍分辨率,然后在执行Upsample,完成bloom。设置bloom相关参数和贴图到UberPost shader。设置lens dirtiness相关参数到uber。SetupLensDistortion(m_Materials.uber, cameraData.isSceneViewCamera);
镜头扭曲效果,设置uber shader的参数。SetupChromaticAberration(m_Materials.uber);
比较高性能的色差效果。SetupVignette(m_Materials.uber);
图像边缘的色调变暗,突出中间部分。SetupColorGrading(cmd, ref renderingData, m_Materials.uber);
改变或矫正最终图像的颜色和亮度,处理lut、hdr、tonemappingSetupGrain(cameraData, m_Materials.uber);
SetupDithering(cameraData, m_Materials.uber);
在不是final pass的情况下执行。cmd.SetGlobalTexture("_BlitTex", GetSource());
rt设置给_BlitTex。cmd.SetRenderTarget(cameraTarget, colorLoadAction, RenderBufferStoreAction.Store, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.DontCare);
设置rt为相机,完成渲染。这些常见的后处理效果,都有比较成熟的算法,具体逻辑就不细看了。
URP的代码大致看了一遍,还有些地方看的不够深,也没完全理解所有细节,以后unity有了新版本,以及有了更深的理解再来补上。
中国有句俗话:没有金刚钻就别揽瓷器活!网上打麻将的人高手不在少数,因此,没有两把刷子的人去哪里打麻将纯粹是去当送财童子的。当然博彩论坛排名,如果你说的钱多到没有地方花博彩论坛排名,那我也只能呵呵了。