protected override ITextureFilter CreateFilter(ITextureFilter sourceFilter) { if (sourceFilter.Size() == Renderer.TargetSize) { return(sourceFilter); } try { m_DxvaHd = Renderer.CreateDxvaHd((Size)sourceFilter.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); }
protected override ITextureFilter CreateFilter(ITextureFilter input) { 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 sourceSize = input.Size(); if ((Renderer.TargetSize <= sourceSize).Any) { return(input); } var yuv = input.ConvertToYuv(); m_Filter1 = NNedi3Helpers.CreateFilter(shaderPass1, yuv, Neurons1, Structured); var resultY = interleave.ApplyTo(yuv, m_Filter1); m_Filter2 = NNedi3Helpers.CreateFilter(shaderPass2, resultY, Neurons2, Structured); var luma = interleave.ApplyTo(resultY, m_Filter2); var result = ChromaScaler.ScaleChroma( new CompositionFilter(luma, yuv, targetSize: luma.Size(), chromaOffset: new Vector2(-0.25f, -0.25f))); return(result.Convolve(null, 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))); }
protected override ITextureFilter CreateFilter(ITextureFilter input) { var sourceSize = input.Size(); if ((Renderer.TargetSize <= sourceSize).Any) { return(input); } var targetSize = Renderer.TargetSize; CreateWeights((Size)sourceSize, targetSize); int lobes = TapCount.ToInt() / 2; var shader = CompileShader("EwaScaler.hlsl", macroDefinitions: string.Format("LOBES = {0}; AR = {1}", lobes, AntiRingingEnabled ? 1 : 0)) .Configure( transform: size => targetSize, arguments: new[] { AntiRingingStrength }, linearSampling: true ); return(GetEwaFilter(shader, new[] { input })); }
protected override ITextureFilter CreateFilter(ITextureFilter input) { 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 = GetShader(Neurons1); var shaderPass2 = GetShader(Neurons2); var interleave = new Shader(FromFile("Interleave.hlsl")) { Transform = transform }; if ((Renderer.TargetSize <= input.Size()).Any) { return(input); } var yuv = input.ConvertToYuv(); var composition = input.Decompose(); var resultY = interleave.ApplyTo(composition.Luma, shaderPass1.ApplyTo(yuv)); var luma = interleave.ApplyTo(resultY, shaderPass2.ApplyTo(resultY)); composition = luma.ComposeWith(composition.Chroma, chromaOffset: new Vector2(-0.25f, -0.25f)); var result = ChromaScaler.ScaleChroma(composition); return(result.Convolve(null, offset: new Vector2(0.5f, 0.5f))); }
protected override ITextureFilter CreateFilter(ITextureFilter input) { var sourceSize = input.Size(); if ((Renderer.TargetSize <= sourceSize).Any) { return(input); } var targetSize = Renderer.TargetSize; CreateWeights((Size)sourceSize, targetSize); int lobes = TapCount.ToInt() / 2; var shader = new Shader(FromFile("EwaScaler.hlsl", compilerOptions: string.Format("LOBES = {0}; AR = {1}", lobes, AntiRingingEnabled ? 1 : 0))) { Transform = size => targetSize, Arguments = new[] { AntiRingingStrength }, LinearSampling = true }; return(GetEwaFilter(shader, new[] { input })); }
protected override ITextureFilter CreateFilter(ITextureFilter 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 = new Shader(FromFile("Deband.hlsl", compilerOptions: PreserveDetail ? "PRESERVE_DETAIL=1" : "")) { Arguments = consts, PerTextureLinearSampling = new[] { true, false } }; ITextureFilter yuv = input.ConvertToYuv(); var inputsize = yuv.Size(); var deband = yuv; double factor = 2.0;// 0.5 * Math.Sqrt(5) + 0.5; int maxWidth = Math.Min(Math.Min(inputsize.Width, inputsize.Height) / 3, 256); int max = (int)Math.Floor(Math.Log(maxWidth, 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.Transform = s => size; deband = Deband.ApplyTo(yuv, deband); } return(deband.ConvertToRgb()); }
public static ITextureFilter ScaleChroma(ITextureFilter luma, ITextureFilter chroma, TextureSize targetSize, Vector2 chromaOffset) { luma = luma.SetSize(targetSize); var resizedLuma = luma as ResizeFilter; if (resizedLuma != null) { resizedLuma.AddLabel(resizedLuma.ScaleDescription.AddPrefixToDescription("Luma: ")); } if (chroma.Size() != luma.Size()) { var resizedChroma = new ResizeFilter(chroma, luma.Size(), TextureChannels.ChromaOnly, chromaOffset, Renderer.ChromaUpscaler, Renderer.ChromaDownscaler); resizedChroma.AddLabel(resizedChroma.ScaleDescription.AddPrefixToDescription("Chroma: ")); chroma = resizedChroma; } return(luma .MergeWith(chroma) .ConvertToRgb()); }
protected override ITextureFilter CreateFilter(ITextureFilter input) { 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 neuronCount1 = s_NeuronCount[(int)Neurons1]; var neuronCount2 = s_NeuronCount[(int)Neurons2]; var weights1 = s_Weights[(int)Neurons1]; var buffer1 = Renderer.CreateClBuffer(weights1); var buffer2 = buffer1; var differentWeights = neuronCount1 != neuronCount2; if (differentWeights) { var weights2 = s_Weights[(int)Neurons2]; buffer2 = Renderer.CreateClBuffer(weights2); } var kernel = GetKernel(); // Note Kernel is reused between different filters var shaderH = new NNedi3Kernel(kernel) { Horizontal = true, Buffer = buffer1, NeuronCount = neuronCount1, Transform = transformWidth }; var shaderV = new NNedi3Kernel(kernel) { Horizontal = false, Buffer = buffer2, NeuronCount = neuronCount2, Transform = transformHeight, ReloadWeights = differentWeights }; var sourceSize = input.Size(); if ((Renderer.TargetSize <= sourceSize).Any) { return(input); } var composition = input.Decompose(); var nnedi3H = shaderH.ApplyTo(composition.Luma); var nnedi3V = shaderV.ApplyTo(nnedi3H); composition = nnedi3V.ComposeWith(composition.Chroma, chromaOffset: new Vector2(-0.25f, -0.25f)); var result = ChromaScaler.ScaleChroma(composition); return(result.Convolve(null, offset: new Vector2(0.5f, 0.5f))); }
protected override ITextureFilter CreateFilter(ITextureFilter input) { 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 neuronCount1 = s_NeuronCount[(int)Neurons1]; var neuronCount2 = s_NeuronCount[(int)Neurons2]; var weights1 = s_Weights[(int)Neurons1]; var buffer1 = Renderer.CreateClBuffer(weights1); var buffer2 = buffer1; var differentWeights = neuronCount1 != neuronCount2; if (differentWeights) { var weights2 = s_Weights[(int)Neurons2]; buffer2 = Renderer.CreateClBuffer(weights2); } var sourceSize = input.Size(); if ((Renderer.TargetSize <= sourceSize).Any) { return(input); } var yuv = input.ConvertToYuv(); var localWorkSizes = new[] { 8, 8 }; var nnedi3H = new NNedi3HKernelFilter(shaderH, buffer1, neuronCount1, new TextureSize(yuv.Size().Width, yuv.Size().Height), localWorkSizes, yuv); var nnedi3V = new NNedi3VKernelFilter(shaderV, buffer2, neuronCount2, differentWeights, new TextureSize(nnedi3H.Size().Width, nnedi3H.Size().Height), localWorkSizes, nnedi3H); var result = ChromaScaler.ScaleChroma( new CompositionFilter(nnedi3V, yuv, targetSize: nnedi3V.Size(), chromaOffset: new Vector2(-0.25f, -0.25f))); return(new ResizeFilter(result, result.Size(), new Vector2(0.5f, 0.5f), Renderer.LumaUpscaler, Renderer.LumaDownscaler)); }
private bool UseNedi(ITextureFilter input) { var size = input.Size(); if (size.IsEmpty) { return(false); } if (AlwaysDoubleImage) { return(true); } return(Renderer.TargetSize.Width > size.Width || Renderer.TargetSize.Height > size.Height); }
public static ITextureFilter SetSize(this ITextureFilter filter, TextureSize size, bool tagged = false) { ITextureFilter textureFilter; if (filter.Size() == size && (textureFilter = filter as ITextureFilter) != null) { return(textureFilter); } var resizeable = (filter as IResizeableFilter) ?? new ResizeFilter(filter, size); if (tagged) { resizeable.EnableTag(); } return(resizeable.ResizeTo(size)); }
public CompositionFilter(ITextureFilter luma, ITextureFilter chroma, TextureSize?targetSize = null, Vector2?chromaOffset = null, ITextureFilter fallback = null) : base(targetSize ?? (fallback != null ? fallback.Size() : luma.Size()), luma, chroma) { if (luma == null) { throw new ArgumentNullException("luma"); } if (chroma == null) { throw new ArgumentNullException("chroma"); } Luma = luma; Chroma = chroma; ChromaOffset = chromaOffset ?? Renderer.ChromaOffset; Fallback = fallback ?? new DefaultChromaScaler().ScaleChroma(this); }
protected override ITextureFilter CreateFilter(ITextureFilter input) { ITextureFilter H = input, Sh, L, M, R; var targetSize = Renderer.TargetSize; if ((Renderer.TargetSize >= input.Size()).Any) { return(input); } var Calc = CompileShader("calc.hlsl"); Calc["strength"] = Strength; DownscaleAndCalcVar(H, targetSize, out L, out Sh); ConvolveAndCalcR(L, Sh, out M, out R); return(Calc.ApplyTo(L, M, R)); }
protected override ITextureFilter CreateFilter(ITextureFilter 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: PreserveDetail ? "PRESERVE_DETAIL=1" : "") .Configure(arguments: consts, perTextureLinearSampling: new[] { true, false }); ITextureFilter yuv = input.ConvertToYuv(); var inputsize = yuv.Size(); var deband = yuv; double factor = 2.0;// 0.5 * Math.Sqrt(5) + 0.5; int maxWidth = Math.Min(Math.Min(inputsize.Width, inputsize.Height) / 3, 256); int max = (int)Math.Floor(Math.Log(maxWidth, 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 = Deband.Configure(transform: s => size).ApplyTo(yuv, deband); } return deband.ConvertToRgb(); }
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); }
public ITextureFilter CreateFilter(ITextureFilter original, ITextureFilter initial) { ITextureFilter result; var HQDownscaler = (IScaler) new Bicubic(0.75f, false); // Calculate Sizes var inputSize = original.Size(); var targetSize = TargetSize(); string macroDefinitions = ""; if (Softness == 0.0f) { macroDefinitions += "SkipSoftening = 1;"; } if (Strength == 0.0f) { return(initial); } // Compile Shaders var Diff = new Shader(FromFile("Diff.hlsl")) { Format = TextureFormat.Float16 }; var SuperRes = new Shader(FromFile("SuperRes.hlsl", compilerOptions: macroDefinitions)) { Arguments = new[] { Strength, Softness } }; var FinalSuperRes = new Shader(FromFile("SuperRes.hlsl", compilerOptions: macroDefinitions + "FinalPass = 1;")) { Arguments = new[] { Strength } }; var GammaToLab = new Shader(FromFile("../Common/GammaToLab.hlsl")); var LabToGamma = new Shader(FromFile("../Common/LabToGamma.hlsl")); var LinearToGamma = new Shader(FromFile("../Common/LinearToGamma.hlsl")); var GammaToLinear = new Shader(FromFile("../Common/GammaToLinear.hlsl")); var LabToLinear = new Shader(FromFile("../Common/LabToLinear.hlsl")); var LinearToLab = new Shader(FromFile("../Common/LinearToLab.hlsl")); // 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).Apply(GammaToLinear); } else { result = original.Apply(GammaToLinear).Resize(targetSize, tagged: true); } for (int i = 1; i <= Passes; i++) { // Downscale and Subtract ITextureFilter diff; if (LegacyDownscaling) { var loRes = result.Resize(inputSize, downscaler: HQDownscaler); diff = Diff.ApplyTo(loRes, original); } else { diff = DownscaleAndDiff(result, original, inputSize); } // Update result result = (i != Passes ? SuperRes : FinalSuperRes).ApplyTo(result, diff); } return(result); }
public CompositionFilter(ITextureFilter luma, ITextureFilter chroma, TextureSize?targetSize = null, Vector2?chromaOffset = null, ITextureFilter fallback = null) : this(luma, chroma, targetSize ?? luma.Size(), chromaOffset ?? Renderer.ChromaOffset, fallback) { }
public static ITextureFilter Convolve(this ITextureFilter <ITexture2D> inputFilter, IScaler convolver, TextureChannels?channels = null, Vector2?offset = null, IScaler upscaler = null, IScaler downscaler = null, TextureFormat?outputFormat = null) { return(new ResizeFilter(inputFilter, inputFilter.Size(), channels ?? TextureChannels.All, offset ?? Vector2.Zero, upscaler, downscaler, convolver, outputFormat)); }