public override void Render(CommandBuffer cmd, HDCamera camera, RTHandle srcRT, RTHandle destRT)
        {
            if (_ditherType != ditherType.value || _ditherTexture == null)
            {
                CoreUtils.Destroy(_ditherTexture);
                _ditherType    = ditherType.value;
                _ditherTexture = GenerateDitherTexture(_ditherType);
            }

#if UNITY_EDITOR
            // In Editor, the gradient will be modified without any hint,
            // so we have to copy the color keys every frame.
            if (true)
#else
            // In Player, we assume no one can modify gradients in profiles,
            // so we update the cache only when the reference was updated.
            if (_cachedGradient != fillGradient.value)
#endif
            {
                _cachedGradient  = fillGradient.value;
                _cachedColorKeys = _cachedGradient.colorKeys;
            }

            Vector2 edgeThresh;

            if (edgeSource.value == EdgeSource.Depth)
            {
                var thresh = 1 / Mathf.Lerp(1000, 1, edgeThreshold.value);
                var scaler = 1 + 2 / (1.01f - edgeContrast.value);
                edgeThresh = new Vector2(thresh, thresh * scaler);
            }
            else // Depth & Color
            {
                var t1 = edgeThreshold.value;
                var t2 = t1 + 1.01f - edgeContrast.value;
                edgeThresh = new Vector2(t1, t2);
            }

            _material.SetColor(ShaderIDs.EdgeColor, edgeColor.value);
            _material.SetVector(ShaderIDs.EdgeThresholds, edgeThresh);
            _material.SetFloat(ShaderIDs.FillOpacity, fillOpacity.value);
            GradientUtility.SetColorKeys(_material, _cachedColorKeys);

            _material.SetTexture(ShaderIDs.DitherTexture, _ditherTexture);
            _material.SetFloat(ShaderIDs.DitherStrength, ditherStrength.value);

            var pass = (int)edgeSource.value;
            if (fillOpacity.value > 0 && _cachedColorKeys.Length > 4)
            {
                pass += 3;
            }
            if (fillGradient.value.mode == GradientMode.Blend)
            {
                pass += 6;
            }

            // Blit to destRT with the overlay shader.
            _material.SetTexture(ShaderIDs.InputTexture, srcRT);
            HDUtils.DrawFullScreen(cmd, _material, destRT, null, pass);
        }
        public override void Render(CommandBuffer cmd, HDCamera camera, RTHandle source, RTHandle destination)
        {
            m_Material.SetFloat("_Opacity", opacity.value);

            var pass = (int)blendMode.value * 3;

            if (sourceType == Overlay.SourceType.Color)
            {
                // Single color mode parameters
                m_Material.SetColor("_Color", color.value);
                m_Material.SetTexture("_OverlayTexture", Texture2D.whiteTexture);
                m_Material.SetFloat("_UseTextureAlpha", 0);
            }
            else if (sourceType == Overlay.SourceType.Gradient)
            {
#if UNITY_EDITOR
                // In editor, copy gradient color keys every frame.
                _gradientCache = gradient.value.colorKeys;
#endif

                // Gradient direction vector
                var rad = Mathf.Deg2Rad * angle.value;
                var dir = new Vector2(Mathf.Sin(rad), Mathf.Cos(rad));

                // Gradient mode parameters
                m_Material.SetVector("_Direction", dir);
                GradientUtility.SetColorKeys(m_Material, _gradientCache);
                pass += _gradientCache.Length > 3 ? 2 : 1;
            }
            else // Overlay.Source.Texture
            {
                // Skip when no texture is given.
                if (texture.value == null)
                {
                    return;
                }

                // Texture mode parameters
                m_Material.SetColor("_Color", Color.white);
                m_Material.SetTexture("_OverlayTexture", texture.value);
                m_Material.SetFloat("_UseTextureAlpha", sourceAlpha.value ? 1 : 0);
            }

            // Blit to destRT with the overlay shader.
            m_Material.SetTexture("_InputTexture", source);
            HDUtils.DrawFullScreen(cmd, m_Material, destination, null, pass);
        }