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