Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Adapted for RetroArch from Flyguy's "Apple II-Like Artifact Colors" from shadertoy:
- https://www.shadertoy.com/view/llyGzR
- "Colors created through NTSC artifacting on 4-bit patterns, similar to the Apple II's lo-res mode."
- "Ported to ReShade by Matsilagi and luluco250"
- */
- #if ARTIFACT_COLORS_MUL_FIX
- //on directx the matrices must be multiplied in reverse
- #if (__RENDERER__ >= 0x10000)
- #define MUL(A, B) mul(A, B)
- #else
- #define MUL(A, B) mul(B, A)
- #endif
- #else
- #define MUL(A, B) mul(A, B)
- #endif
- #include "ReShade.fxh"
- //Macros/////////////////////////////////////////////////////////////////////////////////////////
- uniform float display_sizeX <
- ui_type = "drag";
- ui_min = 1.0;
- ui_max = BUFFER_WIDTH;
- ui_label = "Screen Width [ArtifactColors]";
- > = BUFFER_WIDTH;
- uniform float display_sizeY <
- ui_type = "drag";
- ui_min = 1.0;
- ui_max = BUFFER_HEIGHT;
- ui_label = "Screen Height [ArtifactColors]";
- > = BUFFER_HEIGHT;
- uniform float HUE <
- ui_type = "drag";
- ui_min = 0.0;
- ui_max = 1.0;
- ui_step = 0.01;
- ui_label = "Hue [ArtifactColors]";
- > = 0.0;
- uniform float SATURATION <
- ui_type = "drag";
- ui_min = 0.0;
- ui_max = 100.0;
- ui_step = 1.0;
- ui_label = "Saturation [ArtifactColors]";
- > = 30.0;
- uniform float BRIGHTNESS <
- ui_type = "drag";
- ui_min = 0.0;
- ui_max = 2.0;
- ui_label = "Brightness [ArtifactColors]";
- ui_step = 0.01;
- > = 1.0;
- uniform float F_COL <
- ui_type = "drag";
- ui_min = 4.0;
- ui_max = 8.0;
- ui_step = 1.0;
- ui_label = "F Col [ArtifactColors]";
- ui_tooltip = "Realtime changes not available in DX9.\nUse F_COL_DX9 to mod that in DX9.\n(Preprocessor Definition)";
- > = 4.0;
- uniform float F_COL_BW <
- ui_type = "drag";
- ui_min = 10.0;
- ui_max = 200.0;
- ui_step = 1.0;
- ui_label = "F Col BW [ArtifactColors]";
- ui_tooltip = "Realtime changes not available in DX9.\nUse F_COL_BW_DX9 to mod that in DX9.\n(Preprocessor Definition)";
- > = 50.0;
- uniform float F_LUMA_LP <
- ui_type = "drag";
- ui_min = 1.0;
- ui_max = 12.0;
- ui_step = 1.0;
- ui_label = "F Luma LP [ArtifactColors]";
- ui_tooltip = "Realtime changes not available in DX9.\nUse F_LUMA_LP_DX9 to mod that in DX9.\n(Preprocessor Definition)";
- > = 6.0;
- uniform int Viewmode <
- ui_type = "combo";
- ui_label = "View Mode [ArtifactColors]";
- ui_items = "Composite\0RGB\0Luma\0Chroma\0Signal\0Split\0";
- > = 0;
- //DirectX 9 fixes HERE WE GOOOOOO fuck...
- #ifndef F_COL_DX9
- #define F_COL_DX9 4.0
- #endif
- #ifndef F_LUMA_LP_DX9
- #define F_LUMA_LP_DX9 6.0
- #endif
- #ifndef F_COL_BW_DX9
- #define F_COL_BW_DX9 50.0
- #endif
- #define FIR_SIZE 29
- #define display_size float2(display_sizeX,display_sizeY)
- //Statics////////////////////////////////////////////////////////////////////////////////////////
- static const float pi = atan(1.0) * 4.0;
- static const float tau = atan(1.0) * 8.0;
- static const float3x3 rgb2yiq = float3x3(
- 0.299, 0.596, 0.211,
- 0.587,-0.274,-0.523,
- 0.114,-0.322, 0.312
- );
- static const float3x3 yiq2rgb = float3x3(
- 1.000, 1.000, 1.000,
- 0.956,-0.272,-1.106,
- 0.621,-0.647, 1.703
- );
- //Uniforms///////////////////////////////////////////////////////////////////////////////////////
- //Textures///////////////////////////////////////////////////////////////////////////////////////
- texture ArtifactChannel0_tex {
- Width = BUFFER_WIDTH;
- Height = BUFFER_HEIGHT;
- Format = RGBA32F;
- };
- texture tArtifactColors_Modulator {
- Width = BUFFER_WIDTH;
- Height = BUFFER_HEIGHT;
- Format = R16F;
- };
- sampler sArtifactColors_Modulator {
- Texture = tArtifactColors_Modulator;
- };
- texture tArtifactColors_Demodulator {
- Width = BUFFER_WIDTH;
- Height = BUFFER_HEIGHT;
- Format = RGBA16F;
- };
- sampler sArtifactColors_Demodulator {
- Texture = tArtifactColors_Demodulator;
- };
- sampler ArtifactChannel0 {
- Texture = ArtifactChannel0_tex;
- };
- //Functions//////////////////////////////////////////////////////////////////////////////////////
- //Angle -> 2D rotation matrix
- float2x2 rotate(float a) {
- return float2x2(
- cos(a), sin(a),
- -sin(a), cos(a)
- );
- }
- //Non-normalized texture sampling
- float4 sample2D(sampler sp, float2 res, float2 uv) {
- return tex2D(sp, uv / res);
- }
- //Complex multiply
- float2 cmul(float2 a, float2 b) {
- return float2((a.x * b.x) - (a.y * b.y), (a.x * b.y) + (a.y * b.y));
- }
- float sinc(float x) { //reshade warns about division by zero here, even though there should be none
- //return (x == 0.0) ? 1.0 : sin(x * pi) / max(x * pi, 0.001); //so we'll use max()
- return (x == 0.0) ? 1.0 : sin(x * pi) / (x * pi);
- }
- //https://en.wikipedia.org/wiki/Window_function
- float WindowBlackman(float a, int N, int i) {
- float a0 = (1.0 - a) / 2.0;
- float a1 = 0.5;
- float a2 = a / 2.0;
- float wnd = a0;
- wnd -= a1 * cos(2.0 * pi * (float(i) / float(N - 1)));
- wnd += a2 * cos(4.0 * pi * (float(i) / float(N - 1)));
- return wnd;
- }
- //FIR lowpass filter
- //Fc = Cutoff freq., Fs = Sample freq., N = # of taps, i = Tap index
- float Lowpass(float Fc, float Fs, int N, int i) {
- float wc = (Fc / Fs);
- float wnd = WindowBlackman(0.16, N, i);
- return 2.0 * wc * wnd * sinc(2.0 * wc * float(i - N / 2));
- }
- //FIR bandpass filter
- //Fa/Fb = Low/High cutoff freq., Fs = Sample freq., N = # of taps, i = Tap index
- float Bandpass(float Fa, float Fb, float Fs, int N, int i) {
- float wa = (Fa / Fs);
- float wb = (Fb / Fs);
- float wnd = WindowBlackman(0.16, N, i);
- return 2.0 * (wb - wa) * wnd * (sinc(2.0 * wb * float(i - N / 2)) - sinc(2.0 * wa * float(i - N / 2)));
- }
- //Complex oscillator, Fo = Oscillator freq., Fs = Sample freq., n = Sample index
- float2 Oscillator(float Fo, float Fs, float N) {
- float phase = (tau * Fo * floor(N)) / Fs;
- return float2(cos(phase), sin(phase));
- }
- float2 p_sh(float2 p_){
- float2 xx = float2(320.0, 240.0); //output screen res
- float2 ar = float2(1.0,1.0); //final aspect ratio (calculated)
- xx = display_size;
- ar = float(1.0).xx;
- return 0.5 * float2(
- step(0.0, 1.0 - ar.y) * (1.0 - 1.0 / ar.y),
- step(1.0, ar.y) * (1.0 - ar.y));
- }
- //Shaders////////////////////////////////////////////////////////////////////////////////////////
- float4 PS_Stock(float4 vpos : SV_Position, float2 texcoord : TexCoord) : SV_Target
- {
- float2 p_ = texcoord.xy*float2((float)BUFFER_WIDTH,(float)BUFFER_HEIGHT);
- float2 xx = float2(320.0,240.0);
- float2 ar = float2(1.0,1.0); //final aspect ratio (calculated)
- xx = ReShade::ScreenSize.xy;
- ar = float(1.0).xx;
- xx = display_size;
- p_ = texcoord;
- p_ -= 0.5;
- p_ *= ar;
- p_ += 0.5;
- if(ar.y<1.0){p_ -= 0.5; p_ = p_*(1.0/ar.y); p_ += 0.5; }
- p_ = floor(p_*xx)/xx;
- p_ += p_sh(p_);
- return tex2D(ReShade::BackBuffer, p_).rgba;
- }
- float PS_Modulator(
- float4 pos : SV_POSITION,
- float2 uv : TEXCOORD
- ) : SV_TARGET {
- float Fs = BUFFER_WIDTH;
- float Fcol = Fs * (1.0 / F_COL);
- float n = floor(uv.x * BUFFER_WIDTH);
- float3 cRGB = tex2D(ArtifactChannel0, uv).rgb;
- float3 cYIQ = MUL(rgb2yiq, cRGB);
- float2 cOsc = Oscillator(Fcol, Fs, n);
- float sig = cYIQ.x + dot(cOsc, cYIQ.yz);
- return sig;
- }
- float4 PS_Demodulator(
- float4 pos : SV_POSITION,
- float2 uv : TEXCOORD
- ) : SV_TARGET {
- float2 _uv = uv * ReShade::ScreenSize;
- float Fs = BUFFER_WIDTH;
- float Fcol = Fs * (1.0 / F_COL_DX9);
- float Fcolbw = Fs * (1.0 / F_COL_BW_DX9);
- float Flumlp = Fs * (1.0 / F_LUMA_LP_DX9);
- float n = floor(_uv.x);
- if (__RENDERER__ != 0x09300){
- Fcol = Fs * (1.0 / F_COL);
- Fcolbw = Fs * (1.0 / F_COL_BW);
- Flumlp = Fs * (1.0 / F_LUMA_LP);
- }
- float y_sig = 0.0;
- float iq_sig = 0.0;
- float2 cOsc = Oscillator(Fcol, Fs, n);
- n += float(FIR_SIZE) / 2.0;
- //Separate luma(Y) & chroma(IQ) signals
- [unroll]
- for (int i = 0; i < FIR_SIZE; ++i) {
- int tpidx = FIR_SIZE - i - 1;
- float lp = Lowpass(Flumlp, Fs, FIR_SIZE, tpidx);
- float bp = Bandpass(Fcol - Fcolbw, Fcol + Fcolbw, Fs, FIR_SIZE, tpidx);
- y_sig += sample2D(sArtifactColors_Modulator, ReShade::ScreenSize, float2(n - float(i), _uv.y)).x * lp;
- iq_sig += sample2D(sArtifactColors_Modulator, ReShade::ScreenSize, float2(n - float(i), _uv.y)).x * bp;
- }
- //Shift IQ signal down from Fcol to DC
- float2 iq_sig_mix = cmul(float2(iq_sig, 0.0), cOsc);
- return float4(y_sig, iq_sig_mix, 0.0);
- }
- float4 PS_Final(
- float4 pos : SV_POSITION,
- float2 uv : TEXCOORD
- ) : SV_TARGET {
- float Fs = BUFFER_WIDTH;
- float Fcol = Fs * (1.0 / F_COL);
- float Flumlp = Fs * (1.0 / F_LUMA_LP);
- float n = floor(uv.x * BUFFER_WIDTH);
- if (__RENDERER__ != 0x09300){
- Fcol = Fs * (1.0 / F_COL_DX9);
- Flumlp = Fs * (1.0 / F_LUMA_LP_DX9);
- }
- float2 _uv = uv * ReShade::ScreenSize;
- float luma = sample2D(sArtifactColors_Demodulator, ReShade::ScreenSize, _uv).x;
- float2 chroma = 0.0;
- //Filtering out unwanted high frequency content from the chroma(IQ) signal
- [unroll]
- for (int i = 0; i < FIR_SIZE; ++i) {
- int tpidx = FIR_SIZE - i -1;
- float lp = Lowpass(Flumlp, Fs, FIR_SIZE, tpidx);
- chroma += sample2D(sArtifactColors_Demodulator, ReShade::ScreenSize, _uv - float2(i - FIR_SIZE / 2, 0)).yz * lp;
- }
- //chroma *= rotate(tau * HUE);
- chroma = MUL(chroma, rotate(tau * HUE));
- float3 color = MUL(yiq2rgb, float3(BRIGHTNESS * luma, chroma * SATURATION));
- if (Viewmode == 0) {
- return float4(color, 0.0);
- } else if (Viewmode == 1) {
- return tex2D(sArtifactColors_Modulator, uv).xxxx;
- } else if (Viewmode == 2){
- return float4(luma.xxx, 0.0);
- } else if (Viewmode == 3){
- return float4(40.0 * chroma + 0.5, 0.0, 0.0);
- } else if (Viewmode == 4){
- return 0.5 * tex2D(sArtifactColors_Demodulator, uv).xxxx + 0.25;
- } else if (Viewmode == 5){
- if (uv.x < 0.5)
- return tex2D(sArtifactColors_Modulator, uv).xxxx;
- else
- return float4(color, 0.0);
- } else {
- return 0;
- }
- }
- //Technique//////////////////////////////////////////////////////////////////////////////////////
- technique ArtifactColors {
- pass Resize {
- VertexShader = PostProcessVS;
- PixelShader = PS_Stock;
- RenderTarget = ArtifactChannel0_tex;
- }
- pass Modulator {
- VertexShader = PostProcessVS;
- PixelShader = PS_Modulator;
- RenderTarget = tArtifactColors_Modulator;
- }
- pass Demodulator {
- VertexShader = PostProcessVS;
- PixelShader = PS_Demodulator;
- RenderTarget = tArtifactColors_Demodulator;
- }
- pass Final {
- VertexShader = PostProcessVS;
- PixelShader = PS_Final;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement