duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

bicubic.fx (5133B)


      1 #include "ReShade.fxh"
      2 
      3 /*
      4    Bicubic multipass Shader
      5 
      6    Copyright (C) 2011-2022 Hyllian - sergiogdb@gmail.com
      7 
      8    Permission is hereby granted, free of charge, to any person obtaining a copy
      9    of this software and associated documentation files (the "Software"), to deal
     10    in the Software without restriction, including without limitation the rights
     11    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     12    copies of the Software, and to permit persons to whom the Software is
     13    furnished to do so, subject to the following conditions:
     14 
     15    The above copyright notice and this permission notice shall be included in
     16    all copies or substantial portions of the Software.
     17 
     18    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     19    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     20    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     21    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     22    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     23    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     24    THE SOFTWARE.
     25 
     26 */
     27 
     28 uniform int BICUBIC_FILTER <
     29 	ui_type = "combo";
     30 	ui_items = "Bicubic\0Catmull-Rom\0B-Spline\0Hermite\0";
     31 	ui_label = "Bicubic Filter";
     32 	ui_tooltip = "Bicubic: balanced. Catmull-Rom: sharp. B-Spline: blurred. Hermite: soft pixelized.";
     33 > = 0;
     34 
     35 uniform float B_PRESCALE <
     36 	ui_type = "drag";
     37 	ui_min = 1.0;
     38 	ui_max = 8.0;
     39 	ui_step = 1.0;
     40 	ui_label = "Prescale factor";
     41 > = 1.0;
     42 
     43 uniform bool B_ANTI_RINGING <
     44 	ui_type = "radio";
     45 	ui_label = "Anti-Ringing";
     46 > = false;
     47 
     48 uniform float2 NormalizedNativePixelSize < source = "normalized_native_pixel_size"; >;
     49 uniform float  BufferWidth < source = "bufferwidth"; >;
     50 
     51 texture2D tBicubic_P0{Width=BUFFER_WIDTH;Height=BUFFER_HEIGHT;Format=RGBA8;};
     52 sampler2D sBicubic_P0{Texture=tBicubic_P0;AddressU=CLAMP;AddressV=CLAMP;AddressW=CLAMP;MagFilter=POINT;MinFilter=POINT;};
     53 
     54 
     55 #define AR_STRENGTH 1.0
     56 
     57 // Classic Mitchell-Netravali bicubic parameters
     58 
     59 float4x4 get_inv()
     60 {
     61 	float bf = 1.0/3.0;
     62 	float cf = 1.0/3.0;
     63 
     64 	if (BICUBIC_FILTER == 1) {bf = 0.0;     cf = 0.5;}
     65 	if (BICUBIC_FILTER == 2) {bf = 1.0;     cf = 0.0;}
     66 	if (BICUBIC_FILTER == 3) {bf = 0.0;     cf = 0.0;}
     67 
     68         return float4x4(            (-bf - 6.0*cf)/6.0,         (3.0*bf + 12.0*cf)/6.0,     (-3.0*bf - 6.0*cf)/6.0,             bf/6.0,
     69                                         (12.0 - 9.0*bf - 6.0*cf)/6.0, (-18.0 + 12.0*bf + 6.0*cf)/6.0,                      0.0, (6.0 - 2.0*bf)/6.0,
     70                                        -(12.0 - 9.0*bf - 6.0*cf)/6.0, (18.0 - 15.0*bf - 12.0*cf)/6.0,      (3.0*bf + 6.0*cf)/6.0,             bf/6.0,
     71                                                    (bf + 6.0*cf)/6.0,                           -cf,                      0.0,               0.0);
     72          
     73          
     74 }
     75 
     76 float3 bicubic_ar(float fp, float3 C0, float3 C1, float3 C2, float3 C3)
     77 {
     78     float4 weights = mul(get_inv(), float4(fp*fp*fp, fp*fp, fp, 1.0));
     79     float3 color   = mul(weights, float4x3( C0, C1, C2, C3 ));
     80 
     81     // Anti-ringing
     82     if (B_ANTI_RINGING == true)
     83     {
     84         float3 aux = color;
     85         float3 min_sample = min(min(C0, C1), min(C2, C3));
     86         float3 max_sample = max(max(C0, C1), max(C2, C3));
     87         color = clamp(color, min_sample, max_sample);
     88         color = lerp(aux, color, step(0.0, (C0-C1)*(C2-C3)));
     89     }
     90 
     91     return color;
     92 }
     93 
     94 
     95 float4 PS_Bicubic_X(float4 vpos: SV_Position, float2 uv_tx : TEXCOORD) : SV_Target
     96 {
     97     // Both dimensions are unfiltered, so it looks for lores pixels.
     98     float2 ps  = NormalizedNativePixelSize/B_PRESCALE;
     99     float2 pos = uv_tx.xy/ps - float2(0.5, 0.0);
    100     float2 tc  = (floor(pos) + 0.5.xx) * ps;
    101     float2 fp  = frac(pos);
    102 
    103     float3 C0 = tex2D(ReShade::BackBuffer, tc + ps*float2(-1.0, 0.0)).rgb;
    104     float3 C1 = tex2D(ReShade::BackBuffer, tc + ps*float2( 0.0, 0.0)).rgb;
    105     float3 C2 = tex2D(ReShade::BackBuffer, tc + ps*float2( 1.0, 0.0)).rgb;
    106     float3 C3 = tex2D(ReShade::BackBuffer, tc + ps*float2( 2.0, 0.0)).rgb;
    107 
    108     float3 color = bicubic_ar(fp.x, C0, C1, C2, C3);
    109 
    110     return float4(color, 1.0);
    111 }
    112 
    113 
    114 float4 PS_Bicubic_Y(float4 vpos: SV_Position, float2 uv_tx : TEXCOORD) : SV_Target
    115 {
    116     // One must be careful here. Horizontal dimension is already filtered, so it looks for x in hires.
    117     float2 ps  = float2(1.0/BufferWidth, NormalizedNativePixelSize.y/B_PRESCALE);
    118     float2 pos = uv_tx.xy/ps - float2(0.0, 0.5);
    119     float2 tc  = (floor(pos) + 0.5.xx) * ps;
    120     float2 fp  = frac(pos);
    121 
    122     float3 C0 = tex2D(sBicubic_P0, tc + ps*float2(0.0, -1.0)).rgb;
    123     float3 C1 = tex2D(sBicubic_P0, tc + ps*float2(0.0,  0.0)).rgb;
    124     float3 C2 = tex2D(sBicubic_P0, tc + ps*float2(0.0,  1.0)).rgb;
    125     float3 C3 = tex2D(sBicubic_P0, tc + ps*float2(0.0,  2.0)).rgb;
    126 
    127     float3 color = bicubic_ar(fp.y, C0, C1, C2, C3);
    128 
    129     return float4(color, 1.0);
    130 }
    131 
    132 
    133 technique Bicubic
    134 {
    135 	pass
    136 	{
    137 		VertexShader = PostProcessVS;
    138 		PixelShader  = PS_Bicubic_X;
    139 		RenderTarget = tBicubic_P0;
    140 	}
    141 	pass
    142 	{
    143 		VertexShader = PostProcessVS;
    144 		PixelShader  = PS_Bicubic_Y;
    145 	}
    146 }