mirror of
				https://github.com/RetroDECK/Duckstation.git
				synced 2025-04-10 19:15:14 +00:00 
			
		
		
		
	
		
			
	
	
		
			798 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			HLSL
		
	
	
	
	
	
		
		
			
		
	
	
			798 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			HLSL
		
	
	
	
	
	
|   | #include "ReShade.fxh" | ||
|  | 
 | ||
|  | 
 | ||
|  | /* | ||
|  |    CRT-Consumer | ||
|  | 
 | ||
|  |    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 PRE_SCALE < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = 1.0; | ||
|  | 	ui_max = 4.0; | ||
|  | 	ui_step = 0.1; | ||
|  | 	ui_label = "Pre-Scale Sharpening"; | ||
|  | > = 1.5; | ||
|  | 
 | ||
|  | uniform float blurx < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = -4.0; | ||
|  | 	ui_max = 4.0; | ||
|  | 	ui_step = 0.05; | ||
|  | 	ui_label = "Convergence X"; | ||
|  | > = 0.25; | ||
|  | 
 | ||
|  | uniform float blury < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = -4.0; | ||
|  | 	ui_max = 4.0; | ||
|  | 	ui_step = 0.05; | ||
|  | 	ui_label = "Convergence Y"; | ||
|  | > = -0.1; | ||
|  | 
 | ||
|  | uniform float warpx < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = 0.0; | ||
|  | 	ui_max = 0.12; | ||
|  | 	ui_step = 0.01; | ||
|  | 	ui_label = " Curvature X"; | ||
|  | > = 0.03; | ||
|  | 
 | ||
|  | uniform float warpy < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = 0.0; | ||
|  | 	ui_max = 0.12; | ||
|  | 	ui_step = 0.01; | ||
|  | 	ui_label = " Curvature Y"; | ||
|  | > = 0.04; | ||
|  | 
 | ||
|  | uniform float corner < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = 0.0; | ||
|  | 	ui_max = 0.10; | ||
|  | 	ui_step = 0.01; | ||
|  | 	ui_label = " Corner size"; | ||
|  | > = 0.03; | ||
|  | 
 | ||
|  | uniform float smoothness < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = 100.0; | ||
|  | 	ui_max = 600.0; | ||
|  | 	ui_step = 5.0; | ||
|  | 	ui_label = " Border Smoothness"; | ||
|  | > = 400.0; | ||
|  | 
 | ||
|  | uniform bool inter < | ||
|  | 	ui_type = "radio"; | ||
|  | 	ui_label = "Interlacing Toggle"; | ||
|  | > = true; | ||
|  | 
 | ||
|  | uniform float Downscale < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = 1.0; | ||
|  | 	ui_max = 8.0; | ||
|  | 	ui_step = 1.; | ||
|  | 	ui_label = "Interlacing Downscale Scanlines"; | ||
|  | > = 2.0; | ||
|  | 
 | ||
|  | uniform float scanlow < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = 1.0; | ||
|  | 	ui_max = 15.0; | ||
|  | 	ui_step = 1.0; | ||
|  | 	ui_label = "Beam low"; | ||
|  | > = 6.0; | ||
|  | 
 | ||
|  | uniform float scanhigh < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = 1.0; | ||
|  | 	ui_max = 15.0; | ||
|  | 	ui_step = 1.0; | ||
|  | 	ui_label = "Beam high"; | ||
|  | > = 8.0; | ||
|  | 
 | ||
|  | uniform float beamlow < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = 0.5; | ||
|  | 	ui_max = 2.5; | ||
|  | 	ui_step = 0.0; | ||
|  | 	ui_label = "Scanlines dark"; | ||
|  | > = 1.45; | ||
|  | 
 | ||
|  | uniform float beamhigh < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = 0.5; | ||
|  | 	ui_max = 2.5; | ||
|  | 	ui_step = 0.0; | ||
|  | 	ui_label = "Scanlines bright"; | ||
|  | > = 1.05; | ||
|  | 
 | ||
|  | uniform float preserve < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = 0.0; | ||
|  | 	ui_max = 1.0; | ||
|  | 	ui_step = 0.01; | ||
|  | 	ui_label = "Protect White On Masks"; | ||
|  | > = 0.98; | ||
|  | 
 | ||
|  | uniform float brightboost1 < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = 0.0; | ||
|  | 	ui_max = 3.0; | ||
|  | 	ui_step = 0.05; | ||
|  | 	ui_label = "Bright boost dark pixels"; | ||
|  | > = 1.25; | ||
|  | 
 | ||
|  | uniform float brightboost2 < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = 0.0; | ||
|  | 	ui_max = 3.0; | ||
|  | 	ui_step = 0.05; | ||
|  | 	ui_label = "Bright boost bright pixels"; | ||
|  | > = 1.0; | ||
|  | 
 | ||
|  | uniform float glow < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = 1.0; | ||
|  | 	ui_max = 6.0; | ||
|  | 	ui_step = 1.0; | ||
|  | 	ui_label = "Glow pixels per axis"; | ||
|  | > = 3.0; | ||
|  | 
 | ||
|  | uniform float quality < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = 0.25; | ||
|  | 	ui_max = 4.0; | ||
|  | 	ui_step = 0.05; | ||
|  | 	ui_label = "Glow quality"; | ||
|  | > = 1.0; | ||
|  | 
 | ||
|  | uniform float glow_str < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = 0.0001; | ||
|  | 	ui_max = 2.0; | ||
|  | 	ui_step = 0.05; | ||
|  | 	ui_label = "Glow intensity"; | ||
|  | > = 0.3; | ||
|  | 
 | ||
|  | uniform float nois < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = 0.0; | ||
|  | 	ui_max = 32.0; | ||
|  | 	ui_step = 1.0; | ||
|  | 	ui_label = "Add Noise"; | ||
|  | > = 0.0; | ||
|  | 
 | ||
|  | uniform float postbr < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = 0.0; | ||
|  | 	ui_max = 2.5; | ||
|  | 	ui_step = 0.02; | ||
|  | 	ui_label = "Post Brightness"; | ||
|  | > = 1.0; | ||
|  | 
 | ||
|  | uniform float palette_fix < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = 0.0; | ||
|  | 	ui_max = 2.0; | ||
|  | 	ui_step = 1.0; | ||
|  | 	ui_label = "Palette Fixes. Sega, PUAE Atari ST dark colors"; | ||
|  | > = 0.0; | ||
|  | 
 | ||
|  | uniform float Shadowmask < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = -1.0; | ||
|  | 	ui_max = 8.0; | ||
|  | 	ui_step = 1.; | ||
|  | 	ui_label = "Mask Type"; | ||
|  | > = 0.0; | ||
|  | 
 | ||
|  | uniform float masksize < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = 1.0; | ||
|  | 	ui_max = 2.0; | ||
|  | 	ui_step = 1.0; | ||
|  | 	ui_label = "Mask Size"; | ||
|  | > = 1.0; | ||
|  | 
 | ||
|  | uniform float MaskDark < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = 0.0; | ||
|  | 	ui_max = 2.0; | ||
|  | 	ui_step = 0.1; | ||
|  | 	ui_label = "Mask dark"; | ||
|  | > = 0.2; | ||
|  | 
 | ||
|  | uniform float MaskLight < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = 0.0; | ||
|  | 	ui_max = 2.0; | ||
|  | 	ui_step = 0.1; | ||
|  | 	ui_label = "Mask light"; | ||
|  | > = 1.5; | ||
|  | 
 | ||
|  | uniform float slotmask < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = 0.0; | ||
|  | 	ui_max = 1.0; | ||
|  | 	ui_step = 0.05; | ||
|  | 	ui_label = "Slot Mask Strength"; | ||
|  | > = 0.0; | ||
|  | 
 | ||
|  | uniform float slotwidth < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = 1.0; | ||
|  | 	ui_max = 6.0; | ||
|  | 	ui_step = 0.5; | ||
|  | 	ui_label = "Slot Mask Width"; | ||
|  | > = 2.0; | ||
|  | 
 | ||
|  | uniform float double_slot < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = 1.0; | ||
|  | 	ui_max = 2.0; | ||
|  | 	ui_step = 1.0; | ||
|  | 	ui_label = "Slot Mask Height: 2x1 or 4x1"; | ||
|  | > = 1.0; | ||
|  | 
 | ||
|  | uniform float slotms < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = 1.0; | ||
|  | 	ui_max = 2.0; | ||
|  | 	ui_step = 1.0; | ||
|  | 	ui_label = "Slot Mask Size"; | ||
|  | > = 1.0; | ||
|  | 
 | ||
|  | uniform float GAMMA_OUT < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = 0.0; | ||
|  | 	ui_max = 4.0; | ||
|  | 	ui_step = 0.05; | ||
|  | 	ui_label = "Gamma Out"; | ||
|  | > = 2.25; | ||
|  | 
 | ||
|  | uniform float sat < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = 0.0; | ||
|  | 	ui_max = 2.0; | ||
|  | 	ui_step = 0.05; | ||
|  | 	ui_label = "Saturation"; | ||
|  | > = 1.0; | ||
|  | 
 | ||
|  | uniform float contrast < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = 0.00; | ||
|  | 	ui_max = 2.00; | ||
|  | 	ui_step = 0.05; | ||
|  | 	ui_label = "Contrast, 1.0:Off"; | ||
|  | > = 1.0; | ||
|  | 
 | ||
|  | uniform float WP < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = -100.0; | ||
|  | 	ui_max = 100.0; | ||
|  | 	ui_step = 5.; | ||
|  | 	ui_label = "Color Temperature %"; | ||
|  | > = 0.0; | ||
|  | 
 | ||
|  | uniform float rg < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = -1.0; | ||
|  | 	ui_max = 1.0; | ||
|  | 	ui_step = 0.005; | ||
|  | 	ui_label = "Red-Green Tint"; | ||
|  | > = 0.0; | ||
|  | 
 | ||
|  | uniform float rb < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = -1.0; | ||
|  | 	ui_max = 1.0; | ||
|  | 	ui_step = 0.005; | ||
|  | 	ui_label = "Red-Blue Tint"; | ||
|  | > = 0.0; | ||
|  | 
 | ||
|  | uniform float gr < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = -1.0; | ||
|  | 	ui_max = 1.0; | ||
|  | 	ui_step = 0.005; | ||
|  | 	ui_label = "Green-Red Tint"; | ||
|  | > = 0.0; | ||
|  | 
 | ||
|  | uniform float gb < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = -1.0; | ||
|  | 	ui_max = 1.0; | ||
|  | 	ui_step = 0.005; | ||
|  | 	ui_label = "Green-Blue Tint"; | ||
|  | > = 0.0; | ||
|  | 
 | ||
|  | uniform float br < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = -1.0; | ||
|  | 	ui_max = 1.0; | ||
|  | 	ui_step = 0.005; | ||
|  | 	ui_label = "Blue-Red Tint"; | ||
|  | > = 0.0; | ||
|  | 
 | ||
|  | uniform float bg < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = -1.0; | ||
|  | 	ui_max = 1.0; | ||
|  | 	ui_step = 0.005; | ||
|  | 	ui_label = "Blue-Green Tint"; | ||
|  | > = 0.0; | ||
|  | 
 | ||
|  | uniform bool vignette < | ||
|  | 	ui_type = "radio"; | ||
|  | 	ui_label = "Vignette On/Off"; | ||
|  | > = false; | ||
|  | 
 | ||
|  | uniform float vpower < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = 0.0; | ||
|  | 	ui_max = 1.0; | ||
|  | 	ui_step = 0.01; | ||
|  | 	ui_label = "Vignette Power"; | ||
|  | > = 0.15; | ||
|  | 
 | ||
|  | uniform float vstr < | ||
|  | 	ui_type = "drag"; | ||
|  | 	ui_min = 0.0; | ||
|  | 	ui_max = 50.0; | ||
|  | 	ui_step = 1.0; | ||
|  | 	ui_label = "Vignette strength"; | ||
|  | > = 40.0; | ||
|  | 
 | ||
|  | uniform bool alloff < | ||
|  | 	ui_type = "radio"; | ||
|  | 	ui_label = "Switch off shader"; | ||
|  | > = false; | ||
|  | 
 | ||
|  | 
 | ||
|  | uniform float  FrameCount < source = "framecount"; >; | ||
|  | uniform float2 BufferToViewportRatio < source = "buffer_to_viewport_ratio"; >; | ||
|  | uniform float2 NormalizedNativePixelSize < source = "normalized_native_pixel_size"; >; | ||
|  | uniform float2 ViewportSize < source = "viewportsize"; >; | ||
|  | uniform float  ViewportX < source = "viewportx"; >; | ||
|  | uniform float  ViewportY < source = "viewporty"; >; | ||
|  | uniform float  ViewportWidth < source = "viewportwidth"; >; | ||
|  | uniform float  ViewportHeight < source = "viewportheight"; >; | ||
|  | uniform float2 ViewportOffset < source = "viewportoffset"; >; | ||
|  | uniform float  BufferWidth < source = "bufferwidth"; >; | ||
|  | uniform float  BufferHeight < source = "bufferheight"; >; | ||
|  | uniform float  NativeWidth < source = "nativewidth"; >; | ||
|  | uniform float  NativeHeight < source = "nativeheight"; >; | ||
|  | uniform float  InternalWidth < source = "internalwidth"; >; | ||
|  | uniform float  InternalHeight < source = "internalheight"; >; | ||
|  | 
 | ||
|  | sampler2D sBackBuffer{Texture=ReShade::BackBufferTex;AddressU=CLAMP;AddressV=CLAMP;AddressW=CLAMP;MagFilter=POINT;MinFilter=POINT;}; | ||
|  | 
 | ||
|  | #define iTime (float(FrameCount)/2.0) | ||
|  | #define iTimer (float(FrameCount)/60.0) | ||
|  | 
 | ||
|  | #define SourceSize (float4(1.0/NormalizedNativePixelSize,NormalizedNativePixelSize)) | ||
|  | #define OutputSize (ViewportSize*BufferToViewportRatio) | ||
|  | 
 | ||
|  | float2 Warp(float2 pos) | ||
|  | { | ||
|  |     pos  = pos * 2.0 - 1.0;     | ||
|  |     pos *= float2(1.0 + (pos.y * pos.y) * warpx, 1.0 + (pos.x * pos.x) * warpy); | ||
|  |     return pos * 0.5 + 0.5; | ||
|  | }  | ||
|  | 
 | ||
|  | float sw(float y, float l) | ||
|  | { | ||
|  |     float beam = lerp(scanlow, scanhigh, y); | ||
|  |     float scan = lerp(beamlow,  beamhigh, l); | ||
|  |     float ex = y * scan; | ||
|  |     return exp2(-beam * ex * ex); | ||
|  | } | ||
|  | 
 | ||
|  | float3 mask(float2 x, float3 col, float l) | ||
|  | { | ||
|  |     x = floor(x / masksize);         | ||
|  |    | ||
|  |     if (Shadowmask == 0.0) | ||
|  |     { | ||
|  |         float m = frac(x.x * 0.4999); | ||
|  |         if (m < 0.4999) return float3(1.0,             MaskDark, 1.0); | ||
|  |         else            return float3(MaskDark, 1.0,             MaskDark); | ||
|  |     } | ||
|  |     | ||
|  |     else if (Shadowmask == 1.0) | ||
|  |     { | ||
|  |         float3 Mask = float3(MaskDark, MaskDark, MaskDark); | ||
|  |         float line = MaskLight; | ||
|  |         float odd  = 0.0; | ||
|  | 
 | ||
|  |         if (frac(x.x / 6.0) < 0.5) odd = 1.0; | ||
|  |         if (frac((x.y + odd) / 2.0) < 0.5) line = MaskDark; | ||
|  | 
 | ||
|  |         float m = frac(x.x / 3.0); | ||
|  |         if      (m < 0.333) Mask.b = MaskLight; | ||
|  |         else if (m < 0.666) Mask.g = MaskLight; | ||
|  |         else                Mask.r = MaskLight; | ||
|  |          | ||
|  |         Mask *= line;  | ||
|  |         return Mask;  | ||
|  |     }  | ||
|  |      | ||
|  |     else if (Shadowmask == 2.0) | ||
|  |     { | ||
|  |         float m = frac(x.x*0.3333); | ||
|  |         if (m < 0.3333) return float3(MaskDark,  MaskDark,  MaskLight); | ||
|  |         if (m < 0.6666) return float3(MaskDark,  MaskLight, MaskDark); | ||
|  |         else            return float3(MaskLight, MaskDark,  MaskDark); | ||
|  |     } | ||
|  | 
 | ||
|  |     if (Shadowmask == 3.0) | ||
|  |     { | ||
|  |         float m = frac(x.x * 0.5); | ||
|  |         if (m < 0.5) return float3(1.0, 1.0, 1.0); | ||
|  |         else         return float3(MaskDark, MaskDark, MaskDark); | ||
|  |     } | ||
|  |     | ||
|  |     else if (Shadowmask == 4.0) | ||
|  |     {    | ||
|  |         float3 Mask = float3(col.rgb); | ||
|  |         float line = MaskLight; | ||
|  |         float odd  = 0.0; | ||
|  | 
 | ||
|  |         if (frac(x.x / 4.0) < 0.5) odd = 1.0; | ||
|  |         if (frac((x.y + odd) / 2.0) < 0.5) line = MaskDark; | ||
|  | 
 | ||
|  |         float m = frac(x.x / 2.0); | ||
|  |         if  (m < 0.5) { Mask.r = 1.0; Mask.b = 1.0; } | ||
|  |         else  Mask.g = 1.0;    | ||
|  | 
 | ||
|  |         Mask *= line;   | ||
|  |         return Mask; | ||
|  |     }  | ||
|  | 
 | ||
|  |     else if (Shadowmask == 5.0) | ||
|  |     { | ||
|  |         float3 Mask = float3(1.0, 1.0, 1.0); | ||
|  | 
 | ||
|  |         if (frac(x.x / 4.0) < 0.5)    | ||
|  |         { | ||
|  |             if (frac(x.y / 3.0) < 0.666) | ||
|  |             { | ||
|  |                 if (frac(x.x / 2.0) < 0.5) Mask = float3(1.0,             MaskDark, 1.0); | ||
|  |                 else                        Mask = float3(MaskDark, 1.0,             MaskDark); | ||
|  |             } | ||
|  |             else Mask *= l; | ||
|  |         } | ||
|  |         else if (frac(x.x / 4.0) >= 0.5)    | ||
|  |         { | ||
|  |             if (frac(x.y / 3.0) > 0.333)  | ||
|  |             { | ||
|  |                 if (frac(x.x / 2.0) < 0.5) Mask = float3(1.0,             MaskDark, 1.0);  | ||
|  |                 else                        Mask = float3(MaskDark, 1.0,             MaskDark); | ||
|  |             } | ||
|  |             else Mask *= l; | ||
|  |         } | ||
|  | 
 | ||
|  |         return Mask; | ||
|  |     } | ||
|  | 
 | ||
|  |     else if (Shadowmask == 6.0) | ||
|  |     { | ||
|  |         float3 Mask = float3(MaskDark, MaskDark, MaskDark); | ||
|  |         if (frac(x.x / 6.0) < 0.5)    | ||
|  |         { | ||
|  |             if (frac(x.y / 4.0) < 0.75)   | ||
|  |             { | ||
|  |                 if      (frac(x.x / 3.0) < 0.3333) Mask.r = MaskLight;  | ||
|  |                 else if (frac(x.x / 3.0) < 0.6666) Mask.g = MaskLight;  | ||
|  |                 else                                Mask.b = MaskLight; | ||
|  |             } | ||
|  |             else Mask * l * 0.9; | ||
|  |         } | ||
|  |         else if (frac(x.x / 6.0) >= 0.5)    | ||
|  |         { | ||
|  |             if (frac(x.y / 4.0) >= 0.5 || frac(x.y / 4.0) < 0.25)   | ||
|  |             { | ||
|  |                 if      (frac(x.x / 3.0) < 0.3333) Mask.r = MaskLight;  | ||
|  |                 else if (frac(x.x / 3.0) < 0.6666) Mask.g = MaskLight; | ||
|  |                 else                                Mask.b = MaskLight; | ||
|  |             } | ||
|  |             else Mask * l * 0.9; | ||
|  |         } | ||
|  |         return Mask; | ||
|  |     } | ||
|  | 
 | ||
|  |     else if (Shadowmask == 7.0) | ||
|  |     { | ||
|  |         float m = frac(x.x * 0.3333); | ||
|  | 
 | ||
|  |         if (m < 0.3333) return float3(MaskDark,          MaskLight,         MaskLight * col.b); //Cyan | ||
|  |         if (m < 0.6666) return float3(MaskLight * col.r, MaskDark,          MaskLight);         //Magenta | ||
|  |         else            return float3(MaskLight,         MaskLight * col.g, MaskDark);          //Yellow | ||
|  |     } | ||
|  | 
 | ||
|  |     else if (Shadowmask == 8.0) | ||
|  |     { | ||
|  |         float3 Mask = float3(MaskDark, MaskDark, MaskDark); | ||
|  | 
 | ||
|  |         float bright = MaskLight; | ||
|  |         float left   = 0.0; | ||
|  |         if (frac(x.x / 6.0) < 0.5) left = 1.0; | ||
|  |               | ||
|  |         float m = frac(x.x / 3.0); | ||
|  |         if      (m < 0.333) Mask.b = 0.9; | ||
|  |         else if (m < 0.666) Mask.g = 0.9; | ||
|  |         else                Mask.r = 0.9; | ||
|  |          | ||
|  |         if ((x.y % 2.0) == 1.0 && left == 1.0 || (x.y % 2.0) == 0.0 && left == 0.0)  | ||
|  |             Mask *= bright;  | ||
|  |        | ||
|  |         return Mask;  | ||
|  |     }  | ||
|  |      | ||
|  |     else return float3(1.0, 1.0, 1.0); | ||
|  | } | ||
|  | 
 | ||
|  | float SlotMask(float2 pos, float3 c) | ||
|  | { | ||
|  |     if (slotmask == 0.0) return 1.0; | ||
|  |      | ||
|  |     pos = floor(pos / slotms); | ||
|  |     float mx = pow(max(max(c.r, c.g), c.b), 1.33); | ||
|  |     float mlen = slotwidth * 2.0; | ||
|  |     float px = frac(pos.x / mlen); | ||
|  |     float py = floor(frac(pos.y / (2.0 * double_slot)) * 2.0 * double_slot); | ||
|  |     float slot_dark = lerp(1.0 - slotmask, 1.0 - 0.80 * slotmask, mx); | ||
|  |     float slot = 1.0 + 0.7 * slotmask * (1.0 - mx); | ||
|  |      | ||
|  |     if      (py == 0.0                && px <  0.5) slot = slot_dark;  | ||
|  |     else if (py == double_slot && px >= 0.5) slot = slot_dark;        | ||
|  |      | ||
|  |     return slot; | ||
|  | } | ||
|  | 
 | ||
|  | float4x4 contrastMatrix(float contrast) | ||
|  | {    | ||
|  |     float t = (1.0 - contrast) / 2.0; | ||
|  |      | ||
|  |     return float4x4(contrast, 0,               0,               0, | ||
|  |                 0,               contrast, 0,               0, | ||
|  |                 0,               0,               contrast, 0, | ||
|  |                 t,               t,               t,               1); | ||
|  | } | ||
|  | 
 | ||
|  | float3x3 vign(float l, float2 tex) | ||
|  | { | ||
|  |     float2 vpos = tex; | ||
|  |     vpos *= 1.0 - vpos.xy; | ||
|  |      | ||
|  |     float vig = vpos.x * vpos.y * vstr; | ||
|  |     vig = min(pow(vig, vpower), 1.0);  | ||
|  |     if (vignette == false) vig = 1.0; | ||
|  |     | ||
|  |     return float3x3(vig, 0,   0, | ||
|  |                 0,   vig, 0, | ||
|  |                 0,   0,   vig); | ||
|  | } | ||
|  | 
 | ||
|  | float3 saturation(float3 textureColor) | ||
|  | { | ||
|  |     float luminance = length(textureColor.rgb) * 0.5775; | ||
|  | 
 | ||
|  |     float3 luminanceWeighting = float3(0.4, 0.5, 0.1); | ||
|  |     if (luminance < 0.5) luminanceWeighting.rgb = (luminanceWeighting.rgb * luminanceWeighting.rgb)  | ||
|  |                                                 + (luminanceWeighting.rgb * luminanceWeighting.rgb); | ||
|  | 
 | ||
|  |     luminance = dot(textureColor.rgb, luminanceWeighting); | ||
|  |     float3 greyScaleColor = float3(luminance, luminance, luminance); | ||
|  | 
 | ||
|  |     float3 res = float3(lerp(greyScaleColor, textureColor.rgb, sat)); | ||
|  |     return res; | ||
|  | } | ||
|  | 
 | ||
|  | /////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
|  | 
 | ||
|  | float3 glow0 (float2 texcoord, float3 col) | ||
|  | { | ||
|  | 
 | ||
|  |    // the more quality, the smaller the offset and better quality, less visible glow too | ||
|  |      float2 size = SourceSize.zw/quality; | ||
|  |       | ||
|  |      float3 c01; | ||
|  |      float3 sum = float3(0.0, 0.0, 0.0); | ||
|  |     | ||
|  |    // glow = pixels per axis, the more the slower! | ||
|  | 
 | ||
|  |     for (float x = -glow; x <= glow; x = x+1.0) | ||
|  |      { | ||
|  | 
 | ||
|  |    // multiply texture, the more far away the less pronounced | ||
|  |         float factor = 1.0/glow; | ||
|  |         for (float y = -glow; y <= glow; y = y+1.0) | ||
|  |         { | ||
|  | 
 | ||
|  |         float2 offset = float2(x, y) * size; | ||
|  | 
 | ||
|  |          c01 = tex2D(sBackBuffer, texcoord + offset).rgb*factor; c01 = c01*c01; | ||
|  |            | ||
|  |                 sum += c01; | ||
|  |         } | ||
|  |     } | ||
|  |    | ||
|  |     return (glow_str * sum / (glow * glow )) ; | ||
|  | } | ||
|  |      | ||
|  | /////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
|  | 
 | ||
|  | float noise(float2 co) | ||
|  | { | ||
|  |     return frac(sin(iTimer * dot(co.xy ,float2(12.9898,78.233))) * 43758.5453); | ||
|  | } | ||
|  | 
 | ||
|  | float corner0(float2 coord) | ||
|  | { | ||
|  |     coord = (coord - float2(0.5, 0.5)) * 1.0 + float2(0.5, 0.5); | ||
|  |     coord = min(coord, float2(1.0, 1.0) - coord) * float2(1.0, SourceSize.y / SourceSize.x); | ||
|  |      | ||
|  |     float2 cdist = float2(corner, corner); | ||
|  |     coord = (cdist - min(coord, cdist)); | ||
|  |     float dist = sqrt(dot(coord, coord)); | ||
|  | 
 | ||
|  |     return clamp((cdist.x - dist) * smoothness, 0.0, 1.0); | ||
|  | }   | ||
|  | 
 | ||
|  | static const float3x3 D65_to_XYZ = float3x3( | ||
|  |            0.4306190,  0.2220379,  0.0201853, | ||
|  |            0.3415419,  0.7066384,  0.1295504, | ||
|  |            0.1783091,  0.0713236,  0.9390944); | ||
|  | 
 | ||
|  | static const float3x3 XYZ_to_D65 = float3x3( | ||
|  |            3.0628971, -0.9692660,  0.0678775, | ||
|  |           -1.3931791,  1.8760108, -0.2288548, | ||
|  |           -0.4757517,  0.0415560,  1.0693490); | ||
|  |             | ||
|  | static const float3x3 D50_to_XYZ = float3x3( | ||
|  |            0.4552773,  0.2323025,  0.0145457, | ||
|  |            0.3675500,  0.7077956,  0.1049154, | ||
|  |            0.1413926,  0.0599019,  0.7057489); | ||
|  |             | ||
|  | static const float3x3 XYZ_to_D50 = float3x3( | ||
|  |            2.9603944, -0.9787684,  0.0844874, | ||
|  |           -1.4678519,  1.9161415, -0.2545973, | ||
|  |           -0.4685105,  0.0334540,  1.4216174);          | ||
|  | 
 | ||
|  | 
 | ||
|  | float4 PS_CRT_CONSUMER(float4 vpos: SV_Position, float2 vTexCoord : TEXCOORD0) : SV_Target | ||
|  | { | ||
|  |     float2 pos = Warp(vTexCoord.xy); | ||
|  |     float2 tex_size = SourceSize.xy;   | ||
|  | 
 | ||
|  |     float2 pC4 = (pos + 0.5/tex_size); | ||
|  |     float2 fp = frac(pos * tex_size); | ||
|  |     if (inter == false && tex_size.y > 400.0){ fp.y = frac(pos.y * tex_size.y*1.0/Downscale);}  | ||
|  | 
 | ||
|  |     float4 res = float4(1.0, 1.0, 1.0, 1.0); | ||
|  |      | ||
|  |     if (alloff == true)  | ||
|  |         res = tex2D(sBackBuffer, pC4);  | ||
|  |     else | ||
|  |     { | ||
|  | 
 | ||
|  |    float2 texel = pos * tex_size; | ||
|  |    float2 texel_floored = floor(texel); | ||
|  | 
 | ||
|  |    float scale = PRE_SCALE; | ||
|  |    float region_range = 0.5 - 0.5 / scale; | ||
|  | 
 | ||
|  |    // Figure out where in the texel to sample to get correct pre-scaled bilinear. | ||
|  |    // Uses the hardware bilinear interpolator to avoid having to sample 4 times manually. | ||
|  | 
 | ||
|  |    float2 center_dist = fp - 0.5; | ||
|  | 
 | ||
|  |    float2 fpp = (center_dist - clamp(center_dist, -region_range, region_range)) * scale + 0.5; | ||
|  | 
 | ||
|  |    float2 mod_texel = texel_floored + fpp; | ||
|  |    float2 coords = mod_texel / SourceSize.xy; | ||
|  | 
 | ||
|  |         float3 sample1 = tex2D(sBackBuffer, float2(coords.x + blurx*SourceSize.z, coords.y - blury*SourceSize.w)).rgb; | ||
|  |         float3 sample2 = tex2D(sBackBuffer, coords).rgb; | ||
|  |         float3 sample3 = tex2D(sBackBuffer, float2(coords.x - blurx*SourceSize.z, coords.y + blury*SourceSize.w )).rgb; | ||
|  |          | ||
|  |         float3 color = float3(sample1.r * 0.5  + sample2.r * 0.5,  | ||
|  |                           sample1.g * 0.25 + sample2.g * 0.5 + sample3.g * 0.25, | ||
|  |                           sample2.b * 0.5  + sample3.b * 0.5); | ||
|  |         if (palette_fix != 0.0)  | ||
|  |         { | ||
|  |             if (palette_fix == 1.0) color = color* 1.0667; | ||
|  |             else if (palette_fix == 2.0) color = color * 2.0; | ||
|  |         } | ||
|  | 
 | ||
|  |         //COLOR TEMPERATURE FROM GUEST.R-DR.VENOM | ||
|  |         if (WP != 0.0) | ||
|  |         { | ||
|  |             float3 warmer = mul(color, D50_to_XYZ); | ||
|  |             warmer = mul(warmer, XYZ_to_D65);  | ||
|  |              | ||
|  |             float3 cooler = mul(color, D65_to_XYZ); | ||
|  |             cooler = mul(cooler, XYZ_to_D50); | ||
|  |              | ||
|  |             float m = abs(WP) / 100.0; | ||
|  |             float3 comp = (WP < 0.0) ? cooler : warmer; | ||
|  |             comp = clamp(comp, 0.0, 1.0);    | ||
|  |              | ||
|  |             color = float3(lerp(color, comp, m)); | ||
|  |         } | ||
|  | 
 | ||
|  |      float3x3 hue = float3x3 (1., rg,  rb,                 //red tint | ||
|  |                       gr,  1., gb,                  //green tint | ||
|  |                       br,  bg,  1.);                //blue tint | ||
|  | 
 | ||
|  |         color = mul(color, hue); | ||
|  | 
 | ||
|  |         color = (2.0*pow(color,float3(2.8, 2.8, 2.8))) - pow(color,float3(3.6, 3.6, 3.6)); | ||
|  | 
 | ||
|  |         float lum = color.r * 0.3 + color.g * 0.6 + color.b * 0.1; | ||
|  | 
 | ||
|  |         float f = frac(fp.y -0.5); | ||
|  |          | ||
|  |         if (inter == true && tex_size.y > 400.0) color = color;  | ||
|  |         else | ||
|  |         {color = color * sw(f,lum) + color * sw (1.0-f,lum);} | ||
|  |          | ||
|  |         float lum1 = color.r * 0.3 + color.g * 0.6 + color.b * 0.1; | ||
|  | 
 | ||
|  |          | ||
|  |         color *= lerp(mask((vTexCoord * OutputSize.xy), color,lum1), float3(1.0, 1.0, 1.0), lum1*preserve); | ||
|  |          | ||
|  | 
 | ||
|  |         if (slotmask != 0.0) color *= SlotMask((vTexCoord * OutputSize.xy) * 1.0001, color); | ||
|  |          | ||
|  |         color *= lerp(brightboost1, brightboost2, max(max(color.r, color.g), color.b));     | ||
|  | 
 | ||
|  |      | ||
|  | 
 | ||
|  |         color = pow(color,float3(1.0 / GAMMA_OUT, 1.0 / GAMMA_OUT, 1.0 / GAMMA_OUT)); | ||
|  |                 if (glow_str != 0.0) color += glow0(coords,color); | ||
|  | 
 | ||
|  |         if (sat    != 1.0) color  = saturation(color); | ||
|  |         if (corner != 0.0) color *= corner0(pC4); | ||
|  |         if (nois   != 0.0) color *= 1.0 + noise(coords * 2.0) / nois; | ||
|  | 
 | ||
|  |         color *= lerp(1.0, postbr, lum); | ||
|  |         res = float4(color, 1.0); | ||
|  |         if (contrast != 1.0) res = mul(res, contrastMatrix(contrast)); | ||
|  |         if (inter == true && SourceSize.y > 400.0 && frac(iTime) < 0.5) res = res * 0.95; | ||
|  |         res.rgb = mul(res.rgb, vign(lum, vTexCoord)); | ||
|  | 
 | ||
|  |     } | ||
|  |      | ||
|  |     return res; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | technique CRT_CONSUMER | ||
|  | { | ||
|  |    pass | ||
|  |    { | ||
|  |    	VertexShader = PostProcessVS; | ||
|  |    	PixelShader  = PS_CRT_CONSUMER; | ||
|  |    } | ||
|  | } |