mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-04-22 09:40:46 +00:00
Ported RetroArch Aperture CRT shader but not much better than Easymode
This commit is contained in:
parent
cef666f2fd
commit
e14d6d595c
6 changed files with 165 additions and 142 deletions
|
@ -8,7 +8,8 @@ bind "F2" "toggle r_showTris 1 2 0"
|
|||
bind "F3" "toggle r_forceAmbient 0.5 1.0 0"
|
||||
bind "F4" "toggle r_skipInteractions"
|
||||
bind "F5" "savegame quick"
|
||||
bind "F6" "toggle r_showLightGrid 1 3 4 0"
|
||||
//bind "F6" "toggle r_showLightGrid 1 3 4 0"
|
||||
bind "F6" "toggle r_renderMode 0 1 3 5 7 9 11"
|
||||
bind "F7" "toggle r_renderMode 0 1 2 3 4 5 6 7 8 9 10 11"
|
||||
bind "F8" "toggle r_useCRTPostFX 0 1 2 3"
|
||||
bind "F9" "loadgame quick"
|
||||
|
|
|
@ -455,8 +455,8 @@ float idConsoleLocal::DrawFPS( float y )
|
|||
"CPC Hi",
|
||||
"NES",
|
||||
"NES Hi",
|
||||
"Sega",
|
||||
"Sega Hi",
|
||||
"Sega MD",
|
||||
"Sega MD Hi",
|
||||
"Sony PSX",
|
||||
};
|
||||
|
||||
|
|
|
@ -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_easymode", "", {}, 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_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 },
|
||||
|
|
|
@ -51,7 +51,7 @@ struct PS_OUT
|
|||
};
|
||||
// *INDENT-ON*
|
||||
|
||||
#define TEX2D(c) dilate(t_CurrentRender.Sample( s_LinearClamp, c ).rgba)
|
||||
#define TEX2D(c) dilate(t_CurrentRender.Sample( s_LinearClamp, c ).rgb)
|
||||
#define FIX(c) max(abs(c), 1e-5)
|
||||
|
||||
// Set to 0 to use linear filter and gain speed
|
||||
|
@ -59,16 +59,40 @@ struct PS_OUT
|
|||
|
||||
#define RESOLUTION_DIVISOR 4.0
|
||||
|
||||
float4 dilate( float4 col )
|
||||
struct Params
|
||||
{
|
||||
float4 sourceSize;
|
||||
float4 outputSize;
|
||||
uint FrameCount;
|
||||
|
||||
float SHARPNESS_IMAGE;
|
||||
float SHARPNESS_EDGES;
|
||||
float GLOW_WIDTH;
|
||||
float GLOW_HEIGHT;
|
||||
float GLOW_HALATION;
|
||||
float GLOW_DIFFUSION;
|
||||
float MASK_COLORS;
|
||||
float MASK_STRENGTH;
|
||||
float MASK_SIZE;
|
||||
float SCANLINE_SIZE_MIN;
|
||||
float SCANLINE_SIZE_MAX;
|
||||
float SCANLINE_SHAPE;
|
||||
float SCANLINE_OFFSET;
|
||||
float GAMMA_INPUT;
|
||||
float GAMMA_OUTPUT;
|
||||
float BRIGHTNESS;
|
||||
};
|
||||
|
||||
float3 dilate( float3 col )
|
||||
{
|
||||
#if 1
|
||||
// FIXME
|
||||
//float4 x = lerp( _float4( 1.0 ), col, params.DILATION );
|
||||
float4 x = lerp( _float4( 1.0 ), col, 1.0 );
|
||||
return col * x;
|
||||
#else
|
||||
return col;
|
||||
#endif
|
||||
//return pow(col, float3(params.GAMMA_INPUT))
|
||||
return pow( col, _float3( 2.4 ) );
|
||||
}
|
||||
|
||||
float mod( float x, float y )
|
||||
{
|
||||
return x - y * floor( x / y );
|
||||
}
|
||||
|
||||
float curve_distance( float x, float sharp )
|
||||
|
@ -85,31 +109,106 @@ float curve_distance( float x, float sharp )
|
|||
return lerp( x, curve, sharp );
|
||||
}
|
||||
|
||||
float4x4 get_color_matrix( float2 co, float2 dx )
|
||||
float3x3 get_color_matrix( float2 co, float2 dx )
|
||||
{
|
||||
return float4x4( TEX2D( co - dx ), TEX2D( co ), TEX2D( co + dx ), TEX2D( co + 2.0 * dx ) );
|
||||
return float3x3( TEX2D( co - dx ), TEX2D( co ), TEX2D( co + dx ) );
|
||||
}
|
||||
float3 blur( float3x3 m, float dist, float rad )
|
||||
{
|
||||
float3 x = float3( dist - 1.0, dist, dist + 1.0 ) / rad;
|
||||
float3 w = exp2( x * x * -1.0 );
|
||||
|
||||
// transpose for HLSL
|
||||
//m = transpose(m);
|
||||
//return m;
|
||||
return ( m[0] * w.x + m[1] * w.y + m[2] * w.z ) / ( w.x + w.y + w.z );
|
||||
}
|
||||
|
||||
float3 filter_lanczos( float4 coeffs, float4x4 color_matrix )
|
||||
float3 filter_gaussian( float2 co, float2 tex_size, Params params )
|
||||
{
|
||||
float4 col = mul( color_matrix, coeffs );
|
||||
float4 sample_min = min( color_matrix[1], color_matrix[2] );
|
||||
float4 sample_max = max( color_matrix[1], color_matrix[2] );
|
||||
float2 dx = float2( 1.0 / tex_size.x, 0.0 );
|
||||
float2 dy = float2( 0.0, 1.0 / tex_size.y );
|
||||
float2 pix_co = co * tex_size;
|
||||
float2 tex_co = ( floor( pix_co ) + 0.5 ) / tex_size;
|
||||
float2 dist = ( frac( pix_co ) - 0.5 ) * -1.0;
|
||||
|
||||
float3x3 line0 = get_color_matrix( tex_co - dy, dx );
|
||||
float3x3 line1 = get_color_matrix( tex_co, dx );
|
||||
float3x3 line2 = get_color_matrix( tex_co + dy, dx );
|
||||
float3x3 column = float3x3( blur( line0, dist.x, params.GLOW_WIDTH ),
|
||||
blur( line1, dist.x, params.GLOW_WIDTH ),
|
||||
blur( line2, dist.x, params.GLOW_WIDTH ) );
|
||||
|
||||
return blur( column, dist.y, params.GLOW_HEIGHT );
|
||||
}
|
||||
|
||||
float3 filter_lanczos2( float4 coeffs, float3x3 color_matrix )
|
||||
{
|
||||
float3 col = mul( color_matrix, coeffs.rgb );
|
||||
float3 sample_min = min( color_matrix[1], color_matrix[2] );
|
||||
float3 sample_max = max( color_matrix[1], color_matrix[2] );
|
||||
|
||||
col = clamp( col, sample_min, sample_max );
|
||||
|
||||
return col.rgb;
|
||||
}
|
||||
|
||||
float mod( float x, float y )
|
||||
float3 filter_lanczos( float2 co, float2 tex_size, float sharp )
|
||||
{
|
||||
return x - y * floor( x / y );
|
||||
tex_size.x *= sharp;
|
||||
|
||||
float2 dx = float2( 1.0 / tex_size.x, 0.0 );
|
||||
float2 pix_co = co * tex_size - float2( 0.5, 0.0 );
|
||||
float2 tex_co = ( floor( pix_co ) + float2( 0.5, 0.001 ) ) / tex_size;
|
||||
float2 dist = frac( pix_co );
|
||||
float4 coef = PI * float4( dist.x + 1.0, dist.x, dist.x - 1.0, dist.x - 2.0 );
|
||||
|
||||
coef = FIX( coef );
|
||||
coef = 2.0 * sin( coef ) * sin( coef / 2.0 ) / ( coef * coef );
|
||||
coef /= dot( coef, _float4( 1.0 ) );
|
||||
|
||||
#if 0
|
||||
float4 col1 = float4( TEX2D( tex_co ), 1.0 );
|
||||
float4 col2 = float4( TEX2D( tex_co + dx ), 1.0 );
|
||||
|
||||
return ( mul( float4x4( col1, col1, col2, col2 ), coef ) ).rgb;
|
||||
#else
|
||||
float3 col = filter_lanczos2( coef, get_color_matrix( tex_co, _float2( 0 ) ) );
|
||||
float3 col2 = filter_lanczos2( coef, get_color_matrix( tex_co, dx ) );
|
||||
|
||||
//col = lerp( col, col2, curve_distance( dist.y, params.SHARPNESS_V ) );
|
||||
col = lerp( col, col2, sharp );
|
||||
|
||||
return col;
|
||||
#endif
|
||||
}
|
||||
|
||||
float3 get_scanline_weight( float x, float3 col, Params params )
|
||||
{
|
||||
float3 beam = lerp( _float3( params.SCANLINE_SIZE_MIN ), _float3( params.SCANLINE_SIZE_MAX ), pow( col, _float3( 1.0 / params.SCANLINE_SHAPE ) ) );
|
||||
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;
|
||||
}
|
||||
|
||||
float3 get_mask_weight( float x, Params params )
|
||||
{
|
||||
float i = mod( floor( x * params.outputSize.x * params.sourceSize.x / ( params.sourceSize.x * params.MASK_SIZE ) ), params.MASK_COLORS );
|
||||
|
||||
if( i == 0.0 )
|
||||
{
|
||||
return lerp( float3( 1.0, 0.0, 1.0 ), float3( 1.0, 0.0, 0.0 ), params.MASK_COLORS - 2.0 );
|
||||
}
|
||||
else if( i == 1.0 )
|
||||
{
|
||||
return float3( 0.0, 1.0, 0.0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
return float3( 0.0, 0.0, 1.0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
float2 curve( float2 uv, float curvature )
|
||||
{
|
||||
uv = ( uv - 0.5 ) * curvature;
|
||||
|
@ -125,137 +224,58 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
{
|
||||
// revised version from RetroArch
|
||||
|
||||
struct Params
|
||||
{
|
||||
float BRIGHT_BOOST;
|
||||
float DILATION;
|
||||
float GAMMA_INPUT;
|
||||
float GAMMA_OUTPUT;
|
||||
float MASK_SIZE;
|
||||
float MASK_STAGGER;
|
||||
float MASK_STRENGTH;
|
||||
float MASK_DOT_HEIGHT;
|
||||
float MASK_DOT_WIDTH;
|
||||
float SCANLINE_CUTOFF;
|
||||
float SCANLINE_BEAM_WIDTH_MAX;
|
||||
float SCANLINE_BEAM_WIDTH_MIN;
|
||||
float SCANLINE_BRIGHT_MAX;
|
||||
float SCANLINE_BRIGHT_MIN;
|
||||
float SCANLINE_STRENGTH;
|
||||
float SHARPNESS_H;
|
||||
float SHARPNESS_V;
|
||||
};
|
||||
|
||||
Params params;
|
||||
params.BRIGHT_BOOST = 1.2;
|
||||
params.DILATION = 1.0;
|
||||
params.GAMMA_INPUT = 2.0;
|
||||
params.GAMMA_OUTPUT = 1.8;
|
||||
params.FrameCount = int( rpJitterTexOffset.w );
|
||||
params.SHARPNESS_IMAGE = 1.0;
|
||||
params.SHARPNESS_EDGES = 3.0;
|
||||
params.GLOW_WIDTH = 0.5;
|
||||
params.GLOW_HEIGHT = 0.5;
|
||||
params.GLOW_HALATION = 0.1;
|
||||
params.GLOW_DIFFUSION = 0.05;
|
||||
params.MASK_COLORS = 2.0;
|
||||
params.MASK_STRENGTH = 0.3;
|
||||
params.MASK_SIZE = 1.0;
|
||||
params.MASK_STAGGER = 0.0;
|
||||
params.MASK_STRENGTH = 0.8;
|
||||
params.MASK_DOT_HEIGHT = 1.0;
|
||||
params.MASK_DOT_WIDTH = 1.0;
|
||||
params.SCANLINE_CUTOFF = 400.0;
|
||||
params.SCANLINE_BEAM_WIDTH_MAX = 1.5;
|
||||
params.SCANLINE_BEAM_WIDTH_MIN = 1.5;
|
||||
params.SCANLINE_BRIGHT_MAX = 0.65;
|
||||
params.SCANLINE_BRIGHT_MIN = 0.35;
|
||||
params.SCANLINE_STRENGTH = 1.0;
|
||||
params.SHARPNESS_H = 0.5;
|
||||
params.SHARPNESS_V = 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.GAMMA_INPUT = 2.4;
|
||||
params.GAMMA_OUTPUT = 2.4;
|
||||
params.BRIGHTNESS = 1.5;
|
||||
|
||||
float4 outputSize;
|
||||
outputSize.xy = rpWindowCoord.zw;
|
||||
outputSize.zw = float2( 1.0, 1.0 ) / rpWindowCoord.zw;
|
||||
|
||||
#if 1
|
||||
float4 sourceSize = outputSize;
|
||||
#else
|
||||
float4 sourceSize;
|
||||
sourceSize.xy = rpWindowCoord.zw / float2( 4, 4.4 ); //RESOLUTION_DIVISOR;
|
||||
sourceSize.zw = float2( 1.0, 1.0 ) / sourceSize.xy;
|
||||
#endif
|
||||
|
||||
float2 vTexCoord = fragment.texcoord0.xy;
|
||||
params.sourceSize = sourceSize;
|
||||
params.outputSize = outputSize;
|
||||
|
||||
#if 0
|
||||
if( rpWindowCoord.x > 0.0 )
|
||||
float scale = floor( outputSize.y * sourceSize.w );
|
||||
float offset = 1.0 / scale * 0.5;
|
||||
|
||||
if( bool( mod( scale, 2.0 ) ) )
|
||||
{
|
||||
vTexCoord = curve( vTexCoord, 2.0 );
|
||||
}
|
||||
#endif
|
||||
|
||||
float2 dx = float2( sourceSize.z, 0.0 );
|
||||
float2 dy = float2( 0.0, sourceSize.w );
|
||||
float2 pix_co = vTexCoord * sourceSize.xy - float2( 0.5, 0.5 );
|
||||
float2 tex_co = ( floor( pix_co ) + float2( 0.5, 0.5 ) ) * sourceSize.zw;
|
||||
float2 dist = frac( pix_co );
|
||||
float curve_x;
|
||||
float3 col, col2;
|
||||
|
||||
#if ENABLE_LANCZOS
|
||||
curve_x = curve_distance( dist.x, params.SHARPNESS_H * params.SHARPNESS_H );
|
||||
|
||||
float4 coeffs = PI * float4( 1.0 + curve_x, curve_x, 1.0 - curve_x, 2.0 - curve_x );
|
||||
|
||||
coeffs = FIX( coeffs );
|
||||
coeffs = 2.0 * sin( coeffs ) * sin( coeffs * 0.5 ) / ( coeffs * coeffs );
|
||||
coeffs /= dot( coeffs, _float4( 1.0 ) );
|
||||
|
||||
col = filter_lanczos( coeffs, get_color_matrix( tex_co, dx ) );
|
||||
col2 = filter_lanczos( coeffs, get_color_matrix( tex_co + dy, dx ) );
|
||||
#else
|
||||
curve_x = curve_distance( dist.x, params.SHARPNESS_H );
|
||||
|
||||
col = lerp( TEX2D( tex_co ).rgb, TEX2D( tex_co + dx ).rgb, curve_x );
|
||||
col2 = lerp( TEX2D( tex_co + dy ).rgb, TEX2D( tex_co + dx + dy ).rgb, curve_x );
|
||||
#endif
|
||||
|
||||
col = lerp( col, col2, curve_distance( dist.y, params.SHARPNESS_V ) );
|
||||
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;
|
||||
float scan_bright = clamp( bright, params.SCANLINE_BRIGHT_MIN, params.SCANLINE_BRIGHT_MAX );
|
||||
float scan_beam = clamp( bright * params.SCANLINE_BEAM_WIDTH_MAX, params.SCANLINE_BEAM_WIDTH_MIN, params.SCANLINE_BEAM_WIDTH_MAX );
|
||||
float scan_weight = 1.0 - pow( cos( vTexCoord.y * 2.0 * PI * sourceSize.y / RESOLUTION_DIVISOR ) * 0.5 + 0.5, scan_beam ) * params.SCANLINE_STRENGTH;
|
||||
|
||||
float mask = 1.0 - params.MASK_STRENGTH;
|
||||
float2 mod_fac = floor( vTexCoord * outputSize.xy * sourceSize.xy / ( sourceSize.xy * float2( params.MASK_SIZE, params.MASK_DOT_HEIGHT * params.MASK_SIZE ) ) );
|
||||
int dot_no = int( mod( ( mod_fac.x + mod( mod_fac.y, 2.0 ) * params.MASK_STAGGER ) / params.MASK_DOT_WIDTH, 3.0 ) );
|
||||
float3 mask_weight;
|
||||
|
||||
if( dot_no == 0 )
|
||||
{
|
||||
mask_weight = float3( 1.0, mask, mask );
|
||||
}
|
||||
else if( dot_no == 1 )
|
||||
{
|
||||
mask_weight = float3( mask, 1.0, mask );
|
||||
}
|
||||
else
|
||||
{
|
||||
mask_weight = float3( mask, mask, 1.0 );
|
||||
offset = 0.0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if( sourceSize.y >= params.SCANLINE_CUTOFF )
|
||||
{
|
||||
scan_weight = 1.0;
|
||||
}
|
||||
#endif
|
||||
float2 vTexCoord = abs( fragment.texcoord0.xy );
|
||||
|
||||
col2 = col.rgb;
|
||||
col *= _float3( scan_weight );
|
||||
col = lerp( col, col2, scan_bright );
|
||||
col *= mask_weight;
|
||||
col = pow( col, _float3( 1.0 / params.GAMMA_OUTPUT ) );
|
||||
float2 co = ( vTexCoord * sourceSize.xy - float2( 0.0, offset * params.SCANLINE_OFFSET ) ) * sourceSize.zw;
|
||||
float3 col_glow = filter_gaussian( co, sourceSize.xy, params );
|
||||
float3 col_soft = filter_lanczos( co, sourceSize.xy, params.SHARPNESS_IMAGE );
|
||||
float3 col_sharp = filter_lanczos( co, sourceSize.xy, params.SHARPNESS_EDGES );
|
||||
float3 col = sqrt( col_sharp * col_soft );
|
||||
|
||||
//col = col2;
|
||||
//col = _float3( scan_weight );
|
||||
//col = float3( scan_bright, scan_beam, scan_weight );
|
||||
col *= get_scanline_weight( frac( co.y * sourceSize.y / RESOLUTION_DIVISOR ), col_soft, params );
|
||||
col_glow = saturate( col_glow - col );
|
||||
col += col_glow * col_glow * params.GLOW_HALATION;
|
||||
col = lerp( col, col * get_mask_weight( vTexCoord.x, params ) * params.MASK_COLORS, params.MASK_STRENGTH );
|
||||
col += col_glow * params.GLOW_DIFFUSION;
|
||||
col = pow( col * params.BRIGHTNESS, _float3( 1.0 / params.GAMMA_OUTPUT ) );
|
||||
|
||||
result.color = float4( col * params.BRIGHT_BOOST, 1.0 );
|
||||
//col = col_soft;
|
||||
|
||||
result.color = float4( col, 1.0 );
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ struct PS_OUT
|
|||
// Set to 0 to use linear filter and gain speed
|
||||
#define ENABLE_LANCZOS 1
|
||||
|
||||
#define RESOLUTION_DIVISOR 4.0
|
||||
#define RESOLUTION_DIVISOR 6.0
|
||||
|
||||
float4 dilate( float4 col )
|
||||
{
|
||||
|
|
|
@ -70,6 +70,8 @@ builtin/post/crt_newpixie.vs.hlsl -T vs
|
|||
builtin/post/crt_newpixie.ps.hlsl -T ps
|
||||
builtin/post/crt_easymode.vs.hlsl -T vs
|
||||
builtin/post/crt_easymode.ps.hlsl -T ps
|
||||
builtin/post/crt_aperture.vs.hlsl -T vs
|
||||
builtin/post/crt_aperture.ps.hlsl -T ps
|
||||
builtin/post/screen.vs.hlsl -T vs
|
||||
builtin/post/screen.ps.hlsl -T ps
|
||||
builtin/post/tonemap.vs.hlsl -T vs -D BRIGHTPASS={0,1} -D HDR_DEBUG={0,1}
|
||||
|
|
Loading…
Reference in a new issue