in unity/Assets/PostProcessingV2/Runtime/Effects/DepthOfField.cs [123:201]
public override void Render(PostProcessRenderContext context)
{
var colorFormat = RenderTextureFormat.DefaultHDR;
var cocFormat = SelectFormat(RenderTextureFormat.R8, RenderTextureFormat.RHalf);
// Avoid using R8 on OSX with Metal. #896121, https://goo.gl/MgKqu6
#if (UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX) && !UNITY_2017_1_OR_NEWER
if (SystemInfo.graphicsDeviceType == UnityEngine.Rendering.GraphicsDeviceType.Metal)
cocFormat = SelectFormat(RenderTextureFormat.RHalf, RenderTextureFormat.Default);
#endif
// Material setup
var f = settings.focalLength.value / 1000f;
var s1 = Mathf.Max(settings.focusDistance.value, f);
var aspect = (float)context.screenWidth / (float)context.screenHeight;
var coeff = f * f / (settings.aperture.value * (s1 - f) * k_FilmHeight * 2);
var maxCoC = CalculateMaxCoCRadius(context.screenHeight);
var sheet = context.propertySheets.Get(context.resources.shaders.depthOfField);
sheet.properties.Clear();
sheet.properties.SetFloat(ShaderIDs.Distance, s1);
sheet.properties.SetFloat(ShaderIDs.LensCoeff, coeff);
sheet.properties.SetFloat(ShaderIDs.MaxCoC, maxCoC);
sheet.properties.SetFloat(ShaderIDs.RcpMaxCoC, 1f / maxCoC);
sheet.properties.SetFloat(ShaderIDs.RcpAspect, 1f / aspect);
var cmd = context.command;
cmd.BeginSample("DepthOfField");
// CoC calculation pass
context.GetScreenSpaceTemporaryRT(cmd, ShaderIDs.CoCTex, 0, cocFormat, RenderTextureReadWrite.Linear);
cmd.BlitFullscreenTriangle(BuiltinRenderTextureType.None, ShaderIDs.CoCTex, sheet, (int)Pass.CoCCalculation);
// CoC temporal filter pass when TAA is enabled
if (context.IsTemporalAntialiasingActive())
{
float motionBlending = context.temporalAntialiasing.motionBlending;
float blend = m_ResetHistory ? 0f : motionBlending; // Handles first frame blending
var jitter = context.temporalAntialiasing.jitter;
sheet.properties.SetVector(ShaderIDs.TaaParams, new Vector3(jitter.x, jitter.y, blend));
int pp = m_HistoryPingPong[context.xrActiveEye];
var historyRead = CheckHistory(context.xrActiveEye, ++pp % 2, context, cocFormat);
var historyWrite = CheckHistory(context.xrActiveEye, ++pp % 2, context, cocFormat);
m_HistoryPingPong[context.xrActiveEye] = ++pp % 2;
cmd.BlitFullscreenTriangle(historyRead, historyWrite, sheet, (int)Pass.CoCTemporalFilter);
cmd.ReleaseTemporaryRT(ShaderIDs.CoCTex);
cmd.SetGlobalTexture(ShaderIDs.CoCTex, historyWrite);
}
// Downsampling and prefiltering pass
context.GetScreenSpaceTemporaryRT(cmd, ShaderIDs.DepthOfFieldTex, 0, colorFormat, RenderTextureReadWrite.Default, FilterMode.Bilinear, context.width / 2, context.height / 2);
cmd.BlitFullscreenTriangle(context.source, ShaderIDs.DepthOfFieldTex, sheet, (int)Pass.DownsampleAndPrefilter);
// Bokeh simulation pass
context.GetScreenSpaceTemporaryRT(cmd, ShaderIDs.DepthOfFieldTemp, 0, colorFormat, RenderTextureReadWrite.Default, FilterMode.Bilinear, context.width / 2, context.height / 2);
cmd.BlitFullscreenTriangle(ShaderIDs.DepthOfFieldTex, ShaderIDs.DepthOfFieldTemp, sheet, (int)Pass.BokehSmallKernel + (int)settings.kernelSize.value);
// Postfilter pass
cmd.BlitFullscreenTriangle(ShaderIDs.DepthOfFieldTemp, ShaderIDs.DepthOfFieldTex, sheet, (int)Pass.PostFilter);
cmd.ReleaseTemporaryRT(ShaderIDs.DepthOfFieldTemp);
// Debug overlay pass
if (context.IsDebugOverlayEnabled(DebugOverlay.DepthOfField))
context.PushDebugOverlay(cmd, context.source, sheet, (int)Pass.DebugOverlay);
// Combine pass
cmd.BlitFullscreenTriangle(context.source, context.destination, sheet, (int)Pass.Combine);
cmd.ReleaseTemporaryRT(ShaderIDs.DepthOfFieldTex);
if (!context.IsTemporalAntialiasingActive())
cmd.ReleaseTemporaryRT(ShaderIDs.CoCTex);
cmd.EndSample("DepthOfField");
m_ResetHistory = false;
}