예제 #1
0
            public override IFilter CreateFilter(IResizeableFilter sourceFilter)
            {
                var nedi1Shader           = CompileShader("NEDI-I.hlsl");
                var nedi2Shader           = CompileShader("NEDI-II.hlsl");
                var nediHInterleaveShader = CompileShader("NEDI-HInterleave.hlsl");
                var nediVInterleaveShader = CompileShader("NEDI-VInterleave.hlsl");

                Func <Size, Size> transformWidth;
                Func <Size, Size> transformHeight;

                if (Centered)
                {
                    transformWidth  = s => new Size(2 * s.Width - 1, s.Height);
                    transformHeight = s => new Size(s.Width, 2 * s.Height - 1);
                }
                else
                {
                    transformWidth  = s => new Size(2 * s.Width, s.Height);
                    transformHeight = s => new Size(s.Width, 2 * s.Height);
                }

                if (!UseNedi(sourceFilter))
                {
                    return(sourceFilter);
                }

                var nedi1 = new ShaderFilter(nedi1Shader, LumaConstants, sourceFilter);
                var nediH = new ShaderFilter(nediHInterleaveShader, transformWidth, sourceFilter, nedi1);
                var nedi2 = new ShaderFilter(nedi2Shader, LumaConstants, nediH);
                var nediV = new ShaderFilter(nediVInterleaveShader, transformHeight, nediH, nedi2);

                return(nediV);
            }
예제 #2
0
            public override IFilter CreateFilter(IFilter input)
            {
                IFilter xbr;

                Func <TextureSize, TextureSize> transformWidth  = s => new TextureSize(2 * s.Width, s.Height);
                Func <TextureSize, TextureSize> transformHeight = s => new TextureSize(s.Width, 2 * s.Height);
                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.OutputSize.Width &&
                    Renderer.TargetSize.Height <= input.OutputSize.Height)
                {
                    return(input);
                }

                xbr = new ShaderFilter(Pass0, input);
                xbr = new ShaderFilter(Pass1, xbr);

                if (ThirdPass)
                {
                    return(xbr + (RenderChain)Pass2);
                }
                else
                {
                    return(new ResizeFilter(xbr, xbr.OutputSize, new Vector2(0.5f, 0.5f)));
                }
            }
            protected override ITextureFilter CreateFilter(ITextureFilter sourceFilter)
            {
                if (sourceFilter.Output.Size == Renderer.TargetSize)
                {
                    return(sourceFilter);
                }

                try
                {
                    m_DxvaHd = Renderer.CreateDxvaHd((Size)sourceFilter.Output.Size, TextureFormat.Unorm8,
                                                     Renderer.TargetSize, TextureFormat.Unorm8, Quality);
                }
                catch (DxvaHdException)
                {
                    // DXVA HD not available; fallback
                    Renderer.FallbackOccurred = true;
                    return(sourceFilter);
                }

                var input = YuvMode ? sourceFilter.ConvertToYuv() : sourceFilter;

                if (sourceFilter.Output.Format != TextureFormat.Unorm8)
                {
                    // Convert input to Unorm8 (and unforunately murdering quality at the same time)
                    var copy = CompileShader("Copy.hlsl").Configure(linearSampling: false, format: TextureFormat.Unorm8);
                    input = new ShaderFilter(copy, input);
                }

                var result = new DxvaHdResizeFilter(m_DxvaHd, input);

                return(YuvMode ? result.ConvertToRgb() : result);
            }
            public override IFilter CreateFilter(IFilter input)
            {
                DisposeHelper.Dispose(ref m_Buffer1);
                DisposeHelper.Dispose(ref m_Buffer2);

                if (!Renderer.IsOpenClAvail || Renderer.RenderQuality.PerformanceMode())
                {
                    Renderer.FallbackOccurred = true; // Warn user via player stats OSD
                    return(input);                    // OpenCL is not available, or UNORM8 textures used (not supported); fallback
                }

                Func <TextureSize, TextureSize> transformWidth  = s => new TextureSize(2 * s.Width, s.Height);
                Func <TextureSize, TextureSize> transformHeight = s => new TextureSize(s.Width, 2 * s.Height);

                var kernel  = CompileKernel();
                var shaderH = kernel.Configure(transform: transformWidth);
                var shaderV = kernel.Configure(transform: transformHeight);

                var combine = CompileShader("Combine.hlsl");

                var neuronCount1 = s_NeuronCount[(int)Neurons1];
                var neuronCount2 = s_NeuronCount[(int)Neurons2];
                var weights1     = s_Weights[(int)Neurons1];

                m_Buffer1 = Renderer.CreateClBuffer(weights1);
                var differentWeights = neuronCount1 != neuronCount2;

                if (differentWeights)
                {
                    var weights2 = s_Weights[(int)Neurons2];
                    m_Buffer2 = Renderer.CreateClBuffer(weights2);
                }

                var sourceSize = input.OutputSize;

                if (!IsUpscalingFrom(sourceSize))
                {
                    return(input);
                }

                var yuv = input.ConvertToYuv();

                var chroma = new ResizeFilter(yuv, new TextureSize(sourceSize.Width * 2, sourceSize.Height * 2),
                                              TextureChannels.ChromaOnly, new Vector2(-0.25f, -0.25f), Renderer.ChromaUpscaler,
                                              Renderer.ChromaDownscaler);

                var localWorkSizes = new[] { 8, 8 };
                var nnedi3H        = new NNedi3HKernelFilter(shaderH, m_Buffer1, neuronCount1,
                                                             new TextureSize(yuv.OutputSize.Width, yuv.OutputSize.Height),
                                                             localWorkSizes, yuv);
                var nnedi3V = new NNedi3VKernelFilter(shaderV, m_Buffer2, neuronCount2, differentWeights,
                                                      new TextureSize(nnedi3H.OutputSize.Width, nnedi3H.OutputSize.Height),
                                                      localWorkSizes, nnedi3H);

                var result = new ShaderFilter(combine, nnedi3V, chroma);

                return(new ResizeFilter(result.ConvertToRgb(), result.OutputSize, new Vector2(0.5f, 0.5f),
                                        Renderer.LumaUpscaler, Renderer.LumaDownscaler));
            }
예제 #5
0
            public override IFilter CreateFilter(IFilter input)
            {
                if (Renderer.InputFormat.IsRgb())
                {
                    return(input);
                }

                int bits = Renderer.InputFormat.GetBitDepth();

                if (bits > maxbitdepth)
                {
                    return(input);
                }

                float[] consts =
                {
                    (1 << bits) - 1,
                    power
                };

                var Deband = CompileShader("Deband.hlsl", macroDefinitions: !grain ? "SkipDithering=1" : "")
                             .Configure(arguments: consts, perTextureLinearSampling: new[] { true, false });

                /*var Subtract = CompileShader("Subtract.hlsl")
                 *  .Configure(perTextureLinearSampling: new[] { false, true }, format: TextureFormat.Float16);
                 * var SubtractLimited = CompileShader("SubtractLimited.hlsl")
                 *  .Configure(perTextureLinearSampling: new[] { false, true }, arguments: Consts);*/

                IFilter yuv       = input.ConvertToYuv();
                var     inputsize = yuv.OutputSize;

                var    deband = yuv;
                double factor = 2.0;// 0.5 * Math.Sqrt(5) + 0.5;

                int max = (int)Math.Floor(Math.Log(Math.Min(inputsize.Width, inputsize.Height) / 3.0, factor));

                for (int i = max; i >= 0; i--)
                {
                    double scale = Math.Pow(factor, i);
                    var    size  = new TextureSize((int)Math.Round(inputsize.Width / scale), (int)Math.Round(inputsize.Height / scale));
                    if (size.Width == 0 || size.Height == 0)
                    {
                        continue;
                    }
                    if (i == 0)
                    {
                        size = inputsize;
                    }

                    deband = new ShaderFilter(Deband.Configure(transform: s => size), yuv, deband);
                }

                return(deband.ConvertToRgb());
            }
예제 #6
0
            public override IFilter CreateFilter(IFilter input)
            {
                var yInput = new YSourceFilter();
                var uInput = new USourceFilter();
                var vInput = new VSourceFilter();

                Vector2 offset = Renderer.ChromaOffset + new Vector2(0.5f, 0.5f);

                var chromaShader = CompileShader("Chroma.hlsl").Configure(arguments: new[] { B, C, offset[0], offset[1] });

                var chroma = new ShaderFilter(chromaShader, yInput, uInput, vInput);
                var rgb    = chroma.ConvertToRgb();

                return(rgb);
            }
            public override IFilter CreateFilter(IResizeableFilter sourceFilter)
            {
                var chromaShader = CompileShader("Chroma.hlsl");

                var yInput = new YSourceFilter();
                var uInput = new USourceFilter();
                var vInput = new VSourceFilter();

                float[] offset = { 0.0f, 0.5f };

                var chroma = new ShaderFilter(chromaShader, new[] { B, C, offset[0], offset[1] }, yInput, uInput, vInput);
                var rgb    = chroma.ConvertToRgb();

                return(rgb);
            }
예제 #8
0
            public override IFilter CreateFilter(IFilter input)
            {
                if (!Renderer.IsDx11Avail)
                {
                    Renderer.FallbackOccurred = true; // Warn user via player stats OSD
                    return(input);                    // DX11 is not available; fallback
                }

                Func <TextureSize, TextureSize> Transformation = s => new TextureSize(2 * s.Height, s.Width);

                var NNEDI3     = LoadShader11(string.Format("NNEDI3_{0}_{1}.cso", s_NeuronCount[(int)Neurons], s_CodePath[(int)CodePath]));
                var Interleave = CompileShader("Interleave.hlsl").Configure(transform: Transformation);
                var Combine    = CompileShader("Combine.hlsl").Configure(transform: Transformation);

                var sourceSize = input.OutputSize;

                if (!IsUpscalingFrom(sourceSize))
                {
                    return(input);
                }

                var yuv = input.ConvertToYuv();

                var chroma = new ResizeFilter(yuv, new TextureSize(sourceSize.Width * 2, sourceSize.Height * 2),
                                              TextureChannels.ChromaOnly, new Vector2(-0.25f, -0.25f), Renderer.ChromaUpscaler, Renderer.ChromaDownscaler);

                IFilter resultY, result;

                var pass1 = NNedi3Helpers.CreateFilter(NNEDI3, yuv, Neurons);

                resultY = new ShaderFilter(Interleave, yuv, pass1);
                var pass2 = NNedi3Helpers.CreateFilter(NNEDI3, resultY, Neurons);

                result = new ShaderFilter(Combine, resultY, pass2, chroma);

                return(new ResizeFilter(result.ConvertToRgb(), result.OutputSize, new Vector2(0.5f, 0.5f),
                                        Renderer.LumaUpscaler, Renderer.LumaDownscaler));
            }
예제 #9
0
            public override IFilter CreateFilter(IFilter input)
            {
                Cleanup();

                if (!Renderer.IsDx11Avail)
                {
                    Renderer.FallbackOccurred = true; // Warn user via player stats OSD
                    return(input);                    // DX11 is not available; fallback
                }

                Func <TextureSize, TextureSize> transform = s => new TextureSize(2 * s.Height, s.Width);

                var shaderPass1 = LoadShader11(GetShaderFileName(Neurons1));
                var shaderPass2 = LoadShader11(GetShaderFileName(Neurons2));
                var interleave  = CompileShader("Interleave.hlsl").Configure(transform: transform);
                var combine     = CompileShader("Combine.hlsl").Configure(transform: transform);

                var sourceSize = input.OutputSize;

                if (!IsUpscalingFrom(sourceSize))
                {
                    return(input);
                }

                var yuv = input.ConvertToYuv();

                var chroma = new ResizeFilter(yuv, new TextureSize(sourceSize.Width * 2, sourceSize.Height * 2),
                                              TextureChannels.ChromaOnly, new Vector2(-0.25f, -0.25f), Renderer.ChromaUpscaler, Renderer.ChromaDownscaler);

                m_Filter1 = NNedi3Helpers.CreateFilter(shaderPass1, yuv, Neurons1, Structured);
                var resultY = new ShaderFilter(interleave, yuv, m_Filter1);

                m_Filter2 = NNedi3Helpers.CreateFilter(shaderPass2, resultY, Neurons2, Structured);
                var result = new ShaderFilter(combine, resultY, m_Filter2, chroma);

                return(new ResizeFilter(result.ConvertToRgb(), result.OutputSize, new Vector2(0.5f, 0.5f),
                                        Renderer.LumaUpscaler, Renderer.LumaDownscaler));
            }
예제 #10
0
            public override IFilter CreateFilter(IFilter input)
            {
                Func <TextureSize, TextureSize> transformWidth  = s => new TextureSize(2 * s.Width, s.Height);
                Func <TextureSize, TextureSize> transformHeight = s => new TextureSize(s.Width, 2 * s.Height);

                var nedi1Shader           = CompileShader("NEDI-I.hlsl").Configure(arguments: LumaConstants);
                var nedi2Shader           = CompileShader("NEDI-II.hlsl").Configure(arguments: LumaConstants);
                var nediHInterleaveShader = CompileShader("NEDI-HInterleave.hlsl").Configure(transform: transformWidth);
                var nediVInterleaveShader = CompileShader("NEDI-VInterleave.hlsl").Configure(transform: transformHeight);

                if (!UseNedi(input))
                {
                    return(input);
                }

                var nedi1 = new ShaderFilter(nedi1Shader, input);
                var nediH = new ShaderFilter(nediHInterleaveShader, input, nedi1);
                var nedi2 = new ShaderFilter(nedi2Shader, nediH);
                var nediV = new ShaderFilter(nediVInterleaveShader, nediH, nedi2);

                return(new ResizeFilter(nediV, nediV.OutputSize, new Vector2(0.5f, 0.5f),
                                        Renderer.LumaUpscaler, Renderer.LumaDownscaler, ForceCentered ? Renderer.LumaUpscaler : null));
            }
예제 #11
0
            public override IFilter CreateFilter(IResizeableFilter sourceFilter)
            {
                IFilter yuv;

                var chromaSize = Renderer.ChromaSize;
                var targetSize = sourceFilter.OutputSize;

                var Diff       = CompileShader("SuperChromaRes/Diff.hlsl");
                var CopyLuma   = CompileShader("SuperChromaRes/CopyLuma.hlsl");
                var CopyChroma = CompileShader("SuperChromaRes/CopyChroma.hlsl");
                var SuperRes   = CompileShader("SuperChromaRes/SuperRes.hlsl");

                var GammaToLab    = CompileShader("GammaToLab.hlsl");
                var LabToGamma    = CompileShader("LabToGamma.hlsl");
                var LinearToGamma = CompileShader("LinearToGamma.hlsl");
                var GammaToLinear = CompileShader("GammaToLinear.hlsl");
                var LabToLinear   = CompileShader("LabToLinear.hlsl");
                var LinearToLab   = CompileShader("LinearToLab.hlsl");

                // Skip if downscaling
                if (targetSize.Width <= chromaSize.Width && targetSize.Height <= chromaSize.Height)
                {
                    return(sourceFilter);
                }

                // Original values
                var yInput = new YSourceFilter();
                var uInput = new USourceFilter();
                var vInput = new VSourceFilter();

                float[] YuvConsts = new float[2];
                switch (Renderer.Colorimetric)
                {
                case YuvColorimetric.Auto: return(sourceFilter);

                case YuvColorimetric.FullRangePc601: YuvConsts = new[] { 0.114f, 0.299f, 0.0f }; break;

                case YuvColorimetric.FullRangePc709: YuvConsts = new[] { 0.0722f, 0.2126f, 0.0f }; break;

                case YuvColorimetric.FullRangePc2020: YuvConsts = new[] { 0.0593f, 0.2627f, 0.0f }; break;

                case YuvColorimetric.ItuBt601: YuvConsts = new[] { 0.114f, 0.299f, 1.0f }; break;

                case YuvColorimetric.ItuBt709: YuvConsts = new[] { 0.0722f, 0.2126f, 1.0f }; break;

                case YuvColorimetric.ItuBt2020: YuvConsts = new[] { 0.0593f, 0.2627f, 1.0f }; break;
                }

                var Consts = new[] { Strength, Sharpness, AntiAliasing, AntiRinging,
                                     Softness, YuvConsts[0], YuvConsts[1] };

                yuv = sourceFilter.ConvertToYuv();

                for (int i = 1; i <= Passes; i++)
                {
                    IFilter res, diff, linear;
                    bool    useBilinear = (upscaler is Scaler.Bilinear) || (FirstPassOnly && !(i == 1));

                    // Compare to chroma
                    linear = new ShaderFilter(GammaToLinear, yuv.ConvertToRgb());
                    res    = new ResizeFilter(linear, chromaSize, upscaler, downscaler);
                    res    = new ShaderFilter(LinearToGamma, res).ConvertToYuv();
                    diff   = new ShaderFilter(Diff, YuvConsts, res, uInput, vInput);
                    if (!useBilinear)
                    {
                        diff = new ResizeFilter(diff, targetSize, upscaler, downscaler); // Scale to output size
                    }
                    // Update result
                    yuv = new ShaderFilter(SuperRes, useBilinear, Consts, yuv, diff, uInput, vInput);
                }

                return(yuv.ConvertToRgb());
            }
예제 #12
0
            public IFilter CreateFilter(IFilter original, IFilter initial)
            {
                IFilter lab, linear, result = initial;

                var inputSize   = original.OutputSize;
                var currentSize = original.OutputSize;
                var targetSize  = TargetSize();

                var Diff     = CompileShader("Diff.hlsl");
                var SuperRes = CompileShader("SuperRes.hlsl");

                var GammaToLab    = CompileShader("GammaToLab.hlsl");
                var LabToGamma    = CompileShader("LabToGamma.hlsl");
                var LinearToGamma = CompileShader("LinearToGamma.hlsl");
                var GammaToLinear = CompileShader("GammaToLinear.hlsl");
                var LabToLinear   = CompileShader("LabToLinear.hlsl");
                var LinearToLab   = CompileShader("LinearToLab.hlsl");

                var NEDI = new Shiandow.Nedi.Nedi
                {
                    AlwaysDoubleImage = false,
                    Centered          = false,
                    LumaConstants     = new[] { 1.0f, 0.0f, 0.0f }
                };

                var Consts = new[] { Strength, Sharpness, AntiAliasing, AntiRinging };

                // Skip if downscaling
                if (targetSize.Width <= inputSize.Width && targetSize.Height <= inputSize.Height)
                {
                    return(initial);
                }

                // Initial scaling
                lab      = new ShaderFilter(GammaToLab, initial);
                original = new ShaderFilter(GammaToLab, original);

                for (int i = 1; i <= Passes; i++)
                {
                    IFilter res, diff;
                    bool    useBilinear = (upscaler is Scaler.Bilinear) || (FirstPassOnly && !(i == 1));

                    // Calculate size
                    if (i == Passes || NoIntermediates)
                    {
                        currentSize = targetSize;
                    }
                    else
                    {
                        currentSize = CalculateSize(currentSize, targetSize, i);
                    }

                    // Resize
                    if (i == 1 && UseNEDI)
                    {
                        lab = new ResizeFilter(lab + NEDI, currentSize, m_ShiftedScaler, m_ShiftedScaler, m_ShiftedScaler);
                    }
                    else
                    {
                        lab = new ResizeFilter(lab, currentSize, upscaler, downscaler);
                    }

                    // Downscale and Subtract
                    linear = new ShaderFilter(LabToLinear, lab);
                    res    = new ResizeFilter(linear, inputSize, upscaler, downscaler); // Downscale result
                    diff   = new ShaderFilter(Diff, res, original);                     // Compare with original

                    // Scale difference back
                    if (!useBilinear)
                    {
                        diff = new ResizeFilter(diff, currentSize, upscaler, downscaler);
                    }

                    // Update result
                    lab    = new ShaderFilter(SuperRes, useBilinear, Consts, lab, diff, original);
                    result = new ShaderFilter(LabToGamma, lab);
                }

                return(result);
            }
예제 #13
0
            public override IFilter CreateFilter(IFilter input)
            {
                if (Renderer.InputFormat.IsRgb())
                {
                    return(input);
                }

                IFilter hiRes;

                var chromaSize = (TextureSize)Renderer.ChromaSize;
                var targetSize = input.OutputSize;

                // Original values
                var yInput = new YSourceFilter();
                var uInput = new USourceFilter();
                var vInput = new VSourceFilter();

                float[] yuvConsts = Renderer.Colorimetric.GetYuvConsts();
                int     bitdepth  = Renderer.InputFormat.GetBitDepth();
                bool    limited   = Renderer.Colorimetric.IsLimitedRange();

                // Skip if downscaling
                if (targetSize.Width <= chromaSize.Width && targetSize.Height <= chromaSize.Height)
                {
                    return(input);
                }

                Vector2 offset        = Renderer.ChromaOffset;
                Vector2 adjointOffset = -offset * targetSize / chromaSize;

                string superResMacros = "";

                if (IsIntegral(Strength))
                {
                    superResMacros += String.Format("strength = {0};", Strength);
                }
                if (IsIntegral(Softness))
                {
                    superResMacros += String.Format("softness = {0};", Softness);
                }

                string diffMacros = string.Format("LimitedRange = {0}; range = {1}", limited ? 1 : 0, (1 << bitdepth) - 1);

                var CopyLuma    = CompileShader("CopyLuma.hlsl");
                var CopyChroma  = CompileShader("CopyChroma.hlsl");
                var MergeChroma = CompileShader("MergeChroma.hlsl").Configure(format: TextureFormat.Float16);

                var Diff = CompileShader("Diff.hlsl", macroDefinitions: diffMacros)
                           .Configure(arguments: yuvConsts, format: TextureFormat.Float16);

                var SuperRes = CompileShader("SuperResEx.hlsl", macroDefinitions: superResMacros)
                               .Configure(
                    arguments: new[] { Strength, Softness, yuvConsts[0], yuvConsts[1], offset.X, offset.Y }
                    );

                var CrossBilateral = CompileShader("CrossBilateral.hlsl")
                                     .Configure(
                    arguments: new[] { offset.X, offset.Y, yuvConsts[0], yuvConsts[1] },
                    perTextureLinearSampling: new[] { true, false }
                    );

                var GammaToLab    = CompileShader("../../Common/GammaToLab.hlsl");
                var LabToGamma    = CompileShader("../../Common/LabToGamma.hlsl");
                var LinearToGamma = CompileShader("../../Common/LinearToGamma.hlsl");
                var GammaToLinear = CompileShader("../../Common/GammaToLinear.hlsl");
                var LabToLinear   = CompileShader("../../Common/LabToLinear.hlsl");
                var LinearToLab   = CompileShader("../../Common/LinearToLab.hlsl");

                hiRes = Prescaler ? new ShaderFilter(CrossBilateral, yInput, uInput, vInput) : input.ConvertToYuv();

                for (int i = 1; i <= Passes; i++)
                {
                    IFilter diff, linear;

                    // Compare to chroma
                    var rgb = new RgbFilter(hiRes, limitChroma: false);
                    linear = new ShaderFilter(GammaToLinear, rgb);
                    linear = new ResizeFilter(linear, chromaSize, adjointOffset, upscaler, downscaler);
                    diff   = new ShaderFilter(Diff, linear, uInput, vInput);

                    // Update result
                    hiRes = new ShaderFilter(SuperRes, hiRes, diff);
                }

                return(hiRes.ConvertToRgb());
            }
예제 #14
0
            public IFilter CreateFilter(IFilter original, IFilter initial)
            {
                IFilter lab, linear, result = initial;

                var inputSize   = original.OutputSize;
                var currentSize = original.OutputSize;
                var targetSize  = TargetSize();

                var Diff     = CompileShader("Diff.hlsl");
                var SuperRes = CompileShader("SuperRes.hlsl");

                var GammaToLab    = CompileShader("GammaToLab.hlsl");
                var LabToGamma    = CompileShader("LabToGamma.hlsl");
                var LinearToGamma = CompileShader("LinearToGamma.hlsl");
                var GammaToLinear = CompileShader("GammaToLinear.hlsl");
                var LabToLinear   = CompileShader("LabToLinear.hlsl");
                var LinearToLab   = CompileShader("LinearToLab.hlsl");

                var NEDI = new Shiandow.Nedi.Nedi
                {
                    AlwaysDoubleImage = false,
                    Centered          = false,
                    LumaConstants     = new[] { 1.0f, 0.0f, 0.0f }
                };

                var Consts = new[] { Strength, Sharpness, AntiAliasing, AntiRinging };

                // Initial scaling
                lab      = new ShaderFilter(GammaToLab, initial);
                original = new ShaderFilter(GammaToLab, original);

                for (int i = 1; i <= Passes; i++)
                {
                    IFilter res, diff;
                    bool    useBilinear = (upscaler is Scaler.Bilinear) || (FirstPassOnly && !(i == 1));

                    // Calculate size
                    if (i == Passes)
                    {
                        currentSize = targetSize;
                    }
                    else
                    {
                        currentSize = CalculateSize(currentSize, targetSize, i);
                    }

                    // Resize and Convert
                    if (i == 1 && UseNEDI)
                    {
                        var nedi = lab + NEDI;
                        lab = new ResizeFilter(nedi, currentSize, m_ShiftedScaler, m_ShiftedScaler);

                        if (currentSize == nedi.OutputSize)
                        {
                            // TODO: implement a proper way to shift NEDI without resizing
                            lab = new ResizeFilter(lab, currentSize);
                        }
                    }
                    else
                    {
                        lab = new ResizeFilter(lab, currentSize);
                    }
                    linear = new ShaderFilter(LabToLinear, lab);

                    // Calculate difference
                    res  = new ResizeFilter(linear, inputSize, upscaler, downscaler); // Downscale result
                    diff = new ShaderFilter(Diff, res, original);                     // Compare with original
                    if (!useBilinear)
                    {
                        diff = new ResizeFilter(diff, currentSize, upscaler, downscaler); // Scale to output size
                    }
                    // Update result
                    lab    = new ShaderFilter(SuperRes, useBilinear, Consts, lab, diff, original);
                    result = new ShaderFilter(LabToGamma, lab);
                }

                return(result);
            }
예제 #15
0
            public IFilter CreateFilter(IFilter original, IFilter initial)
            {
                IFilter lab;
                IFilter result = initial;

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

                string macroDefinitions = "";

                if (IsIntegral(Strength))
                {
                    macroDefinitions += String.Format("strength = {0};", Strength);
                }
                if (IsIntegral(Softness))
                {
                    macroDefinitions += String.Format("softness = {0};", Softness);
                }

                // Compile Shaders
                var Diff = CompileShader("Diff.hlsl")
                           .Configure(format: TextureFormat.Float16);

                var SuperRes = CompileShader("SuperResEx.hlsl", macroDefinitions: macroDefinitions)
                               .Configure(
                    arguments: new[] { Strength, Softness }
                    );

                var GammaToLab    = CompileShader("../Common/GammaToLab.hlsl");
                var LabToGamma    = CompileShader("../Common/LabToGamma.hlsl");
                var LinearToGamma = CompileShader("../Common/LinearToGamma.hlsl");
                var GammaToLinear = CompileShader("../Common/GammaToLinear.hlsl");
                var LabToLinear   = CompileShader("../Common/LabToLinear.hlsl");
                var LinearToLab   = CompileShader("../Common/LinearToLab.hlsl");

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

                // Initial scaling
                if (initial != original)
                {
                    original = new ShaderFilter(GammaToLab, original);

                    // Always correct offset (if any)
                    if (initial is ResizeFilter)
                    {
                        ((ResizeFilter)initial).ForceOffsetCorrection();
                    }

                    lab = new ShaderFilter(GammaToLab, initial.SetSize(targetSize));
                }
                else
                {
                    original = new ShaderFilter(GammaToLab, original);
                    lab      = new ResizeFilter(original, targetSize);
                }

                for (int i = 1; i <= Passes; i++)
                {
                    IFilter diff, linear;

                    // Downscale and Subtract
                    linear = new ShaderFilter(LabToLinear, lab);
                    linear = new ResizeFilter(linear, inputSize, m_Upscaler, m_Downscaler); // Downscale result
                    diff   = new ShaderFilter(Diff, linear, original);                      // Compare with original

                    // Update result
                    lab    = new ShaderFilter(SuperRes, lab, diff);
                    result = new ShaderFilter(LabToGamma, lab);
                }

                return(result);
            }
예제 #16
0
            public override IFilter CreateFilter(IResizeableFilter sourceFilter)
            {
                var upscaler   = new Scaler.Custom(new GaussianBlur(0.75), ScalerTaps.Four, false);
                var downscaler = new Scaler.HwBilinear(); // Good enough (?)

                int bits = 8;

                switch (Renderer.InputFormat)
                {
                case FrameBufferInputFormat.P010: bits = 10; break;

                case FrameBufferInputFormat.Y410: bits = 10; break;

                case FrameBufferInputFormat.P016: bits = 16; break;

                case FrameBufferInputFormat.Y416: bits = 16; break;

                case FrameBufferInputFormat.Rgb24: return(sourceFilter);

                case FrameBufferInputFormat.Rgb32: return(sourceFilter);
                }
                if (bits > maxbitdepth)
                {
                    return(sourceFilter);
                }

                var inputsize = sourceFilter.OutputSize;
                var size      = inputsize;
                var current   = sourceFilter.ConvertToYuv();

                var factor     = 2.0;
                var downscaled = new Stack <IFilter>();

                downscaled.Push(current);

                // Generate downscaled images
                for (int i = 0; i < 8; i++)
                {
                    size = new Size((int)Math.Floor(size.Width / factor), (int)Math.Floor(size.Height / factor));
                    if (size.Width == 0 || size.Height == 0)
                    {
                        break;
                    }

                    current = new ResizeFilter(current, size, upscaler, downscaler);
                    downscaled.Push(current);
                }

                var deband = downscaled.Pop();

                while (downscaled.Count > 0)
                {
                    deband = new ShaderFilter(CompileShader("Deband.hlsl"), true,
                                              new[]
                    {
                        (1 << bits) - 1,
                        advancedMode ? threshold : DEFAULT_THRESHOLD,
                        advancedMode ? margin : DEFAULT_MARGIN
                    },
                                              downscaled.Pop(), deband);
                }

                return(deband.ConvertToRgb());
            }
예제 #17
0
            public override IFilter CreateFilter(IFilter input)
            {
                IFilter hiRes;

                var chromaSize = (TextureSize)Renderer.ChromaSize;
                var targetSize = input.OutputSize;

                // Original values
                var yInput = new YSourceFilter();
                var uInput = new USourceFilter();
                var vInput = new VSourceFilter();

                float[] yuvConsts = new float[0];
                int     bitdepth  = (uInput.OutputFormat == TextureFormat.Unorm8) ? 8 : 10;

                float range = (1 << bitdepth) - 1;

                switch (Renderer.Colorimetric)
                {
                case YuvColorimetric.Auto: return(input);

                case YuvColorimetric.FullRangePc601: yuvConsts = new[] { 0.114f, 0.299f, 0.0f, range }; break;

                case YuvColorimetric.FullRangePc709: yuvConsts = new[] { 0.0722f, 0.2126f, 0.0f, range }; break;

                case YuvColorimetric.FullRangePc2020: yuvConsts = new[] { 0.0593f, 0.2627f, 0.0f, range }; break;

                case YuvColorimetric.ItuBt601: yuvConsts = new[] { 0.114f, 0.299f, 1.0f, range }; break;

                case YuvColorimetric.ItuBt709: yuvConsts = new[] { 0.0722f, 0.2126f, 1.0f, range }; break;

                case YuvColorimetric.ItuBt2020: yuvConsts = new[] { 0.0593f, 0.2627f, 1.0f, range }; break;
                }

                // Skip if downscaling
                if (targetSize.Width <= chromaSize.Width && targetSize.Height <= chromaSize.Height)
                {
                    return(input);
                }

                Vector2 offset        = Renderer.ChromaOffset;
                Vector2 adjointOffset = -offset * targetSize / chromaSize;

                string macroDefinitions = "";

                if (IsIntegral(Strength))
                {
                    macroDefinitions += String.Format("strength = {0};", Strength);
                }
                if (IsIntegral(Softness))
                {
                    macroDefinitions += String.Format("softness = {0};", Softness);
                }

                var CopyLuma    = CompileShader("CopyLuma.hlsl");
                var CopyChroma  = CompileShader("CopyChroma.hlsl");
                var MergeChroma = CompileShader("MergeChroma.hlsl").Configure(format: TextureFormat.Float16);

                var Diff = CompileShader("Diff.hlsl")
                           .Configure(arguments: yuvConsts, format: TextureFormat.Float16);

                var SuperRes = CompileShader("SuperResEx.hlsl", macroDefinitions: macroDefinitions)
                               .Configure(
                    arguments: new[] { Strength, Softness, yuvConsts[0], yuvConsts[1], offset.X, offset.Y }
                    );

                var CrossBilateral = CompileShader("CrossBilateral.hlsl")
                                     .Configure(
                    arguments: new[] { offset.X, offset.Y, yuvConsts[0], yuvConsts[1] },
                    perTextureLinearSampling: new[] { true, false }
                    );

                var GammaToLab    = CompileShader("../../Common/GammaToLab.hlsl");
                var LabToGamma    = CompileShader("../../Common/LabToGamma.hlsl");
                var LinearToGamma = CompileShader("../../Common/LinearToGamma.hlsl");
                var GammaToLinear = CompileShader("../../Common/GammaToLinear.hlsl");
                var LabToLinear   = CompileShader("../../Common/LabToLinear.hlsl");
                var LinearToLab   = CompileShader("../../Common/LinearToLab.hlsl");

                hiRes = Prescaler ? new ShaderFilter(CrossBilateral, yInput, uInput, vInput) : input.ConvertToYuv();

                for (int i = 1; i <= Passes; i++)
                {
                    IFilter diff, linear;

                    // Compare to chroma
                    linear = new ShaderFilter(GammaToLinear, hiRes.ConvertToRgb());
                    linear = new ResizeFilter(linear, chromaSize, adjointOffset, upscaler, downscaler);
                    diff   = new ShaderFilter(Diff, linear, uInput, vInput);

                    // Update result
                    hiRes = new ShaderFilter(SuperRes, hiRes, diff);
                }

                return(hiRes.ConvertToRgb());
            }