void PushDebug(PostProcessRenderContext context)
 {
     if (context.IsDebugOverlayEnabled(DebugOverlay.AmbientOcclusion))
     {
         context.PushDebugOverlay(context.command, m_AmbientOnlyAO, m_PropertySheet, (int)Pass.DebugOverlay);
     }
 }
        void RebuildCommandBuffers(PostProcessRenderContext context)
        {
            var cmd = context.command;

            // Update the base dimensions and reallocate static RTs.
            RTHandle.SetBaseDimensions(
                context.width * (RuntimeUtilities.isSinglePassStereoEnabled ? 2 : 1),
                context.height
                );

            m_PropertySheet.properties.SetVector(ShaderIDs.AOColor, Color.white - m_Settings.color.value);

#if !UNITY_2017_1_OR_NEWER
            m_TiledDepth1.AllocateNow();
            m_TiledDepth2.AllocateNow();
            m_TiledDepth3.AllocateNow();
            m_TiledDepth4.AllocateNow();
#endif

            m_Result.AllocateNow();

            PushDownsampleCommands(context, cmd);

            m_Occlusion1.PushAllocationCommand(cmd);
            m_Occlusion2.PushAllocationCommand(cmd);
            m_Occlusion3.PushAllocationCommand(cmd);
            m_Occlusion4.PushAllocationCommand(cmd);

            float tanHalfFovH = CalculateTanHalfFovHeight(context);
            PushRenderCommands(context, cmd, m_TiledDepth1, m_Occlusion1, tanHalfFovH);
            PushRenderCommands(context, cmd, m_TiledDepth2, m_Occlusion2, tanHalfFovH);
            PushRenderCommands(context, cmd, m_TiledDepth3, m_Occlusion3, tanHalfFovH);
            PushRenderCommands(context, cmd, m_TiledDepth4, m_Occlusion4, tanHalfFovH);

            m_Combined1.PushAllocationCommand(cmd);
            m_Combined2.PushAllocationCommand(cmd);
            m_Combined3.PushAllocationCommand(cmd);

            PushUpsampleCommands(context, cmd, m_LowDepth4, m_Occlusion4, m_LowDepth3, m_Occlusion3, m_Combined3);
            PushUpsampleCommands(context, cmd, m_LowDepth3, m_Combined3, m_LowDepth2, m_Occlusion2, m_Combined2);
            PushUpsampleCommands(context, cmd, m_LowDepth2, m_Combined2, m_LowDepth1, m_Occlusion1, m_Combined1);
            PushUpsampleCommands(context, cmd, m_LowDepth1, m_Combined1, m_LinearDepth, null, m_Result);

            if (context.IsDebugOverlayEnabled(DebugOverlay.AmbientOcclusion))
            {
                context.PushDebugOverlay(cmd, m_Result.id, m_PropertySheet, (int)Pass.DebugOverlay);
            }
        }
Beispiel #3
0
        private void Render(PostProcessRenderContext context, CommandBuffer cmd, int occlusionSource)
        {
            DoLazyInitialization(context);
            m_Settings.radius.value = Mathf.Max(m_Settings.radius.value, 0.0001f);
            bool          flag          = m_Settings.quality.value < AmbientOcclusionQuality.High;
            float         value         = m_Settings.intensity.value;
            float         value2        = m_Settings.radius.value;
            float         z             = (!flag) ? 1f : 0.5f;
            float         w             = m_SampleCount[(int)m_Settings.quality.value];
            PropertySheet propertySheet = m_PropertySheet;

            propertySheet.ClearKeywords();
            propertySheet.properties.SetVector(ShaderIDs.AOParams, new Vector4(value, value2, z, w));
            propertySheet.properties.SetVector(ShaderIDs.AOColor, Color.white - m_Settings.color.value);
            if (context.camera.actualRenderingPath == RenderingPath.Forward && RenderSettings.fog)
            {
                propertySheet.EnableKeyword("APPLY_FORWARD_FOG");
                propertySheet.properties.SetVector(ShaderIDs.FogParams, new Vector3(RenderSettings.fogDensity, RenderSettings.fogStartDistance, RenderSettings.fogEndDistance));
            }
            int num = (!flag) ? 1 : 2;
            int occlusionTexture = ShaderIDs.OcclusionTexture1;
            int widthOverride    = context.width / num;
            int heightOverride   = context.height / num;

            context.GetScreenSpaceTemporaryRT(cmd, occlusionTexture, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear, FilterMode.Bilinear, widthOverride, heightOverride);
            cmd.BlitFullscreenTriangle(BuiltinRenderTextureType.None, occlusionTexture, propertySheet, occlusionSource);
            int occlusionTexture2 = ShaderIDs.OcclusionTexture2;

            context.GetScreenSpaceTemporaryRT(cmd, occlusionTexture2, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
            cmd.BlitFullscreenTriangle(occlusionTexture, occlusionTexture2, propertySheet, 2 + occlusionSource);
            cmd.ReleaseTemporaryRT(occlusionTexture);
            cmd.BlitFullscreenTriangle(occlusionTexture2, m_Result, propertySheet, 4);
            cmd.ReleaseTemporaryRT(occlusionTexture2);
            if (context.IsDebugOverlayEnabled(DebugOverlay.AmbientOcclusion))
            {
                context.PushDebugOverlay(cmd, m_Result, propertySheet, 7);
            }
        }
Beispiel #4
0
        public override void Render(PostProcessRenderContext context)
        {
            // The coc is stored in alpha so we need a 4 channels target. Note that using ARGB32
            // will result in a very weak near-blur.
            var colorFormat = context.camera.allowHDR ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.ARGB32;
            var cocFormat   = SelectFormat(RenderTextureFormat.R8, RenderTextureFormat.RHalf);

            // Material setup
            float scaledFilmHeight = k_FilmHeight * (context.height / 1080f);
            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) * scaledFilmHeight * 2f);
            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;
        }
Beispiel #5
0
        public override void Render(PostProcessRenderContext context)
        {
            var cmd = context.command;

            cmd.BeginSample("BloomPyramid");

            var sheet = context.propertySheets.Get(context.resources.shaders.bloom);

            // Apply auto exposure adjustment in the prefiltering pass
            sheet.properties.SetTexture(ShaderIDs.AutoExposureTex, context.autoExposureTexture);

            // Negative anamorphic ratio values distort vertically - positive is horizontal
            float ratio = Mathf.Clamp(settings.anamorphicRatio, -1, 1);
            float rw    = ratio < 0 ? -ratio : 0f;
            float rh    = ratio > 0 ?  ratio : 0f;

            // Do bloom on a half-res buffer, full-res doesn't bring much and kills performances on
            // fillrate limited platforms
            int tw = Mathf.FloorToInt(context.screenWidth / (3f - rw));
            int th = Mathf.FloorToInt(context.screenHeight / (1f - rh));

            // Determine the iteration count
            int   s           = Mathf.Max(tw, th);
            float logs        = Mathf.Log(s, 2f) + Mathf.Min(settings.diffusion.value, 10f) - 10f;
            int   logs_i      = Mathf.FloorToInt(logs);
            int   iterations  = Mathf.Clamp(logs_i, 1, k_MaxPyramidSize);
            float sampleScale = 0.5f + logs - logs_i;

            sheet.properties.SetFloat(ShaderIDs.SampleScale, sampleScale);

            // Prefiltering parameters
            float lthresh   = Mathf.GammaToLinearSpace(settings.threshold.value);
            float knee      = lthresh * settings.softKnee.value + 1e-5f;
            var   threshold = new Vector4(lthresh, lthresh - knee, knee * 2f, 0.25f / knee);

            sheet.properties.SetVector(ShaderIDs.Threshold, threshold);

            int qualityOffset = settings.fastMode ? 1 : 0;

            // Downsample
            var lastDown = context.source;

            for (int i = 0; i < iterations; i++)
            {
                int mipDown = m_Pyramid[i].down;
                int mipUp   = m_Pyramid[i].up;
                int pass    = i == 0
                    ? (int)Pass.Prefilter13 + qualityOffset
                    : (int)Pass.Downsample13 + qualityOffset;

                context.GetScreenSpaceTemporaryRT(cmd, mipDown, 0, context.sourceFormat, RenderTextureReadWrite.Default, FilterMode.Bilinear, tw, th);
                context.GetScreenSpaceTemporaryRT(cmd, mipUp, 0, context.sourceFormat, RenderTextureReadWrite.Default, FilterMode.Bilinear, tw, th);
                cmd.BlitFullscreenTriangle(lastDown, mipDown, sheet, pass);

                lastDown = mipDown;
                tw       = Mathf.Max(tw / 2, 1);
                th       = Mathf.Max(th / 2, 1);
            }

            // Upsample
            int lastUp = m_Pyramid[iterations - 1].down;

            for (int i = iterations - 2; i >= 0; i--)
            {
                int mipDown = m_Pyramid[i].down;
                int mipUp   = m_Pyramid[i].up;
                cmd.SetGlobalTexture(ShaderIDs.BloomTex, mipDown);
                cmd.BlitFullscreenTriangle(lastUp, mipUp, sheet, (int)Pass.UpsampleTent + qualityOffset);
                lastUp = mipUp;
            }

            var   linearColor    = settings.color.value.linear;
            float intensity      = RuntimeUtilities.Exp2(settings.intensity.value / 10f) - 1f;
            var   shaderSettings = new Vector4(sampleScale, intensity, settings.dirtIntensity.value, iterations);

            // Debug overlays
            if (context.IsDebugOverlayEnabled(DebugOverlay.BloomThreshold))
            {
                context.PushDebugOverlay(cmd, context.source, sheet, (int)Pass.DebugOverlayThreshold);
            }
            else if (context.IsDebugOverlayEnabled(DebugOverlay.BloomBuffer))
            {
                sheet.properties.SetVector(ShaderIDs.ColorIntensity, new Vector4(linearColor.r, linearColor.g, linearColor.b, intensity));
                context.PushDebugOverlay(cmd, m_Pyramid[0].up, sheet, (int)Pass.DebugOverlayTent + qualityOffset);
            }

            // Lens dirtiness
            // Keep the aspect ratio correct & center the dirt texture, we don't want it to be
            // stretched or squashed
            var dirtTexture = settings.dirtTexture.value == null
                ? RuntimeUtilities.blackTexture
                : settings.dirtTexture.value;

            var dirtRatio      = (float)dirtTexture.width / (float)dirtTexture.height;
            var screenRatio    = (float)context.screenWidth / (float)context.screenHeight;
            var dirtTileOffset = new Vector4(1f, 1f, 0f, 0f);

            if (dirtRatio > screenRatio)
            {
                dirtTileOffset.x = screenRatio / dirtRatio;
                dirtTileOffset.z = (1f - dirtTileOffset.x) * 0.5f;
            }
            else if (screenRatio > dirtRatio)
            {
                dirtTileOffset.y = dirtRatio / screenRatio;
                dirtTileOffset.w = (1f - dirtTileOffset.y) * 0.5f;
            }

            // Shader properties
            var uberSheet = context.uberSheet;

            uberSheet.EnableKeyword("BLOOM");
            uberSheet.properties.SetVector(ShaderIDs.Bloom_DirtTileOffset, dirtTileOffset);
            uberSheet.properties.SetVector(ShaderIDs.Bloom_Settings, shaderSettings);
            uberSheet.properties.SetColor(ShaderIDs.Bloom_Color, linearColor);
            uberSheet.properties.SetTexture(ShaderIDs.Bloom_DirtTex, dirtTexture);
            cmd.SetGlobalTexture(ShaderIDs.BloomTex, lastUp);

            // Cleanup
            for (int i = 0; i < iterations; i++)
            {
                if (m_Pyramid[i].down != lastUp)
                {
                    cmd.ReleaseTemporaryRT(m_Pyramid[i].down);
                }
                if (m_Pyramid[i].up != lastUp)
                {
                    cmd.ReleaseTemporaryRT(m_Pyramid[i].up);
                }
            }

            cmd.EndSample("BloomPyramid");

            context.bloomBufferNameID = lastUp;
        }
Beispiel #6
0
        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;
        }
Beispiel #7
0
        void Render(PostProcessRenderContext context, CommandBuffer cmd, int occlusionSource)
        {
            DoLazyInitialization(context);
            m_Settings.radius.value = Mathf.Max(m_Settings.radius.value, 1e-4f);

            // Material setup
            // Always use a quater-res AO buffer unless High/Ultra quality is set.
            bool  downsampling = (int)m_Settings.quality.value < (int)AmbientOcclusionQuality.High;
            float px           = m_Settings.intensity.value;
            float py           = m_Settings.radius.value;
            float pz           = downsampling ? 0.5f : 1f;
            float pw           = m_SampleCount[(int)m_Settings.quality.value];

            var sheet = m_PropertySheet;

            sheet.ClearKeywords();
            sheet.properties.SetVector(ShaderIDs.AOParams, new Vector4(px, py, pz, pw));
            sheet.properties.SetVector(ShaderIDs.AOColor, Color.white - m_Settings.color.value);

            // In forward fog is applied at the object level in the grometry pass so we need to
            // apply it to AO as well or it'll drawn on top of the fog effect.
            // Not needed in Deferred.
            if (context.camera.actualRenderingPath == RenderingPath.Forward && RenderSettings.fog)
            {
                sheet.EnableKeyword("APPLY_FORWARD_FOG");
                sheet.properties.SetVector(
                    ShaderIDs.FogParams,
                    new Vector3(RenderSettings.fogDensity, RenderSettings.fogStartDistance, RenderSettings.fogEndDistance)
                    );
            }

            // Texture setup
            int ts = downsampling ? 2 : 1;
            const RenderTextureFormat    kFormat = RenderTextureFormat.ARGB32;
            const RenderTextureReadWrite kRWMode = RenderTextureReadWrite.Linear;
            const FilterMode             kFilter = FilterMode.Bilinear;

            // AO buffer
            var rtMask       = ShaderIDs.OcclusionTexture1;
            int scaledWidth  = context.width / ts;
            int scaledHeight = context.height / ts;

            context.GetScreenSpaceTemporaryRT(cmd, rtMask, 0, kFormat, kRWMode, kFilter, scaledWidth, scaledHeight);

            // AO estimation
            cmd.BlitFullscreenTriangle(BuiltinRenderTextureType.None, rtMask, sheet, (int)Pass.OcclusionEstimationForward + occlusionSource);

            // Blur buffer
            var rtBlur = ShaderIDs.OcclusionTexture2;

            context.GetScreenSpaceTemporaryRT(cmd, rtBlur, 0, kFormat, kRWMode, kFilter);

            // Separable blur (horizontal pass)
            cmd.BlitFullscreenTriangle(rtMask, rtBlur, sheet, (int)Pass.HorizontalBlurForward + occlusionSource);
            cmd.ReleaseTemporaryRT(rtMask);

            // Separable blur (vertical pass)
            cmd.BlitFullscreenTriangle(rtBlur, m_Result, sheet, (int)Pass.VerticalBlur);
            cmd.ReleaseTemporaryRT(rtBlur);

            if (context.IsDebugOverlayEnabled(DebugOverlay.AmbientOcclusion))
            {
                context.PushDebugOverlay(cmd, m_Result, sheet, (int)Pass.DebugOverlay);
            }
        }
        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
            float scaledFilmHeight = k_FilmHeight * (context.height / 1080f);
            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) * scaledFilmHeight * 2f);
            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);

            // 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);
            cmd.ReleaseTemporaryRT(ShaderIDs.CoCTex);

            cmd.EndSample("DepthOfField");

            m_ResetHistory = false;
        }