#include "ReShade.fxh" /* G-sharp resampler 2.0 - dynamic range (upscaler, downsampler) Copyright (C) 2024 guest(r) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ uniform float GSHARP0 < ui_type = "drag"; ui_min = 0.75; ui_max = 8.0; ui_step = 0.05; ui_label = "Filter Range"; > = 2.45; uniform float GBOOST < ui_type = "drag"; ui_min = 1.0; ui_max = 2.5; ui_step = 0.05; ui_label = "Filter Boost (same range, speedup)"; > = 1.75; uniform float GMAXSHARP < ui_type = "drag"; ui_min = 0.0; ui_max = 0.25; ui_step = 0.01; ui_label = "Filter Sharpness"; > = 0.1; uniform float GPAR < ui_type = "drag"; ui_min = 0.0; ui_max = 1.0; ui_step = 0.10; ui_label = "Anti-Ringing"; > = 0.50; uniform float2 NormalizedNativePixelSize < source = "normalized_native_pixel_size"; >; uniform float2 NormalizedInternalPixelSize < source = "normalized_internal_pixel_size"; >; uniform float2 BufferToViewportRatio < source = "buffer_to_viewport_ratio"; >; uniform float2 ViewportSize < source = "viewportsize"; >; sampler2D sBackBuffer{Texture=ReShade::BackBufferTex;AddressU=CLAMP;AddressV=CLAMP;AddressW=CLAMP;MagFilter=POINT;MinFilter=POINT;}; texture2D tGSHARP2_H{Width=BUFFER_WIDTH;Height=BUFFER_HEIGHT;Format=RGBA8;}; sampler2D sGSHARP2_H{Texture=tGSHARP2_H;AddressU=CLAMP;AddressV=CLAMP;AddressW=CLAMP;MagFilter=POINT;MinFilter=POINT;}; #define GMAXSHARP (0.25*GBOOST*GBOOST*GMAXSHARP) float smothstep(float x) { return exp(-2.33*x*x); } float getw(float x) { float z = x/GBOOST; float y = smothstep(z); return max(y*y - GMAXSHARP, lerp(-GMAXSHARP, 0.0, x-1.0)); } float3 gsharp2(float2 tex, float2 dx, float f, sampler2D Source) { float3 color = 0.0.xxx; float w, fp; float wsum = 0.0; float3 pixel; float3 cmax = 0.0.xxx; float3 cmin = 1.0.xxx; float FPR = GSHARP0; float FPR2 = 2.0*FPR; float FPR3 = FPR2*FPR2; float LOOPSIZE = ceil(FPR2); float x = -LOOPSIZE+1.0; do { fp = min(abs(x+f),FPR2); pixel = tex2D(Source, tex + x*dx).rgb; fp = fp/FPR; w = getw(fp); if (w > 0.0) { cmin = min(cmin, pixel); cmax = max(cmax, pixel); } color = color + w * pixel; wsum = wsum + w; x = x + 1.0; } while (x <= LOOPSIZE); color = color / wsum; return lerp(clamp(color, 0.0, 1.0), clamp(color, cmin, cmax), GPAR); } float4 PS_GSHARP2_H(float4 vpos: SV_Position, float2 vTexCoord : TEXCOORD0) : SV_Target { float4 SourceSize = float4(1.0 / NormalizedInternalPixelSize, NormalizedInternalPixelSize); float2 pos = vTexCoord * SourceSize.xy-0.5; float f = -frac(pos.x); float2 tex = (floor(pos) + 0.5)*SourceSize.zw; float3 color; float2 dx = float2(SourceSize.z, 0.0); color = gsharp2(tex, dx, f, sBackBuffer); return float4(color, 1.0); } float4 PS_GSHARP2_V(float4 vpos: SV_Position, float2 vTexCoord : TEXCOORD0) : SV_Target { float4 SourceSize = float4((ViewportSize.x*BufferToViewportRatio.x), 1.0/NormalizedInternalPixelSize.y, 1.0/(ViewportSize.x*BufferToViewportRatio.x), NormalizedInternalPixelSize.y); float2 pos = vTexCoord * SourceSize.xy-0.5; float f = -frac(pos.y); float2 tex = (floor(pos) + 0.5)*SourceSize.zw; float3 color; float2 dy = float2(0.0, SourceSize.w); color = gsharp2(tex, dy, f, sGSHARP2_H); return float4(color, 1.0); } technique GSHARP2 { pass { VertexShader = PostProcessVS; PixelShader = PS_GSHARP2_H; RenderTarget = tGSHARP2_H; } pass { VertexShader = PostProcessVS; PixelShader = PS_GSHARP2_V; } }