CRT-NewPixie.fx (12105B)
1 #include "ReShade.fxh" 2 3 // newpixie CRT 4 // by Mattias Gustavsson 5 // adapted for slang by hunterk 6 7 /* 8 ------------------------------------------------------------------------------ 9 This software is available under 2 licenses - you may choose the one you like. 10 ------------------------------------------------------------------------------ 11 ALTERNATIVE A - MIT License 12 Copyright (c) 2016 Mattias Gustavsson 13 Permission is hereby granted, free of charge, to any person obtaining a copy of 14 this software and associated documentation files (the "Software"), to deal in 15 the Software without restriction, including without limitation the rights to 16 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 17 of the Software, and to permit persons to whom the Software is furnished to do 18 so, subject to the following conditions: 19 The above copyright notice and this permission notice shall be included in all 20 copies or substantial portions of the Software. 21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 27 SOFTWARE. 28 ------------------------------------------------------------------------------ 29 ALTERNATIVE B - Public Domain (www.unlicense.org) 30 This is free and unencumbered software released into the public domain. 31 Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 32 software, either in source code form or as a compiled binary, for any purpose, 33 commercial or non-commercial, and by any means. 34 In jurisdictions that recognize copyright laws, the author or authors of this 35 software dedicate any and all copyright interest in the software to the public 36 domain. We make this dedication for the benefit of the public at large and to 37 the detriment of our heirs and successors. We intend this dedication to be an 38 overt act of relinquishment in perpetuity of all present and future rights to 39 this software under copyright law. 40 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 41 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 42 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 43 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 44 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 45 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 46 ------------------------------------------------------------------------------ 47 */ 48 49 uniform float acc_modulate < 50 ui_type = "drag"; 51 ui_min = 0.0; 52 ui_max = 1.0; 53 ui_step = 0.01; 54 ui_label = "Accumulate Modulation [CRT-NewPixie]"; 55 > = 0.65; 56 57 58 texture2D tAccTex { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; }; 59 sampler sAccTex { Texture=tAccTex; }; 60 61 //PASS 1 62 float3 PrevColor(float4 pos : SV_Position, float2 uv : TEXCOORD0) : SV_Target 63 { 64 return tex2D(ReShade::BackBuffer, uv).rgb; 65 } 66 67 float4 PS_NewPixie_Accum(float4 pos : SV_Position, float2 uv : TEXCOORD0) : SV_Target 68 { 69 float4 a = tex2D(sAccTex, uv.xy) * float4(acc_modulate,acc_modulate,acc_modulate,acc_modulate); 70 float4 b = tex2D(ReShade::BackBuffer, uv.xy); 71 return max( a, b * 0.96 ); 72 } 73 74 //PASS 2 AND 3 75 texture GaussianBlurTex { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; }; 76 sampler GaussianBlurSampler { Texture = GaussianBlurTex;}; 77 78 uniform float blur_x < 79 ui_type = "drag"; 80 ui_min = 0.0; 81 ui_max = 5.0; 82 ui_step = 0.25; 83 ui_label = "Horizontal Blur [CRT-NewPixie]"; 84 > = 1.0; 85 86 uniform float blur_y < 87 ui_type = "drag"; 88 ui_min = 0.0; 89 ui_max = 5.0; 90 ui_step = 0.25; 91 ui_label = "Vertical Blur [CRT-NewPixie]"; 92 > = 1.0; 93 94 float4 PS_NewPixie_Blur(float4 pos : SV_Position, float2 uv_tx : TEXCOORD0) : SV_Target 95 { 96 float2 blur = float2(blur_x, blur_y) * ReShade::PixelSize.xy; 97 float2 uv = uv_tx.xy; 98 float4 sum = tex2D( ReShade::BackBuffer, uv ) * 0.2270270270; 99 sum += tex2D(ReShade::BackBuffer, float2( uv.x - 4.0 * blur.x, uv.y - 4.0 * blur.y ) ) * 0.0162162162; 100 sum += tex2D(ReShade::BackBuffer, float2( uv.x - 3.0 * blur.x, uv.y - 3.0 * blur.y ) ) * 0.0540540541; 101 sum += tex2D(ReShade::BackBuffer, float2( uv.x - 2.0 * blur.x, uv.y - 2.0 * blur.y ) ) * 0.1216216216; 102 sum += tex2D(ReShade::BackBuffer, float2( uv.x - 1.0 * blur.x, uv.y - 1.0 * blur.y ) ) * 0.1945945946; 103 sum += tex2D(ReShade::BackBuffer, float2( uv.x + 1.0 * blur.x, uv.y + 1.0 * blur.y ) ) * 0.1945945946; 104 sum += tex2D(ReShade::BackBuffer, float2( uv.x + 2.0 * blur.x, uv.y + 2.0 * blur.y ) ) * 0.1216216216; 105 sum += tex2D(ReShade::BackBuffer, float2( uv.x + 3.0 * blur.x, uv.y + 3.0 * blur.y ) ) * 0.0540540541; 106 sum += tex2D(ReShade::BackBuffer, float2( uv.x + 4.0 * blur.x, uv.y + 4.0 * blur.y ) ) * 0.0162162162; 107 return sum; 108 } 109 110 //PASS 4 111 uniform int FCount < source = "framecount"; >; 112 uniform float2 BufferViewportRatio < source = "buffer_to_viewport_ratio"; >; 113 114 texture tFrame < source = "crt-newpixie/crtframe.png"; > 115 { 116 Width = 1024; 117 Height = 1024; 118 MipLevels = 1; 119 }; 120 121 sampler sFrame { Texture = tFrame; AddressU = BORDER; AddressV = BORDER; MinFilter = LINEAR; MagFilter = LINEAR;}; 122 123 uniform bool use_frame < 124 ui_type = "boolean"; 125 ui_label = "Use Frame Image [CRT-NewPixie]"; 126 > = false; 127 128 uniform float curvature < 129 ui_type = "drag"; 130 ui_min = 0.0001; 131 ui_max = 4.0; 132 ui_step = 0.25; 133 ui_label = "Curvature [CRT-NewPixie]"; 134 > = 2.0; 135 136 uniform bool wiggle_toggle < 137 ui_type = "boolean"; 138 ui_label = "Interference [CRT-NewPixie]"; 139 > = false; 140 141 uniform bool scanroll < 142 ui_type = "boolean"; 143 ui_label = "Rolling Scanlines [CRT-NewPixie]"; 144 > = true; 145 146 float3 tsample( sampler samp, float2 tc, float offs, float2 resolution ) 147 { 148 tc = tc * float2(1.025, 0.92) + float2(-0.0125, 0.04); 149 float3 s = pow( abs( tex2D( samp, float2( tc.x, 1.0-tc.y ) ).rgb), float3( 2.2,2.2,2.2 ) ); 150 return s*float3(1.25,1.25,1.25); 151 } 152 153 float3 filmic( float3 LinearColor ) 154 { 155 float3 x = max( float3(0.0,0.0,0.0), LinearColor-float3(0.004,0.004,0.004)); 156 return (x*(6.2*x+0.5))/(x*(6.2*x+1.7)+0.06); 157 } 158 159 float2 curve( float2 uv ) 160 { 161 uv = (uv - 0.5);// * 2.0; 162 uv *= float2(0.925, 1.095); 163 uv *= curvature; 164 uv.x *= 1.0 + pow((abs(uv.y) / 4.0), 2.0); 165 uv.y *= 1.0 + pow((abs(uv.x) / 3.0), 2.0); 166 uv /= curvature; 167 uv += 0.5; 168 uv = uv *0.92 + 0.04; 169 return uv; 170 } 171 172 float rand(float2 co){ return frac(sin(dot(co.xy ,float2(12.9898,78.233))) * 43758.5453); } 173 174 #define resolution ReShade::ScreenSize.xy 175 #define mod(x,y) (x-y*floor(x/y)) 176 177 float4 PS_NewPixie_Final(float4 pos: SV_Position, float2 uv_tx : TEXCOORD0) : SV_Target 178 { 179 // stop time variable so the screen doesn't wiggle 180 float time = mod(FCount, 849.0) * 36.0; 181 float2 uv = uv_tx.xy; 182 uv.y = 1.0 - uv_tx.y; 183 /* Curve */ 184 float2 curved_uv = lerp( curve( uv ), uv, 0.4 ); 185 float scale = -0.101; 186 float2 scuv = curved_uv*(1.0-scale)+scale/2.0+float2(0.003, -0.001); 187 188 uv = scuv; 189 190 /* Main color, Bleed */ 191 float3 col; 192 193 float x = wiggle_toggle* sin(0.1*time+curved_uv.y*13.0)*sin(0.23*time+curved_uv.y*19.0)*sin(0.3+0.11*time+curved_uv.y*23.0)*0.0012; 194 float o =sin(uv_tx.y*1.5)/resolution.x; 195 x+=o*0.25; 196 // make time do something again 197 time = float(mod(FCount, 640) * 1); 198 col.r = tsample(ReShade::BackBuffer,float2(x+scuv.x+0.0009,scuv.y+0.0009),resolution.y/800.0, resolution ).x+0.02; 199 col.g = tsample(ReShade::BackBuffer,float2(x+scuv.x+0.0000,scuv.y-0.0011),resolution.y/800.0, resolution ).y+0.02; 200 col.b = tsample(ReShade::BackBuffer,float2(x+scuv.x-0.0015,scuv.y+0.0000),resolution.y/800.0, resolution ).z+0.02; 201 float i = clamp(col.r*0.299 + col.g*0.587 + col.b*0.114, 0.0, 1.0 ); 202 i = pow( 1.0 - pow(i,2.0), 1.0 ); 203 i = (1.0-i) * 0.85 + 0.15; 204 205 /* Ghosting */ 206 float ghs = 0.15; 207 float3 r = tsample(GaussianBlurSampler, float2(x-0.014*1.0, -0.027)*0.85+0.007*float2( 0.35*sin(1.0/7.0 + 15.0*curved_uv.y + 0.9*time), 208 0.35*sin( 2.0/7.0 + 10.0*curved_uv.y + 1.37*time) )+float2(scuv.x+0.001,scuv.y+0.001), 209 5.5+1.3*sin( 3.0/9.0 + 31.0*curved_uv.x + 1.70*time),resolution).xyz*float3(0.5,0.25,0.25); 210 float3 g = tsample(GaussianBlurSampler, float2(x-0.019*1.0, -0.020)*0.85+0.007*float2( 0.35*cos(1.0/9.0 + 15.0*curved_uv.y + 0.5*time), 211 0.35*sin( 2.0/9.0 + 10.0*curved_uv.y + 1.50*time) )+float2(scuv.x+0.000,scuv.y-0.002), 212 5.4+1.3*sin( 3.0/3.0 + 71.0*curved_uv.x + 1.90*time),resolution).xyz*float3(0.25,0.5,0.25); 213 float3 b = tsample(GaussianBlurSampler, float2(x-0.017*1.0, -0.003)*0.85+0.007*float2( 0.35*sin(2.0/3.0 + 15.0*curved_uv.y + 0.7*time), 214 0.35*cos( 2.0/3.0 + 10.0*curved_uv.y + 1.63*time) )+float2(scuv.x-0.002,scuv.y+0.000), 215 5.3+1.3*sin( 3.0/7.0 + 91.0*curved_uv.x + 1.65*time),resolution).xyz*float3(0.25,0.25,0.5); 216 217 col += float3(ghs*(1.0-0.299),ghs*(1.0-0.299),ghs*(1.0-0.299))*pow(clamp(float3(3.0,3.0,3.0)*r,float3(0.0,0.0,0.0),float3(1.0,1.0,1.0)),float3(2.0,2.0,2.0))*float3(i,i,i); 218 col += float3(ghs*(1.0-0.587),ghs*(1.0-0.587),ghs*(1.0-0.587))*pow(clamp(float3(3.0,3.0,3.0)*g,float3(0.0,0.0,0.0),float3(1.0,1.0,1.0)),float3(2.0,2.0,2.0))*float3(i,i,i); 219 col += float3(ghs*(1.0-0.114),ghs*(1.0-0.114),ghs*(1.0-0.114))*pow(clamp(float3(3.0,3.0,3.0)*b,float3(0.0,0.0,0.0),float3(1.0,1.0,1.0)),float3(2.0,2.0,2.0))*float3(i,i,i); 220 221 /* Level adjustment (curves) */ 222 col *= float3(0.95,1.05,0.95); 223 col = clamp(col*1.3 + 0.75*col*col + 1.25*col*col*col*col*col,float3(0.0,0.0,0.0),float3(10.0,10.0,10.0)); 224 225 /* Vignette */ 226 float vig = (0.1 + 1.0*16.0*curved_uv.x*curved_uv.y*(1.0-curved_uv.x)*(1.0-curved_uv.y)); 227 vig = 1.3*pow(vig,0.5); 228 col *= vig; 229 230 time *= scanroll; 231 232 /* Scanlines */ 233 float scans = clamp( 0.35+0.18*sin(6.0*time-curved_uv.y*resolution.y*1.5), 0.0, 1.0); 234 float s = pow(scans,0.9); 235 col = col * float3(s,s,s); 236 237 /* Vertical lines (shadow mask) */ 238 col*=1.0-0.23*(clamp((mod(uv_tx.xy.x, 3.0))/2.0,0.0,1.0)); 239 240 /* Tone map */ 241 col = filmic( col ); 242 243 /* Noise */ 244 /*float2 seed = floor(curved_uv*resolution.xy*float2(0.5))/resolution.xy;*/ 245 float2 seed = curved_uv*resolution.xy;; 246 /* seed = curved_uv; */ 247 col -= 0.015*pow(float3(rand( seed +time ), rand( seed +time*2.0 ), rand( seed +time * 3.0 ) ), float3(1.5,1.5,1.5) ); 248 249 /* Flicker */ 250 col *= (1.0-0.004*(sin(50.0*time+curved_uv.y*2.0)*0.5+0.5)); 251 252 /* Clamp */ 253 // if(max(abs(uv.x-0.5),abs(uv.y-0.5))>0.5) 254 // col = float3(0.0,0.0,0.0); 255 256 // if (curved_uv.x < 0.0 || curved_uv.x > 1.0) 257 // col *= 0.0; 258 // if (curved_uv.y < 0.0 || curved_uv.y > 1.0) 259 // col *= 0.0; 260 261 uv = curved_uv; 262 263 /* Frame */ 264 float2 fscale = float2( 0.026, -0.018);//float2( -0.018, -0.013 ); 265 uv = float2(uv.x, 1.-uv.y); 266 // float4 f= tex2D(sFrame,uv_tx.xy);//*((1.0)+2.0*fscale)-fscale-float2(-0.0, 0.005)); 267 float4 f= tex2D(sFrame,(uv_tx-float2(0.5,0.5)) * BufferViewportRatio + float2(0.5,0.5));//*((1.0)+2.0*fscale)-fscale-float2(-0.0, 0.005)); 268 f.xyz = lerp( f.xyz, float3(0.5,0.5,0.5), 0.5 ); 269 float fvig = clamp( -0.00+512.0*uv.x*uv.y*(1.0-uv.x)*(1.0-uv.y), 0.2, 0.8 ); 270 col = lerp( col, lerp( max( col, 0.0), pow( abs( f.xyz ), float3( 1.4,1.4,1.4 ) ) * fvig, f.w * f.w), float3( use_frame,use_frame,use_frame ) ); 271 272 return float4( col, 1.0 ); 273 } 274 275 technique CRTNewPixie 276 { 277 pass PS_CRTNewPixie_Accum 278 { 279 VertexShader=PostProcessVS; 280 PixelShader=PS_NewPixie_Accum; 281 } 282 283 pass PS_CRTNewPixie_SaveBuffer { 284 VertexShader=PostProcessVS; 285 PixelShader=PrevColor; 286 RenderTarget = tAccTex; 287 } 288 289 pass PS_CRTNewPixie_Blur 290 { 291 VertexShader = PostProcessVS; 292 PixelShader = PS_NewPixie_Blur; 293 RenderTarget = GaussianBlurTex; 294 } 295 296 pass PS_CRTNewPixie_Final 297 { 298 VertexShader = PostProcessVS; 299 PixelShader = PS_NewPixie_Final; 300 } 301 }