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); }
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)); }
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()); }
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); }
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)); }
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)); }
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)); }
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()); }
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); }
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()); }
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); }
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); }
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()); }
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()); }