protected override ITextureFilter CreateFilter(ITextureFilter input)
            {
                Func <TextureSize, TextureSize> transform = s => new TextureSize(2 * s.Width, 2 * s.Height);

                float[] arguments  = { EdgeStrength, Sharpness };
                string  fastToggle = FastMethod ? "FAST_METHOD=1;" : "";

                var pass0 = CompileShader("super-xbr.hlsl", entryPoint: "main_fragment", macroDefinitions: "Pass = 0;" + fastToggle).Configure(transform: transform, arguments: arguments);
                var pass1 = CompileShader("super-xbr.hlsl", entryPoint: "main_fragment", macroDefinitions: "Pass = 1;" + fastToggle).Configure(arguments: arguments);
                var pass2 = CompileShader("super-xbr.hlsl", entryPoint: "main_fragment", macroDefinitions: "Pass = 2;" + fastToggle).Configure(arguments: arguments);

                // Skip if downscaling
                if (Renderer.TargetSize.Width <= input.Output.Size.Width &&
                    Renderer.TargetSize.Height <= input.Output.Size.Height)
                {
                    return(input);
                }

                ITextureFilter xbr = input
                                     .Apply(pass0)
                                     .Apply(pass1);

                return(ThirdPass
                    ? (ITextureFilter)xbr.Apply(pass2)
                    : xbr.Resize(xbr.Output.Size, offset: new Vector2(0.5f, 0.5f)));
            }
            protected override ITextureFilter CreateFilter(ITextureFilter input)
            {
                Func <TextureSize, TextureSize> transform = s => new TextureSize(2 * s.Width, 2 * s.Height);

                float[] arguments  = { EdgeStrength, Sharpness };
                string  fastToggle = FastMethod ? "FAST_METHOD=1;" : "";

                var pass0 = new Shader(FromFile("super-xbr.hlsl", entryPoint: "main_fragment", compilerOptions: "Pass = 0;" + fastToggle))
                {
                    Transform = transform, Arguments = arguments
                };
                var pass1 = new Shader(FromFile("super-xbr.hlsl", entryPoint: "main_fragment", compilerOptions: "Pass = 1;" + fastToggle))
                {
                    Arguments = arguments
                };
                var pass2 = new Shader(FromFile("super-xbr.hlsl", entryPoint: "main_fragment", compilerOptions: "Pass = 2;" + fastToggle))
                {
                    Arguments = arguments
                };

                // Skip if downscaling
                if ((Renderer.TargetSize <= input.Size()).Any)
                {
                    return(input);
                }

                ITextureFilter xbr = input
                                     .Apply(pass0)
                                     .Apply(pass1);

                return(ThirdPass
                    ? xbr.Apply(pass2)
                    : xbr.Resize(xbr.Size(), offset: new Vector2(0.5f, 0.5f)));
            }
            public ITextureFilter CreateFilter(ITextureFilter original, ITextureFilter initial)
            {
                ITextureFilter result;

                // Calculate Sizes
                var inputSize  = original.Size();
                var targetSize = TargetSize();

                // Compile Shaders
                var SharpDiff = CompileShader("Diff.hlsl", macroDefinitions: "MODE = 0;")
                                .Configure(format: TextureFormat.Float16);
                var Diff = CompileShader("Diff.hlsl", macroDefinitions: String.Format("MODE = {0};", Mode == SSSRMode.Sharp ? 0 : 1))
                           .Configure(format: TextureFormat.Float16);
                var SuperRes      = CompileShader("SuperRes.hlsl");
                var FinalSuperRes = CompileShader("SuperRes.hlsl", macroDefinitions: "FinalPass = 1;" + (LinearLight ? "LinearLight = 1;" : ""));
                var GammaToLinear = CompileShader("GammaToLinear.hlsl");

                SharpDiff["spread"]    = 1 / Locality;
                SharpDiff["oversharp"] = OverSharp;

                Diff["spread"]    = 1 / Locality;
                Diff["oversharp"] = OverSharp;

                // Skip if downscaling
                if ((targetSize <= inputSize).Any)
                {
                    return(original);
                }

                // Initial scaling
                if (initial != original)
                {
                    // Always correct offset (if any)
                    var filter = initial as IOffsetFilter;
                    if (filter != null)
                    {
                        filter.ForceOffsetCorrection();
                    }

                    result = initial.SetSize(targetSize, tagged: true);
                    if (LinearLight)
                    {
                        original = original.Apply(GammaToLinear);
                        result   = result.Apply(GammaToLinear);
                    }
                }
                else
                {
                    if (LinearLight)
                    {
                        original = original.Apply(GammaToLinear);
                    }
                    result = original.Resize(targetSize, tagged: true);
                }

                for (int i = 1; i <= Passes; i++)
                {
                    ITextureFilter diff;

                    // Downscale and Subtract
                    var loRes = Downscale(result, original, inputSize);

                    // Calculate difference
                    if (Mode == SSSRMode.Hybrid && i == 1)
                    {
                        diff = SharpDiff.ApplyTo(loRes, original);
                    }
                    else
                    {
                        diff = Diff.ApplyTo(loRes, original);
                    }

                    // Update result
                    result = (i != Passes ? SuperRes : FinalSuperRes).ApplyTo(result, diff, loRes);
                }

                return(result);
            }