mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-22 13:55:38 +00:00
Resources: Fix crt-lottes under Direct3D
And add additional builtin shaders.
This commit is contained in:
parent
344d2ccd5d
commit
a22eef63b9
|
@ -133,7 +133,7 @@ float3 ToLinear(float3 c)
|
||||||
}
|
}
|
||||||
float3 ToSrgb(float3 c)
|
float3 ToSrgb(float3 c)
|
||||||
{
|
{
|
||||||
return pow(c, float3(1.0 / 2.2));
|
return pow(c, float3(1.0 / 2.2, 1.0 / 2.2, 1.0 / 2.2));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
float ToLinear1(float c)
|
float ToLinear1(float c)
|
||||||
|
|
298
data/resources/shaders/reshade/Shaders/CRT-NewPixie.fx
Normal file
298
data/resources/shaders/reshade/Shaders/CRT-NewPixie.fx
Normal file
|
@ -0,0 +1,298 @@
|
||||||
|
#include "ReShade.fxh"
|
||||||
|
|
||||||
|
// newpixie CRT
|
||||||
|
// by Mattias Gustavsson
|
||||||
|
// adapted for slang by hunterk
|
||||||
|
|
||||||
|
/*
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
This software is available under 2 licenses - you may choose the one you like.
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
ALTERNATIVE A - MIT License
|
||||||
|
Copyright (c) 2016 Mattias Gustavsson
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
of the Software, and to permit persons to whom the Software is furnished to do
|
||||||
|
so, subject to the following conditions:
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
ALTERNATIVE B - Public Domain (www.unlicense.org)
|
||||||
|
This is free and unencumbered software released into the public domain.
|
||||||
|
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
||||||
|
software, either in source code form or as a compiled binary, for any purpose,
|
||||||
|
commercial or non-commercial, and by any means.
|
||||||
|
In jurisdictions that recognize copyright laws, the author or authors of this
|
||||||
|
software dedicate any and all copyright interest in the software to the public
|
||||||
|
domain. We make this dedication for the benefit of the public at large and to
|
||||||
|
the detriment of our heirs and successors. We intend this dedication to be an
|
||||||
|
overt act of relinquishment in perpetuity of all present and future rights to
|
||||||
|
this software under copyright law.
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
uniform float acc_modulate <
|
||||||
|
ui_type = "drag";
|
||||||
|
ui_min = 0.0;
|
||||||
|
ui_max = 1.0;
|
||||||
|
ui_step = 0.01;
|
||||||
|
ui_label = "Accumulate Modulation [CRT-NewPixie]";
|
||||||
|
> = 0.65;
|
||||||
|
|
||||||
|
|
||||||
|
texture2D tAccTex { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; };
|
||||||
|
sampler sAccTex { Texture=tAccTex; };
|
||||||
|
|
||||||
|
//PASS 1
|
||||||
|
float3 PrevColor(float4 pos : SV_Position, float2 uv : TEXCOORD0) : SV_Target
|
||||||
|
{
|
||||||
|
return tex2D(ReShade::BackBuffer, uv).rgb;
|
||||||
|
}
|
||||||
|
|
||||||
|
float4 PS_NewPixie_Accum(float4 pos : SV_Position, float2 uv : TEXCOORD0) : SV_Target
|
||||||
|
{
|
||||||
|
float4 a = tex2D(sAccTex, uv.xy) * float4(acc_modulate,acc_modulate,acc_modulate,acc_modulate);
|
||||||
|
float4 b = tex2D(ReShade::BackBuffer, uv.xy);
|
||||||
|
return max( a, b * 0.96 );
|
||||||
|
}
|
||||||
|
|
||||||
|
//PASS 2 AND 3
|
||||||
|
texture GaussianBlurTex { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; };
|
||||||
|
sampler GaussianBlurSampler { Texture = GaussianBlurTex;};
|
||||||
|
|
||||||
|
uniform float blur_x <
|
||||||
|
ui_type = "drag";
|
||||||
|
ui_min = 0.0;
|
||||||
|
ui_max = 5.0;
|
||||||
|
ui_step = 0.25;
|
||||||
|
ui_label = "Horizontal Blur [CRT-NewPixie]";
|
||||||
|
> = 1.0;
|
||||||
|
|
||||||
|
uniform float blur_y <
|
||||||
|
ui_type = "drag";
|
||||||
|
ui_min = 0.0;
|
||||||
|
ui_max = 5.0;
|
||||||
|
ui_step = 0.25;
|
||||||
|
ui_label = "Vertical Blur [CRT-NewPixie]";
|
||||||
|
> = 1.0;
|
||||||
|
|
||||||
|
float4 PS_NewPixie_Blur(float4 pos : SV_Position, float2 uv_tx : TEXCOORD0) : SV_Target
|
||||||
|
{
|
||||||
|
float2 blur = float2(blur_x, blur_y) * ReShade::PixelSize.xy;
|
||||||
|
float2 uv = uv_tx.xy;
|
||||||
|
float4 sum = tex2D( ReShade::BackBuffer, uv ) * 0.2270270270;
|
||||||
|
sum += tex2D(ReShade::BackBuffer, float2( uv.x - 4.0 * blur.x, uv.y - 4.0 * blur.y ) ) * 0.0162162162;
|
||||||
|
sum += tex2D(ReShade::BackBuffer, float2( uv.x - 3.0 * blur.x, uv.y - 3.0 * blur.y ) ) * 0.0540540541;
|
||||||
|
sum += tex2D(ReShade::BackBuffer, float2( uv.x - 2.0 * blur.x, uv.y - 2.0 * blur.y ) ) * 0.1216216216;
|
||||||
|
sum += tex2D(ReShade::BackBuffer, float2( uv.x - 1.0 * blur.x, uv.y - 1.0 * blur.y ) ) * 0.1945945946;
|
||||||
|
sum += tex2D(ReShade::BackBuffer, float2( uv.x + 1.0 * blur.x, uv.y + 1.0 * blur.y ) ) * 0.1945945946;
|
||||||
|
sum += tex2D(ReShade::BackBuffer, float2( uv.x + 2.0 * blur.x, uv.y + 2.0 * blur.y ) ) * 0.1216216216;
|
||||||
|
sum += tex2D(ReShade::BackBuffer, float2( uv.x + 3.0 * blur.x, uv.y + 3.0 * blur.y ) ) * 0.0540540541;
|
||||||
|
sum += tex2D(ReShade::BackBuffer, float2( uv.x + 4.0 * blur.x, uv.y + 4.0 * blur.y ) ) * 0.0162162162;
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
//PASS 4
|
||||||
|
uniform int FCount < source = "framecount"; >;
|
||||||
|
texture tFrame < source = "crt-newpixie/crtframe.png"; >
|
||||||
|
{
|
||||||
|
Width = 1024;
|
||||||
|
Height = 1024;
|
||||||
|
MipLevels = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
sampler sFrame { Texture = tFrame; AddressU = BORDER; AddressV = BORDER; MinFilter = LINEAR; MagFilter = LINEAR;};
|
||||||
|
|
||||||
|
uniform bool use_frame <
|
||||||
|
ui_type = "boolean";
|
||||||
|
ui_label = "Use Frame Image [CRT-NewPixie]";
|
||||||
|
> = false;
|
||||||
|
|
||||||
|
uniform float curvature <
|
||||||
|
ui_type = "drag";
|
||||||
|
ui_min = 0.0001;
|
||||||
|
ui_max = 4.0;
|
||||||
|
ui_step = 0.25;
|
||||||
|
ui_label = "Curvature [CRT-NewPixie]";
|
||||||
|
> = 2.0;
|
||||||
|
|
||||||
|
uniform bool wiggle_toggle <
|
||||||
|
ui_type = "boolean";
|
||||||
|
ui_label = "Interference [CRT-NewPixie]";
|
||||||
|
> = false;
|
||||||
|
|
||||||
|
uniform bool scanroll <
|
||||||
|
ui_type = "boolean";
|
||||||
|
ui_label = "Rolling Scanlines [CRT-NewPixie]";
|
||||||
|
> = true;
|
||||||
|
|
||||||
|
float3 tsample( sampler samp, float2 tc, float offs, float2 resolution )
|
||||||
|
{
|
||||||
|
tc = tc * float2(1.025, 0.92) + float2(-0.0125, 0.04);
|
||||||
|
float3 s = pow( abs( tex2D( samp, float2( tc.x, 1.0-tc.y ) ).rgb), float3( 2.2,2.2,2.2 ) );
|
||||||
|
return s*float3(1.25,1.25,1.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
float3 filmic( float3 LinearColor )
|
||||||
|
{
|
||||||
|
float3 x = max( float3(0.0,0.0,0.0), LinearColor-float3(0.004,0.004,0.004));
|
||||||
|
return (x*(6.2*x+0.5))/(x*(6.2*x+1.7)+0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
float2 curve( float2 uv )
|
||||||
|
{
|
||||||
|
uv = (uv - 0.5);// * 2.0;
|
||||||
|
uv *= float2(0.925, 1.095);
|
||||||
|
uv *= curvature;
|
||||||
|
uv.x *= 1.0 + pow((abs(uv.y) / 4.0), 2.0);
|
||||||
|
uv.y *= 1.0 + pow((abs(uv.x) / 3.0), 2.0);
|
||||||
|
uv /= curvature;
|
||||||
|
uv += 0.5;
|
||||||
|
uv = uv *0.92 + 0.04;
|
||||||
|
return uv;
|
||||||
|
}
|
||||||
|
|
||||||
|
float rand(float2 co){ return frac(sin(dot(co.xy ,float2(12.9898,78.233))) * 43758.5453); }
|
||||||
|
|
||||||
|
#define resolution ReShade::ScreenSize.xy
|
||||||
|
#define mod(x,y) (x-y*floor(x/y))
|
||||||
|
|
||||||
|
float4 PS_NewPixie_Final(float4 pos: SV_Position, float2 uv_tx : TEXCOORD0) : SV_Target
|
||||||
|
{
|
||||||
|
// stop time variable so the screen doesn't wiggle
|
||||||
|
float time = mod(FCount, 849.0) * 36.0;
|
||||||
|
float2 uv = uv_tx.xy;
|
||||||
|
uv.y = 1.0 - uv_tx.y;
|
||||||
|
/* Curve */
|
||||||
|
float2 curved_uv = lerp( curve( uv ), uv, 0.4 );
|
||||||
|
float scale = -0.101;
|
||||||
|
float2 scuv = curved_uv*(1.0-scale)+scale/2.0+float2(0.003, -0.001);
|
||||||
|
|
||||||
|
uv = scuv;
|
||||||
|
|
||||||
|
/* Main color, Bleed */
|
||||||
|
float3 col;
|
||||||
|
|
||||||
|
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;
|
||||||
|
float o =sin(uv_tx.y*1.5)/resolution.x;
|
||||||
|
x+=o*0.25;
|
||||||
|
// make time do something again
|
||||||
|
time = float(mod(FCount, 640) * 1);
|
||||||
|
col.r = tsample(ReShade::BackBuffer,float2(x+scuv.x+0.0009,scuv.y+0.0009),resolution.y/800.0, resolution ).x+0.02;
|
||||||
|
col.g = tsample(ReShade::BackBuffer,float2(x+scuv.x+0.0000,scuv.y-0.0011),resolution.y/800.0, resolution ).y+0.02;
|
||||||
|
col.b = tsample(ReShade::BackBuffer,float2(x+scuv.x-0.0015,scuv.y+0.0000),resolution.y/800.0, resolution ).z+0.02;
|
||||||
|
float i = clamp(col.r*0.299 + col.g*0.587 + col.b*0.114, 0.0, 1.0 );
|
||||||
|
i = pow( 1.0 - pow(i,2.0), 1.0 );
|
||||||
|
i = (1.0-i) * 0.85 + 0.15;
|
||||||
|
|
||||||
|
/* Ghosting */
|
||||||
|
float ghs = 0.15;
|
||||||
|
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),
|
||||||
|
0.35*sin( 2.0/7.0 + 10.0*curved_uv.y + 1.37*time) )+float2(scuv.x+0.001,scuv.y+0.001),
|
||||||
|
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);
|
||||||
|
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),
|
||||||
|
0.35*sin( 2.0/9.0 + 10.0*curved_uv.y + 1.50*time) )+float2(scuv.x+0.000,scuv.y-0.002),
|
||||||
|
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);
|
||||||
|
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),
|
||||||
|
0.35*cos( 2.0/3.0 + 10.0*curved_uv.y + 1.63*time) )+float2(scuv.x-0.002,scuv.y+0.000),
|
||||||
|
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);
|
||||||
|
|
||||||
|
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);
|
||||||
|
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);
|
||||||
|
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);
|
||||||
|
|
||||||
|
/* Level adjustment (curves) */
|
||||||
|
col *= float3(0.95,1.05,0.95);
|
||||||
|
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));
|
||||||
|
|
||||||
|
/* Vignette */
|
||||||
|
float vig = (0.1 + 1.0*16.0*curved_uv.x*curved_uv.y*(1.0-curved_uv.x)*(1.0-curved_uv.y));
|
||||||
|
vig = 1.3*pow(vig,0.5);
|
||||||
|
col *= vig;
|
||||||
|
|
||||||
|
time *= scanroll;
|
||||||
|
|
||||||
|
/* Scanlines */
|
||||||
|
float scans = clamp( 0.35+0.18*sin(6.0*time-curved_uv.y*resolution.y*1.5), 0.0, 1.0);
|
||||||
|
float s = pow(scans,0.9);
|
||||||
|
col = col * float3(s,s,s);
|
||||||
|
|
||||||
|
/* Vertical lines (shadow mask) */
|
||||||
|
col*=1.0-0.23*(clamp((mod(uv_tx.xy.x, 3.0))/2.0,0.0,1.0));
|
||||||
|
|
||||||
|
/* Tone map */
|
||||||
|
col = filmic( col );
|
||||||
|
|
||||||
|
/* Noise */
|
||||||
|
/*float2 seed = floor(curved_uv*resolution.xy*float2(0.5))/resolution.xy;*/
|
||||||
|
float2 seed = curved_uv*resolution.xy;;
|
||||||
|
/* seed = curved_uv; */
|
||||||
|
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) );
|
||||||
|
|
||||||
|
/* Flicker */
|
||||||
|
col *= (1.0-0.004*(sin(50.0*time+curved_uv.y*2.0)*0.5+0.5));
|
||||||
|
|
||||||
|
/* Clamp */
|
||||||
|
// if(max(abs(uv.x-0.5),abs(uv.y-0.5))>0.5)
|
||||||
|
// col = float3(0.0,0.0,0.0);
|
||||||
|
|
||||||
|
// if (curved_uv.x < 0.0 || curved_uv.x > 1.0)
|
||||||
|
// col *= 0.0;
|
||||||
|
// if (curved_uv.y < 0.0 || curved_uv.y > 1.0)
|
||||||
|
// col *= 0.0;
|
||||||
|
|
||||||
|
uv = curved_uv;
|
||||||
|
|
||||||
|
/* Frame */
|
||||||
|
float2 fscale = float2( 0.026, -0.018);//float2( -0.018, -0.013 );
|
||||||
|
uv = float2(uv.x, 1.-uv.y);
|
||||||
|
float4 f= tex2D(sFrame,uv_tx.xy);//*((1.0)+2.0*fscale)-fscale-float2(-0.0, 0.005));
|
||||||
|
f.xyz = lerp( f.xyz, float3(0.5,0.5,0.5), 0.5 );
|
||||||
|
float fvig = clamp( -0.00+512.0*uv.x*uv.y*(1.0-uv.x)*(1.0-uv.y), 0.2, 0.8 );
|
||||||
|
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 ) );
|
||||||
|
|
||||||
|
return float4( col, 1.0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
technique CRTNewPixie
|
||||||
|
{
|
||||||
|
pass PS_CRTNewPixie_Accum
|
||||||
|
{
|
||||||
|
VertexShader=PostProcessVS;
|
||||||
|
PixelShader=PS_NewPixie_Accum;
|
||||||
|
}
|
||||||
|
|
||||||
|
pass PS_CRTNewPixie_SaveBuffer {
|
||||||
|
VertexShader=PostProcessVS;
|
||||||
|
PixelShader=PrevColor;
|
||||||
|
RenderTarget = tAccTex;
|
||||||
|
}
|
||||||
|
|
||||||
|
pass PS_CRTNewPixie_Blur
|
||||||
|
{
|
||||||
|
VertexShader = PostProcessVS;
|
||||||
|
PixelShader = PS_NewPixie_Blur;
|
||||||
|
RenderTarget = GaussianBlurTex;
|
||||||
|
}
|
||||||
|
|
||||||
|
pass PS_CRTNewPixie_Final
|
||||||
|
{
|
||||||
|
VertexShader = PostProcessVS;
|
||||||
|
PixelShader = PS_NewPixie_Final;
|
||||||
|
}
|
||||||
|
}
|
446
data/resources/shaders/reshade/Shaders/CRTLottes2.fx
Normal file
446
data/resources/shaders/reshade/Shaders/CRTLottes2.fx
Normal file
|
@ -0,0 +1,446 @@
|
||||||
|
#include "ReShade.fxh"
|
||||||
|
|
||||||
|
//
|
||||||
|
// PUBLIC DOMAIN CRT STYLED SCAN-LINE SHADER
|
||||||
|
//
|
||||||
|
// by Timothy Lottes
|
||||||
|
//
|
||||||
|
// This is more along the style of a really good CGA arcade monitor.
|
||||||
|
// With RGB inputs instead of NTSC.
|
||||||
|
// The shadow mask example has the mask rotated 90 degrees for less chromatic aberration.
|
||||||
|
//
|
||||||
|
// Left it unoptimized to show the theory behind the algorithm.
|
||||||
|
//
|
||||||
|
// It is an example what I personally would want as a display option for pixel art games.
|
||||||
|
// Please take and use, change, or whatever.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef CRTS_DEBUG
|
||||||
|
#define CRTS_DEBUG 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CRTS_2_TAP
|
||||||
|
#define CRTS_2_TAP 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uniform bool CRTS_WARP <
|
||||||
|
ui_type = "boolean";
|
||||||
|
ui_label = "Enable Warping [CRT Lottes 2.0]";
|
||||||
|
> = true;
|
||||||
|
|
||||||
|
uniform float CRTS_WARP_X <
|
||||||
|
ui_type = "drag";
|
||||||
|
ui_min = 0.0;
|
||||||
|
ui_max = 512.0;
|
||||||
|
ui_label = "CRT Warping X [CRT Lottes 2.0]";
|
||||||
|
> = 64.0;
|
||||||
|
|
||||||
|
uniform float CRTS_WARP_Y <
|
||||||
|
ui_type = "drag";
|
||||||
|
ui_min = 0.0;
|
||||||
|
ui_max = 512.0;
|
||||||
|
ui_label = "CRT Warping Y [CRT Lottes 2.0]";
|
||||||
|
> = 48.0;
|
||||||
|
|
||||||
|
uniform bool CRTS_TONE <
|
||||||
|
ui_type = "boolean";
|
||||||
|
ui_label = "Enable CRT Tonemapping [CRT Lottes 2.0]";
|
||||||
|
> = true;
|
||||||
|
|
||||||
|
uniform bool CRTS_CONTRAST <
|
||||||
|
ui_type = "boolean";
|
||||||
|
ui_label = "Enable CRT Contrast [CRT Lottes 2.0]";
|
||||||
|
> = false;
|
||||||
|
|
||||||
|
uniform bool CRTS_SATURATION <
|
||||||
|
ui_type = "boolean";
|
||||||
|
ui_label = "Enable CRT Saturation [CRT Lottes 2.0]";
|
||||||
|
> = false;
|
||||||
|
|
||||||
|
uniform int CRTS_MASK_TYPE <
|
||||||
|
ui_type = "combo";
|
||||||
|
ui_items = "None\0Aperture Grille\0Aperture Grille (Lite)\0Shadow Mask\0";
|
||||||
|
ui_label = "Mask Type [CRT Lottes 2.0]";
|
||||||
|
> = 2;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
// Scanline thinness
|
||||||
|
// 0.50 = fused scanlines
|
||||||
|
// 0.70 = recommended default
|
||||||
|
// 1.00 = thinner scanlines (too thin)
|
||||||
|
|
||||||
|
uniform float INPUT_THIN <
|
||||||
|
ui_type = "drag";
|
||||||
|
ui_min = 0.5;
|
||||||
|
ui_max = 1.0;
|
||||||
|
ui_label = "Scanlines Thinnes [CRT Lottes 2.0]";
|
||||||
|
> = 0.70;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
// Horizonal scan blur
|
||||||
|
// -3.0 = pixely
|
||||||
|
// -2.5 = default
|
||||||
|
// -2.0 = smooth
|
||||||
|
// -1.0 = too blurry
|
||||||
|
|
||||||
|
uniform float INPUT_BLUR <
|
||||||
|
ui_type = "drag";
|
||||||
|
ui_min = -3.0;
|
||||||
|
ui_max = 0.0;
|
||||||
|
ui_label = "Horizontal Scan Blur [CRT Lottes 2.0]";
|
||||||
|
> = -2.5;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
// Shadow mask effect, ranges from,
|
||||||
|
// 0.25 = large amount of mask (not recommended, too dark)
|
||||||
|
// 0.50 = recommended default
|
||||||
|
// 1.00 = no shadow mask
|
||||||
|
|
||||||
|
uniform float INPUT_MASK <
|
||||||
|
ui_type = "drag";
|
||||||
|
ui_min = 0.0;
|
||||||
|
ui_max = 1.0;
|
||||||
|
ui_label = "Shadow Mask Intensity [CRT Lottes 2.0]";
|
||||||
|
> = 0.5;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
|
||||||
|
uniform int INPUT_X <
|
||||||
|
ui_type = "drag";
|
||||||
|
ui_min = 1;
|
||||||
|
ui_max = BUFFER_WIDTH;
|
||||||
|
ui_label = "Resolution Width [CRT Lottes 2.0]";
|
||||||
|
> = 640;
|
||||||
|
|
||||||
|
uniform int INPUT_Y <
|
||||||
|
ui_type = "drag";
|
||||||
|
ui_min = 1;
|
||||||
|
ui_max = BUFFER_HEIGHT;
|
||||||
|
ui_label = "Resolution Height [CRT Lottes 2.0]";
|
||||||
|
> = 480;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
// Setup the function which returns input image color
|
||||||
|
|
||||||
|
void ToLinear(inout float3 color)
|
||||||
|
{
|
||||||
|
float3 c1 = color.rgb / 12.92;
|
||||||
|
float3 c2 = pow((color.rgb + 0.055)/1.055, 2.4);
|
||||||
|
|
||||||
|
color.r = (color.r <= 0.04045) ? c1.r : c2.r;
|
||||||
|
color.g = (color.g <= 0.04045) ? c1.g : c2.g;
|
||||||
|
color.b = (color.b <= 0.04045) ? c1.b : c2.b;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToSRGB(inout float3 color)
|
||||||
|
{
|
||||||
|
float3 c1 = color.rgb * 12.92;
|
||||||
|
float3 c2 = 1.055 * pow(color.rgb, 0.4166) - 0.055;
|
||||||
|
|
||||||
|
color.r = (color.r < 0.0031308) ? c1.r : c2.r;
|
||||||
|
color.g = (color.g < 0.0031308) ? c1.g : c2.g;
|
||||||
|
color.b = (color.b < 0.0031308) ? c1.b : c2.b;
|
||||||
|
}
|
||||||
|
|
||||||
|
float3 CrtsFetch(float2 uv)
|
||||||
|
{
|
||||||
|
float3 color = tex2D(ReShade::BackBuffer, uv).rgb;
|
||||||
|
ToLinear(color);
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
float4 CrtsTone(
|
||||||
|
float contrast,
|
||||||
|
float saturation,
|
||||||
|
float thin,
|
||||||
|
float mask)
|
||||||
|
{
|
||||||
|
|
||||||
|
mask = INPUT_MASK;
|
||||||
|
|
||||||
|
if (CRTS_MASK_TYPE <= 0){
|
||||||
|
mask=1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(CRTS_MASK_TYPE == 2){
|
||||||
|
mask=0.5+INPUT_MASK*0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
float4 ret;
|
||||||
|
float midOut=0.18/((1.5-thin)*(0.5*mask+0.5));
|
||||||
|
float pMidIn=pow(0.18,contrast);
|
||||||
|
ret.x=contrast;
|
||||||
|
ret.y=((-pMidIn)+midOut)/((1.0-pMidIn)*midOut);
|
||||||
|
ret.z=((-pMidIn)*midOut+pMidIn)/(midOut*(-pMidIn)+midOut);
|
||||||
|
ret.w=contrast+saturation;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
float3 CrtsMask(float2 pos,float dark)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (CRTS_MASK_TYPE == 1){
|
||||||
|
float3 m=dark;
|
||||||
|
float x=frac(pos.x*(1.0/3.0));
|
||||||
|
if(x<(1.0/3.0))m.r=1.0;
|
||||||
|
else if(x<(2.0/3.0))m.g=1.0;
|
||||||
|
else m.b=1.0;
|
||||||
|
return m;
|
||||||
|
} else if (CRTS_MASK_TYPE == 2){
|
||||||
|
float3 m=1.0;
|
||||||
|
float x=frac(pos.x*(1.0/3.0));
|
||||||
|
if(x<(1.0/3.0))m.r=dark;
|
||||||
|
else if(x<(2.0/3.0))m.g=dark;
|
||||||
|
else m.b=dark;
|
||||||
|
return m;
|
||||||
|
} else if(CRTS_MASK_TYPE <= 0){
|
||||||
|
return 1.0;
|
||||||
|
} else if(CRTS_MASK_TYPE >= 3){
|
||||||
|
pos.x+=pos.y*3.0;
|
||||||
|
float3 m=dark;
|
||||||
|
float x=frac(pos.x*(1.0/6.0));
|
||||||
|
if(x<(1.0/3.0))m.r=1.0;
|
||||||
|
else if(x<(2.0/3.0))m.g=1.0;
|
||||||
|
else m.b=1.0;
|
||||||
|
return m;
|
||||||
|
} else {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float3 CrtsFilter(
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
// SV_POSITION, fragCoord.xy
|
||||||
|
float2 ipos,
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
// inputSize / outputSize (in pixels)
|
||||||
|
float2 inputSizeDivOutputSize,
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
// 0.5 * inputSize (in pixels)
|
||||||
|
float2 halfInputSize,
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
// 1.0 / inputSize (in pixels)
|
||||||
|
float2 rcpInputSize,
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
// 1.0 / outputSize (in pixels)
|
||||||
|
float2 rcpOutputSize,
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
// 2.0 / outputSize (in pixels)
|
||||||
|
float2 twoDivOutputSize,
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
// inputSize.y
|
||||||
|
float inputHeight,
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
// Warp scanlines but not phosphor mask
|
||||||
|
// 0.0 = no warp
|
||||||
|
// 1.0/64.0 = light warping
|
||||||
|
// 1.0/32.0 = more warping
|
||||||
|
// Want x and y warping to be different (based on aspect)
|
||||||
|
float2 warp,
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
// Scanline thinness
|
||||||
|
// 0.50 = fused scanlines
|
||||||
|
// 0.70 = recommended default
|
||||||
|
// 1.00 = thinner scanlines (too thin)
|
||||||
|
// Shared with CrtsTone() function
|
||||||
|
float thin,
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
// Horizonal scan blur
|
||||||
|
// -3.0 = pixely
|
||||||
|
// -2.5 = default
|
||||||
|
// -2.0 = smooth
|
||||||
|
// -1.0 = too blurry
|
||||||
|
float blur,
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
// Shadow mask effect, ranges from,
|
||||||
|
// 0.25 = large amount of mask (not recommended, too dark)
|
||||||
|
// 0.50 = recommended default
|
||||||
|
// 1.00 = no shadow mask
|
||||||
|
// Shared with CrtsTone() function
|
||||||
|
float mask,
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
// Tonal curve parameters generated by CrtsTone()
|
||||||
|
float4 tone
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
){
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
#if (CRTS_DEBUG == 1)
|
||||||
|
float2 uv=ipos*rcpOutputSize;
|
||||||
|
// Show second half processed, and first half un-processed
|
||||||
|
if(uv.x<0.5)
|
||||||
|
{
|
||||||
|
// Force nearest to get squares
|
||||||
|
uv*=1.0/rcpInputSize;
|
||||||
|
uv=floor(uv)+float2(0.5,0.5);
|
||||||
|
uv*=rcpInputSize;
|
||||||
|
float3 color=CrtsFetch(uv);
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
float2 pos;
|
||||||
|
float vin;
|
||||||
|
|
||||||
|
if (CRTS_WARP){
|
||||||
|
// Convert to {-1 to 1} range
|
||||||
|
pos=ipos*twoDivOutputSize-float2(1.0,1.0);
|
||||||
|
// Distort pushes image outside {-1 to 1} range
|
||||||
|
pos*=float2(1.0+(pos.y*pos.y)*warp.x,1.0+(pos.x*pos.x)*warp.y);
|
||||||
|
// TODO: Vignette needs optimization
|
||||||
|
vin=1.0-((1.0-saturate(pos.x*pos.x))*(1.0-saturate(pos.y*pos.y)));
|
||||||
|
vin=saturate((-vin)*inputHeight+inputHeight);
|
||||||
|
// Leave in {0 to inputSize}
|
||||||
|
pos=pos*halfInputSize+halfInputSize;
|
||||||
|
} else {
|
||||||
|
pos=ipos*inputSizeDivOutputSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Snap to center of first scanline
|
||||||
|
float y0=floor(pos.y-0.5)+0.5;
|
||||||
|
|
||||||
|
#if (CRTS_2_TAP == 1)
|
||||||
|
// Using Inigo's "Improved Texture Interpolation"
|
||||||
|
// http://iquilezles.org/www/articles/texture/texture.htm
|
||||||
|
pos.x+=0.5;
|
||||||
|
float xi=floor(pos.x);
|
||||||
|
float xf=pos.x-xi;
|
||||||
|
xf=xf*xf*xf*(xf*(xf*6.0-15.0)+10.0);
|
||||||
|
float x0=xi+xf-0.5;
|
||||||
|
float2 p=float2(x0*rcpInputSize.x,y0*rcpInputSize.y);
|
||||||
|
// Coordinate adjusted bilinear fetch from 2 nearest scanlines
|
||||||
|
float3 colA=CrtsFetch(p);
|
||||||
|
p.y+=rcpInputSize.y;
|
||||||
|
float3 colB=CrtsFetch(p);
|
||||||
|
#else
|
||||||
|
// Snap to center of one of four pixels
|
||||||
|
float x0=floor(pos.x-1.5)+0.5;
|
||||||
|
// Inital UV position
|
||||||
|
float2 p=float2(x0*rcpInputSize.x,y0*rcpInputSize.y);
|
||||||
|
// Fetch 4 nearest texels from 2 nearest scanlines
|
||||||
|
float3 colA0=CrtsFetch(p);
|
||||||
|
p.x+=rcpInputSize.x;
|
||||||
|
float3 colA1=CrtsFetch(p);
|
||||||
|
p.x+=rcpInputSize.x;
|
||||||
|
float3 colA2=CrtsFetch(p);
|
||||||
|
p.x+=rcpInputSize.x;
|
||||||
|
float3 colA3=CrtsFetch(p);
|
||||||
|
p.y+=rcpInputSize.y;
|
||||||
|
float3 colB3=CrtsFetch(p);
|
||||||
|
p.x-=rcpInputSize.x;
|
||||||
|
float3 colB2=CrtsFetch(p);
|
||||||
|
p.x-=rcpInputSize.x;
|
||||||
|
float3 colB1=CrtsFetch(p);
|
||||||
|
p.x-=rcpInputSize.x;
|
||||||
|
float3 colB0=CrtsFetch(p);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Vertical filter
|
||||||
|
// Scanline intensity is using sine wave
|
||||||
|
// Easy filter window and integral used later in exposure
|
||||||
|
float off=pos.y-y0;
|
||||||
|
float pi2=6.28318530717958;
|
||||||
|
float hlf=0.5;
|
||||||
|
float scanA=cos(min(0.5, off *thin )*pi2)*hlf+hlf;
|
||||||
|
float scanB=cos(min(0.5,(-off)*thin+thin)*pi2)*hlf+hlf;
|
||||||
|
|
||||||
|
#if (CRTS_2_TAP == 1)
|
||||||
|
if (CRTS_WARP){
|
||||||
|
// Get rid of wrong pixels on edge
|
||||||
|
scanA*=vin;
|
||||||
|
scanB*=vin;
|
||||||
|
}
|
||||||
|
// Apply vertical filter
|
||||||
|
float3 color=(colA*scanA)+(colB*scanB);
|
||||||
|
#else
|
||||||
|
// Horizontal kernel is simple gaussian filter
|
||||||
|
float off0=pos.x-x0;
|
||||||
|
float off1=off0-1.0;
|
||||||
|
float off2=off0-2.0;
|
||||||
|
float off3=off0-3.0;
|
||||||
|
float pix0=exp2(blur*off0*off0);
|
||||||
|
float pix1=exp2(blur*off1*off1);
|
||||||
|
float pix2=exp2(blur*off2*off2);
|
||||||
|
float pix3=exp2(blur*off3*off3);
|
||||||
|
float pixT=rcp(pix0+pix1+pix2+pix3);
|
||||||
|
|
||||||
|
if (CRTS_WARP){
|
||||||
|
// Get rid of wrong pixels on edge
|
||||||
|
pixT*=vin;
|
||||||
|
}
|
||||||
|
scanA*=pixT;
|
||||||
|
scanB*=pixT;
|
||||||
|
// Apply horizontal and vertical filters
|
||||||
|
float3 color=
|
||||||
|
(colA0*pix0+colA1*pix1+colA2*pix2+colA3*pix3)*scanA +
|
||||||
|
(colB0*pix0+colB1*pix1+colB2*pix2+colB3*pix3)*scanB;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Apply phosphor mask
|
||||||
|
color*=CrtsMask(ipos,mask);
|
||||||
|
// Optional color processing
|
||||||
|
if (CRTS_TONE){
|
||||||
|
// Tonal control, start by protecting from /0
|
||||||
|
float peak=max(1.0/(256.0*65536.0),max(color.r,max(color.g,color.b)));
|
||||||
|
// Compute the ratios of {R,G,B}
|
||||||
|
float3 ratio=color*rcp(peak);
|
||||||
|
// Apply tonal curve to peak value
|
||||||
|
if (CRTS_CONTRAST){
|
||||||
|
peak=pow(peak,tone.x);
|
||||||
|
}
|
||||||
|
peak=peak*rcp(peak*tone.y+tone.z);
|
||||||
|
// Apply saturation
|
||||||
|
if (CRTS_SATURATION){
|
||||||
|
ratio=pow(ratio,float3(tone.w,tone.w,tone.w));
|
||||||
|
}
|
||||||
|
// Reconstruct color
|
||||||
|
return ratio*peak;
|
||||||
|
} else {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
//
|
||||||
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
//
|
||||||
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
void PS_CRTLottes2018(float4 vpos : SV_Position, float2 texcoord : TEXCOORD, out float4 color : SV_Target0)
|
||||||
|
{
|
||||||
|
color = tex2D(ReShade::BackBuffer, texcoord.xy);
|
||||||
|
|
||||||
|
color.rgb=CrtsFilter(
|
||||||
|
vpos.xy,
|
||||||
|
float2(INPUT_X,INPUT_Y)/ReShade::ScreenSize.xy,
|
||||||
|
float2(INPUT_X,INPUT_Y)*0.5,
|
||||||
|
1.0/float2(INPUT_X,INPUT_Y),
|
||||||
|
1.0/ReShade::ScreenSize.xy,
|
||||||
|
2.0/ReShade::ScreenSize.xy,
|
||||||
|
INPUT_Y,
|
||||||
|
float2(1.0/CRTS_WARP_X,1.0/CRTS_WARP_Y),
|
||||||
|
INPUT_THIN,
|
||||||
|
INPUT_BLUR,
|
||||||
|
INPUT_MASK,
|
||||||
|
CrtsTone(1.0,0.0,INPUT_THIN,INPUT_MASK));
|
||||||
|
|
||||||
|
ToSRGB(color.rgb);
|
||||||
|
}
|
||||||
|
|
||||||
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
//
|
||||||
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
|
||||||
|
technique CRTLottes2018
|
||||||
|
{
|
||||||
|
pass
|
||||||
|
{
|
||||||
|
VertexShader = PostProcessVS;
|
||||||
|
PixelShader = PS_CRTLottes2018;
|
||||||
|
}
|
||||||
|
}
|
149
data/resources/shaders/reshade/Shaders/FilmGrain2.fx
Normal file
149
data/resources/shaders/reshade/Shaders/FilmGrain2.fx
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
/**
|
||||||
|
* Film Grain post-process shader v1.1
|
||||||
|
* Martins Upitis (martinsh) devlog-martinsh.blogspot.com 2013
|
||||||
|
*
|
||||||
|
* This work is licensed under a Creative Commons Attribution 3.0 Unported License.
|
||||||
|
* So you are free to share, modify and adapt it for your needs, and even use it for commercial use.
|
||||||
|
*
|
||||||
|
* Uses perlin noise shader by toneburst from http://machinesdontcare.wordpress.com/2009/06/25/3d-perlin-noise-sphere-vertex-shader-sourcecode/
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ReShadeUI.fxh"
|
||||||
|
|
||||||
|
uniform float grainamount < __UNIFORM_SLIDER_FLOAT1
|
||||||
|
ui_min = 0.0; ui_max = 0.2;
|
||||||
|
ui_label = "Amount";
|
||||||
|
> = 0.05;
|
||||||
|
uniform float coloramount < __UNIFORM_SLIDER_FLOAT1
|
||||||
|
ui_min = 0.0; ui_max = 1.0;
|
||||||
|
ui_label = "Color Amount";
|
||||||
|
> = 0.6;
|
||||||
|
uniform float lumamount < __UNIFORM_SLIDER_FLOAT1
|
||||||
|
ui_min = 0.0; ui_max = 1.0;
|
||||||
|
ui_label = "Luminance Amount";
|
||||||
|
> = 1.0;
|
||||||
|
|
||||||
|
uniform float grainsize < __UNIFORM_SLIDER_FLOAT1
|
||||||
|
ui_min = 1.5; ui_max = 2.5;
|
||||||
|
ui_label = "Grain Particle Size";
|
||||||
|
> = 1.6;
|
||||||
|
|
||||||
|
#include "ReShade.fxh"
|
||||||
|
|
||||||
|
uniform float timer < source = "timer"; >;
|
||||||
|
|
||||||
|
float4 rnm(in float2 tc)
|
||||||
|
{
|
||||||
|
// A random texture generator, but you can also use a pre-computed perturbation texture
|
||||||
|
float noise = sin(dot(tc, float2(12.9898, 78.233))) * 43758.5453;
|
||||||
|
|
||||||
|
float noiseR = frac(noise) * 2.0 - 1.0;
|
||||||
|
float noiseG = frac(noise * 1.2154) * 2.0 - 1.0;
|
||||||
|
float noiseB = frac(noise * 1.3453) * 2.0 - 1.0;
|
||||||
|
float noiseA = frac(noise * 1.3647) * 2.0 - 1.0;
|
||||||
|
|
||||||
|
return float4(noiseR, noiseG, noiseB, noiseA);
|
||||||
|
}
|
||||||
|
float pnoise3D(in float3 p)
|
||||||
|
{
|
||||||
|
// Perm texture texel-size
|
||||||
|
static const float permTexUnit = 1.0 / 256.0;
|
||||||
|
// Half perm texture texel-size
|
||||||
|
static const float permTexUnitHalf = 0.5 / 256.0;
|
||||||
|
|
||||||
|
// Integer part
|
||||||
|
// Scaled so +1 moves permTexUnit texel and offset 1/2 texel to sample texel centers
|
||||||
|
float3 pi = permTexUnit * floor(p) + permTexUnitHalf;
|
||||||
|
// Fractional part for interpolation
|
||||||
|
float3 pf = frac(p);
|
||||||
|
|
||||||
|
// Noise contributions from (x=0, y=0), z=0 and z=1
|
||||||
|
float perm00 = rnm(pi.xy).a;
|
||||||
|
float3 grad000 = rnm(float2(perm00, pi.z)).rgb * 4.0 - 1.0;
|
||||||
|
float n000 = dot(grad000, pf);
|
||||||
|
float3 grad001 = rnm(float2(perm00, pi.z + permTexUnit)).rgb * 4.0 - 1.0;
|
||||||
|
float n001 = dot(grad001, pf - float3(0.0, 0.0, 1.0));
|
||||||
|
|
||||||
|
// Noise contributions from (x=0, y=1), z=0 and z=1
|
||||||
|
float perm01 = rnm(pi.xy + float2(0.0, permTexUnit)).a;
|
||||||
|
float3 grad010 = rnm(float2(perm01, pi.z)).rgb * 4.0 - 1.0;
|
||||||
|
float n010 = dot(grad010, pf - float3(0.0, 1.0, 0.0));
|
||||||
|
float3 grad011 = rnm(float2(perm01, pi.z + permTexUnit)).rgb * 4.0 - 1.0;
|
||||||
|
float n011 = dot(grad011, pf - float3(0.0, 1.0, 1.0));
|
||||||
|
|
||||||
|
// Noise contributions from (x=1, y=0), z=0 and z=1
|
||||||
|
float perm10 = rnm(pi.xy + float2(permTexUnit, 0.0)).a;
|
||||||
|
float3 grad100 = rnm(float2(perm10, pi.z)).rgb * 4.0 - 1.0;
|
||||||
|
float n100 = dot(grad100, pf - float3(1.0, 0.0, 0.0));
|
||||||
|
float3 grad101 = rnm(float2(perm10, pi.z + permTexUnit)).rgb * 4.0 - 1.0;
|
||||||
|
float n101 = dot(grad101, pf - float3(1.0, 0.0, 1.0));
|
||||||
|
|
||||||
|
// Noise contributions from (x=1, y=1), z=0 and z=1
|
||||||
|
float perm11 = rnm(pi.xy + float2(permTexUnit, permTexUnit)).a;
|
||||||
|
float3 grad110 = rnm(float2(perm11, pi.z)).rgb * 4.0 - 1.0;
|
||||||
|
float n110 = dot(grad110, pf - float3(1.0, 1.0, 0.0));
|
||||||
|
float3 grad111 = rnm(float2(perm11, pi.z + permTexUnit)).rgb * 4.0 - 1.0;
|
||||||
|
float n111 = dot(grad111, pf - float3(1.0, 1.0, 1.0));
|
||||||
|
|
||||||
|
// Blend contributions along x
|
||||||
|
float fade_x = pf.x * pf.x * pf.x * (pf.x * (pf.x * 6.0 - 15.0) + 10.0);
|
||||||
|
float4 n_x = lerp(float4(n000, n001, n010, n011), float4(n100, n101, n110, n111), fade_x);
|
||||||
|
|
||||||
|
// Blend contributions along y
|
||||||
|
float fade_y = pf.y * pf.y * pf.y * (pf.y * (pf.y * 6.0 - 15.0) + 10.0);
|
||||||
|
float2 n_xy = lerp(n_x.xy, n_x.zw, fade_y);
|
||||||
|
|
||||||
|
// Blend contributions along z
|
||||||
|
float fade_z = pf.z * pf.z * pf.z * (pf.z * (pf.z * 6.0 - 15.0) + 10.0);
|
||||||
|
float n_xyz = lerp(n_xy.x, n_xy.y, fade_z);
|
||||||
|
|
||||||
|
// We're done, return the final noise value.
|
||||||
|
return n_xyz;
|
||||||
|
}
|
||||||
|
|
||||||
|
float2 coordRot(in float2 tc, in float angle)
|
||||||
|
{
|
||||||
|
float rotX = ((tc.x * 2.0 - 1.0) * BUFFER_ASPECT_RATIO * cos(angle)) - ((tc.y * 2.0 - 1.0) * sin(angle));
|
||||||
|
float rotY = ((tc.y * 2.0 - 1.0) * cos(angle)) + ((tc.x * 2.0 - 1.0) * BUFFER_ASPECT_RATIO * sin(angle));
|
||||||
|
rotX = ((rotX / BUFFER_ASPECT_RATIO) * 0.5 + 0.5);
|
||||||
|
rotY = rotY * 0.5 + 0.5;
|
||||||
|
|
||||||
|
return float2(rotX, rotY);
|
||||||
|
}
|
||||||
|
|
||||||
|
float4 main(float4 vpos : SV_Position, float2 texCoord : TexCoord) : SV_Target
|
||||||
|
{
|
||||||
|
float3 rotOffset = float3(1.425, 3.892, 5.835); // Rotation offset values
|
||||||
|
float2 rotCoordsR = coordRot(texCoord, timer + rotOffset.x);
|
||||||
|
float3 noise = pnoise3D(float3(rotCoordsR * BUFFER_SCREEN_SIZE / grainsize, 0.0)).xxx;
|
||||||
|
|
||||||
|
if (coloramount > 0)
|
||||||
|
{
|
||||||
|
float2 rotCoordsG = coordRot(texCoord, timer + rotOffset.y);
|
||||||
|
float2 rotCoordsB = coordRot(texCoord, timer + rotOffset.z);
|
||||||
|
noise.g = lerp(noise.r, pnoise3D(float3(rotCoordsG * BUFFER_SCREEN_SIZE / grainsize, 1.0)), coloramount);
|
||||||
|
noise.b = lerp(noise.r, pnoise3D(float3(rotCoordsB * BUFFER_SCREEN_SIZE / grainsize, 2.0)), coloramount);
|
||||||
|
}
|
||||||
|
|
||||||
|
float3 col = tex2D(ReShade::BackBuffer, texCoord).rgb;
|
||||||
|
|
||||||
|
const float3 lumcoeff = float3(0.299, 0.587, 0.114);
|
||||||
|
float luminance = lerp(0.0, dot(col, lumcoeff), lumamount);
|
||||||
|
float lum = smoothstep(0.2, 0.0, luminance);
|
||||||
|
lum += luminance;
|
||||||
|
|
||||||
|
|
||||||
|
noise = lerp(noise, 0.0, pow(lum, 4.0));
|
||||||
|
col = col + noise * grainamount;
|
||||||
|
|
||||||
|
return float4(col, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
technique FilmGrain2
|
||||||
|
{
|
||||||
|
pass
|
||||||
|
{
|
||||||
|
VertexShader = PostProcessVS;
|
||||||
|
PixelShader = main;
|
||||||
|
}
|
||||||
|
}
|
77
data/resources/shaders/reshade/Shaders/scanlines-abs.fx
Normal file
77
data/resources/shaders/reshade/Shaders/scanlines-abs.fx
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
Scanlines Sine Absolute Value
|
||||||
|
An ultra light scanline shader
|
||||||
|
by RiskyJumps
|
||||||
|
license: public domain
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ReShade.fxh"
|
||||||
|
|
||||||
|
uniform float texture_sizeY <
|
||||||
|
ui_type = "drag";
|
||||||
|
ui_min = 1.0;
|
||||||
|
ui_max = BUFFER_HEIGHT;
|
||||||
|
ui_label = "Scanlines Height [Scanlines-Absolute]";
|
||||||
|
> = 240.0;
|
||||||
|
|
||||||
|
uniform float amp <
|
||||||
|
ui_type = "drag";
|
||||||
|
ui_min = 0.0;
|
||||||
|
ui_max = 2.0;
|
||||||
|
ui_step = 0.05;
|
||||||
|
ui_label = "Amplitude [Scanlines-Absolute]";
|
||||||
|
> = 1.25;
|
||||||
|
|
||||||
|
uniform float phase <
|
||||||
|
ui_type = "drag";
|
||||||
|
ui_min = 0.0;
|
||||||
|
ui_max = 2.0;
|
||||||
|
ui_step = 0.05;
|
||||||
|
ui_label = "Phase [Scanlines-Absolute]";
|
||||||
|
> = 0.0;
|
||||||
|
|
||||||
|
uniform float lines_black <
|
||||||
|
ui_type = "drag";
|
||||||
|
ui_min = 0.0;
|
||||||
|
ui_max = 1.0;
|
||||||
|
ui_step = 0.05;
|
||||||
|
ui_label = "Lines Blacks [Scanlines-Absolute]";
|
||||||
|
> = 0.0;
|
||||||
|
|
||||||
|
uniform float lines_white <
|
||||||
|
ui_type = "drag";
|
||||||
|
ui_min = 0.0;
|
||||||
|
ui_max = 2.0;
|
||||||
|
ui_step = 0.05;
|
||||||
|
ui_label = "Lines Whites [Scanlines-Absolute]";
|
||||||
|
> = 1.0;
|
||||||
|
|
||||||
|
#define freq 0.500000
|
||||||
|
#define offset 0.000000
|
||||||
|
#define pi 3.141592654
|
||||||
|
|
||||||
|
float4 PS_ScanlinesAbs(float4 pos : SV_POSITION, float2 tex : TEXCOORD0) : SV_TARGET
|
||||||
|
{
|
||||||
|
float3 color = tex2D(ReShade::BackBuffer, tex).xyz;
|
||||||
|
float grid;
|
||||||
|
|
||||||
|
float lines;
|
||||||
|
|
||||||
|
float omega = 2.0 * pi * freq; // Angular frequency
|
||||||
|
float angle = tex.y * omega * texture_sizeY + phase;
|
||||||
|
|
||||||
|
lines = sin(angle);
|
||||||
|
lines *= amp;
|
||||||
|
lines += offset;
|
||||||
|
lines = abs(lines) * (lines_white - lines_black) + lines_black;
|
||||||
|
color *= lines;
|
||||||
|
|
||||||
|
return color.xyzz;
|
||||||
|
}
|
||||||
|
|
||||||
|
technique ScanlinesAbs {
|
||||||
|
pass ScanlinesAbsolute{
|
||||||
|
VertexShader = PostProcessVS;
|
||||||
|
PixelShader = PS_ScanlinesAbs;
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 250 KiB |
|
@ -1 +1,2 @@
|
||||||
https://github.com/crosire/reshade-shaders
|
https://github.com/crosire/reshade-shaders
|
||||||
|
https://github.com/Matsilagi/RSRetroArch/
|
||||||
|
|
|
@ -71,7 +71,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
<h3>cubeb - <a href="https://github.com/mozilla/cubeb">https://github.com/mozilla/cubeb</a></h3>
|
<h3>cubeb - <a href="https://github.com/mozilla/cubeb">https://github.com/mozilla/cubeb</a></h3>
|
||||||
<pre>
|
<pre>
|
||||||
Copyright © 2011 Mozilla Foundation
|
Copyright 2011 Mozilla Foundation
|
||||||
|
|
||||||
Permission to use, copy, modify, and distribute this software for any
|
Permission to use, copy, modify, and distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -1624,7 +1624,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2014-2021 Florian Bernd
|
Copyright (c) 2014-2021 Florian Bernd
|
||||||
Copyright (c) 2014-2021 Joel Höner
|
Copyright (c) 2014-2021 Joel H ner
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -1645,5 +1645,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
Some shaders provided with the application are sourced from <a href="https://github.com/Matsilagi/RSRetroArch/">https://github.com/Matsilagi/RSRetroArch/</a>.<br>
|
||||||
|
License details are included in the relevant shader source files, under resources\shaders\reshade.
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Reference in a new issue