From 885bf8d7c0506fa43624e591d37ec9b54c39357a Mon Sep 17 00:00:00 2001 From: Robert Beckebans Date: Fri, 2 Aug 2024 17:30:01 +0200 Subject: [PATCH] Combined easymode CRT with a NTSC signal --- neo/renderer/RenderProgs.cpp | 2 +- neo/shaders/builtin/post/crt_aperture.ps.hlsl | 8 +- neo/shaders/builtin/post/crt_easymode.ps.hlsl | 131 +++++++++++++++++- neo/shaders/builtin/post/crt_newpixie.ps.hlsl | 10 +- 4 files changed, 131 insertions(+), 20 deletions(-) diff --git a/neo/renderer/RenderProgs.cpp b/neo/renderer/RenderProgs.cpp index 674766f4..c27f75c9 100644 --- a/neo/renderer/RenderProgs.cpp +++ b/neo/renderer/RenderProgs.cpp @@ -539,7 +539,7 @@ void idRenderProgManager::Init( nvrhi::IDevice* device ) { BUILTIN_POSTPROCESS_RETRO_PSX, "builtin/post/retro_ps1", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_POST_PROCESS_FINAL }, { BUILTIN_CRT_MATTIAS, "builtin/post/crt_mattias", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_POST_PROCESS_FINAL }, { BUILTIN_CRT_NUPIXIE, "builtin/post/crt_newpixie", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_POST_PROCESS_FINAL }, - { BUILTIN_CRT_EASYMODE, "builtin/post/crt_aperture", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_POST_PROCESS_FINAL }, + { BUILTIN_CRT_EASYMODE, "builtin/post/crt_easymode", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_POST_PROCESS_FINAL }, { BUILTIN_SCREEN, "builtin/post/screen", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT }, { BUILTIN_TONEMAP, "builtin/post/tonemap", "", { { "BRIGHTPASS", "0" }, { "HDR_DEBUG", "0"} }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT }, diff --git a/neo/shaders/builtin/post/crt_aperture.ps.hlsl b/neo/shaders/builtin/post/crt_aperture.ps.hlsl index 87e1ced7..e194da06 100644 --- a/neo/shaders/builtin/post/crt_aperture.ps.hlsl +++ b/neo/shaders/builtin/post/crt_aperture.ps.hlsl @@ -78,6 +78,7 @@ struct Params float SCANLINE_SIZE_MAX; float SCANLINE_SHAPE; float SCANLINE_OFFSET; + float SCANLINE_STRENGTH; float GAMMA_INPUT; float GAMMA_OUTPUT; float BRIGHTNESS; @@ -186,7 +187,7 @@ float3 get_scanline_weight( float x, float3 col, Params params ) float3 x_mul = 2.0 / beam; float3 x_offset = x_mul * 0.5; - return smoothstep( 0.0, 1.0, 1.0 - abs( x * x_mul - x_offset ) ) * x_offset; + return smoothstep( 0.0, 1.0, 1.0 - abs( x * x_mul - x_offset ) ) * x_offset * params.SCANLINE_STRENGTH; } float3 get_mask_weight( float x, Params params ) @@ -231,14 +232,15 @@ void main( PS_IN fragment, out PS_OUT result ) params.GLOW_WIDTH = 0.5; params.GLOW_HEIGHT = 0.5; params.GLOW_HALATION = 0.1; - params.GLOW_DIFFUSION = 0.05; + params.GLOW_DIFFUSION = 0.5; params.MASK_COLORS = 2.0; - params.MASK_STRENGTH = 0.3; + params.MASK_STRENGTH = 0.5; params.MASK_SIZE = 1.0; params.SCANLINE_SIZE_MIN = 0.5; params.SCANLINE_SIZE_MAX = 1.5; params.SCANLINE_SHAPE = 2.5; params.SCANLINE_OFFSET = 1.0; + params.SCANLINE_STRENGTH = 1.0; params.GAMMA_INPUT = 2.4; params.GAMMA_OUTPUT = 2.4; params.BRIGHTNESS = 1.5; diff --git a/neo/shaders/builtin/post/crt_easymode.ps.hlsl b/neo/shaders/builtin/post/crt_easymode.ps.hlsl index b694349f..bf00b7d5 100644 --- a/neo/shaders/builtin/post/crt_easymode.ps.hlsl +++ b/neo/shaders/builtin/post/crt_easymode.ps.hlsl @@ -55,9 +55,10 @@ struct PS_OUT #define FIX(c) max(abs(c), 1e-5) // Set to 0 to use linear filter and gain speed -#define ENABLE_LANCZOS 1 +#define ENABLE_LANCZOS 0 +#define ENABLE_NTSC 1 -#define RESOLUTION_DIVISOR 6.0 +#define RESOLUTION_DIVISOR 4.0 float4 dilate( float4 col ) { @@ -121,6 +122,119 @@ float2 curve( float2 uv, float curvature ) return uv; } +#if 1 +float3 rgb2yiq( float3 c ) +{ + return float3( + ( 0.2989 * c.x + 0.5959 * c.y + 0.2115 * c.z ), + ( 0.5870 * c.x - 0.2744 * c.y - 0.5229 * c.z ), + ( 0.1140 * c.x - 0.3216 * c.y + 0.3114 * c.z ) + ); +} + +float3 yiq2rgb( float3 c ) +{ + return float3( + ( 1.0 * c.x + 1.0 * c.y + 1.0 * c.z ), + ( 0.956 * c.x - 0.2720 * c.y - 1.1060 * c.z ), + ( 0.6210 * c.x - 0.6474 * c.y + 1.7046 * c.z ) + ); +} + +float2 circle( float start, float points, float p ) +{ + float rad = ( 3.141592 * 2.0 * ( 1.0 / points ) ) * ( p + start ); + //return float2(sin(rad), cos(rad)); + return float2( -( .3 + rad ), cos( rad ) ); + +} + +float3 blur( float2 uv, float f, float d ) +{ + float t = 0.0; + float b = 1.0; + + float2 pixelOffset = float2( d + 0.0005 * t, 0 ); + + float start = 2.0 / 14.0; + float2 scale = 0.66 * 4.0 * 2.0 * pixelOffset.xy; + + //t_CurrentRender.Sample( s_LinearClamp, c ).rgb + float3 N0 = t_CurrentRender.Sample( s_LinearClamp, uv + circle( start, 14.0, 0.0 ) * scale ).rgb; + float3 N1 = t_CurrentRender.Sample( s_LinearClamp, uv + circle( start, 14.0, 1.0 ) * scale ).rgb; + float3 N2 = t_CurrentRender.Sample( s_LinearClamp, uv + circle( start, 14.0, 2.0 ) * scale ).rgb; + float3 N3 = t_CurrentRender.Sample( s_LinearClamp, uv + circle( start, 14.0, 3.0 ) * scale ).rgb; + float3 N4 = t_CurrentRender.Sample( s_LinearClamp, uv + circle( start, 14.0, 4.0 ) * scale ).rgb; + float3 N5 = t_CurrentRender.Sample( s_LinearClamp, uv + circle( start, 14.0, 5.0 ) * scale ).rgb; + float3 N6 = t_CurrentRender.Sample( s_LinearClamp, uv + circle( start, 14.0, 6.0 ) * scale ).rgb; + float3 N7 = t_CurrentRender.Sample( s_LinearClamp, uv + circle( start, 14.0, 7.0 ) * scale ).rgb; + float3 N8 = t_CurrentRender.Sample( s_LinearClamp, uv + circle( start, 14.0, 8.0 ) * scale ).rgb; + float3 N9 = t_CurrentRender.Sample( s_LinearClamp, uv + circle( start, 14.0, 9.0 ) * scale ).rgb; + float3 N10 = t_CurrentRender.Sample( s_LinearClamp, uv + circle( start, 14.0, 10.0 ) * scale ).rgb; + float3 N11 = t_CurrentRender.Sample( s_LinearClamp, uv + circle( start, 14.0, 11.0 ) * scale ).rgb; + float3 N12 = t_CurrentRender.Sample( s_LinearClamp, uv + circle( start, 14.0, 12.0 ) * scale ).rgb; + float3 N13 = t_CurrentRender.Sample( s_LinearClamp, uv + circle( start, 14.0, 13.0 ) * scale ).rgb; + float3 N14 = t_CurrentRender.Sample( s_LinearClamp, uv ).rgb; + + float4 clr = t_CurrentRender.Sample( s_LinearClamp, uv ); + float W = 1.0 / 15.0; + + clr.rgb = + ( N0 * W ) + + ( N1 * W ) + + ( N2 * W ) + + ( N3 * W ) + + ( N4 * W ) + + ( N5 * W ) + + ( N6 * W ) + + ( N7 * W ) + + ( N8 * W ) + + ( N9 * W ) + + ( N10 * W ) + + ( N11 * W ) + + ( N12 * W ) + + ( N13 * W ) + + ( N14 * W ); + + return float3( clr.xyz ) * b; +} + + + +float3 get_blurred_pixel( float2 uv ) +{ + float d = 0.0; + float s = 0.0; + + float e = min( 0.30, pow( max( 0.0, cos( uv.y * 4.0 + 0.3 ) - 0.75 ) * ( s + 0.5 ) * 1.0, 3.0 ) ) * 25.0; + + d = 0.051 + abs( sin( s / 4.0 ) ); + float c = max( 0.0001, 0.002 * d ); + float2 uvo = uv; + // uv.x+=.1*d; + + float3 fragColor; + fragColor.xyz = blur( uv, 0.0, c + c * ( uv.x ) ); + float y = rgb2yiq( fragColor.xyz ).r; + + uv.x += 0.01 * d; + c *= 6.0; + fragColor.xyz = blur( uv, 0.333, c ); + float i = rgb2yiq( fragColor.xyz ).g; + + uv.x += 0.005 * d; + c *= 2.50; + fragColor.xyz = blur( uv, 0.666, c ); + float q = rgb2yiq( fragColor.xyz ).b; + + fragColor.xyz = yiq2rgb( float3( y, i, q ) ) - pow( s + e * 2.0, 3.0 ); + fragColor.xyz *= smoothstep( 1.0, .999, uv.x - 0.1 ); + + return fragColor; +} +#endif + + void main( PS_IN fragment, out PS_OUT result ) { // revised version from RetroArch @@ -147,13 +261,13 @@ void main( PS_IN fragment, out PS_OUT result ) }; Params params; - params.BRIGHT_BOOST = 1.2; + params.BRIGHT_BOOST = 1.5; params.DILATION = 1.0; - params.GAMMA_INPUT = 2.0; - params.GAMMA_OUTPUT = 1.8; + params.GAMMA_INPUT = 2.4; + params.GAMMA_OUTPUT = 2.5; params.MASK_SIZE = 1.0; params.MASK_STAGGER = 0.0; - params.MASK_STRENGTH = 0.8; + params.MASK_STRENGTH = 0.4; params.MASK_DOT_HEIGHT = 1.0; params.MASK_DOT_WIDTH = 1.0; params.SCANLINE_CUTOFF = 400.0; @@ -206,6 +320,9 @@ void main( PS_IN fragment, out PS_OUT result ) col = filter_lanczos( coeffs, get_color_matrix( tex_co, dx ) ); col2 = filter_lanczos( coeffs, get_color_matrix( tex_co + dy, dx ) ); + +#elif ENABLE_NTSC + col = col2 = get_blurred_pixel( vTexCoord ); #else curve_x = curve_distance( dist.x, params.SHARPNESS_H ); @@ -214,7 +331,7 @@ void main( PS_IN fragment, out PS_OUT result ) #endif col = lerp( col, col2, curve_distance( dist.y, params.SHARPNESS_V ) ); - col = pow( col, _float3( params.GAMMA_INPUT / ( params.DILATION + 1.0 ) ) ); + col = pow( col, _float3( params.GAMMA_INPUT ) ); /// ( params.DILATION + 1.0 ) ) ); float luma = dot( float3( 0.2126, 0.7152, 0.0722 ), col ); float bright = ( max( col.r, max( col.g, col.b ) ) + luma ) * 0.5; diff --git a/neo/shaders/builtin/post/crt_newpixie.ps.hlsl b/neo/shaders/builtin/post/crt_newpixie.ps.hlsl index 1b7aba6a..23ef21bd 100644 --- a/neo/shaders/builtin/post/crt_newpixie.ps.hlsl +++ b/neo/shaders/builtin/post/crt_newpixie.ps.hlsl @@ -53,7 +53,7 @@ struct PS_OUT float3 tsample( Texture2D tex, float2 tc, float offs, float2 resolution ) { #if 1 - // DON'T this messes really everythign up tc = tc * float2( 1.025, 0.92 ) + float2( -0.0125, 0.04 ); + // DON'T : this really messes everything up tc = tc * float2( 1.025, 0.92 ) + float2( -0.0125, 0.04 ); float3 s = pow( abs( tex.Sample( s_LinearClamp, float2( tc.x, tc.y ) ).rgb ), _float3( 2.2 ) ); return s * _float3( 1.25 ); #else @@ -150,17 +150,9 @@ void main( PS_IN fragment, out PS_OUT result ) time = float( mod( params.FrameCount, 640 ) * 1 ); Texture2D backbuffer = t_CurrentRender; -#if 1 col.r = tsample( backbuffer, float2( x + scuv.x + 0.0009, scuv.y + 0.0009 ), resolution.y / 800.0, resolution ).x + 0.02; col.g = tsample( backbuffer, float2( x + scuv.x + 0.0000, scuv.y - 0.0011 ), resolution.y / 800.0, resolution ).y + 0.02; col.b = tsample( backbuffer, float2( x + scuv.x - 0.0015, scuv.y + 0.0000 ), resolution.y / 800.0, resolution ).z + 0.02; -#else - col.r = t_CurrentRender.Sample( LinearSampler, float2( x + uv.x + 0.001, uv.y + 0.001 ) ).x + 0.05; - col.g = t_CurrentRender.Sample( LinearSampler, float2( x + uv.x + 0.000, uv.y - 0.002 ) ).y + 0.05; - col.b = t_CurrentRender.Sample( LinearSampler, float2( x + uv.x - 0.002, uv.y + 0.000 ) ).z + 0.05; -#endif - - /* Ghosting */ #if 1