mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-03-14 06:34:10 +00:00
Easymode CRT looks like the games on my TV in the 90s
This commit is contained in:
parent
885bf8d7c0
commit
e66754b7f3
9 changed files with 417 additions and 59 deletions
|
@ -1565,6 +1565,39 @@ void idRenderBackend::GetCurrentBindingLayout( int type )
|
|||
desc[1].bindings[1].resourceHandle = commonPasses.m_LinearWrapSampler;
|
||||
}
|
||||
}
|
||||
else if( type == BINDING_LAYOUT_POST_PROCESS_CRT )
|
||||
{
|
||||
if( desc[0].bindings.empty() )
|
||||
{
|
||||
desc[0].bindings =
|
||||
{
|
||||
nvrhi::BindingSetItem::ConstantBuffer( 0, paramCb, range ),
|
||||
nvrhi::BindingSetItem::Texture_SRV( 0, ( nvrhi::ITexture* )GetImageAt( 0 )->GetTextureID() ),
|
||||
nvrhi::BindingSetItem::Texture_SRV( 1, ( nvrhi::ITexture* )GetImageAt( 1 )->GetTextureID() )
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
desc[0].bindings[0].resourceHandle = paramCb;
|
||||
desc[0].bindings[0].range = range;
|
||||
desc[0].bindings[1].resourceHandle = ( nvrhi::ITexture* )GetImageAt( 0 )->GetTextureID();
|
||||
desc[0].bindings[2].resourceHandle = ( nvrhi::ITexture* )GetImageAt( 1 )->GetTextureID();
|
||||
}
|
||||
|
||||
if( desc[1].bindings.empty() )
|
||||
{
|
||||
desc[1].bindings =
|
||||
{
|
||||
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_PointClampSampler ),
|
||||
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearWrapSampler )
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
desc[1].bindings[0].resourceHandle = commonPasses.m_PointClampSampler;
|
||||
desc[1].bindings[1].resourceHandle = commonPasses.m_LinearWrapSampler;
|
||||
}
|
||||
}
|
||||
else if( type == BINDING_LAYOUT_NORMAL_CUBE )
|
||||
{
|
||||
if( desc[0].bindings.empty() )
|
||||
|
|
|
@ -6459,7 +6459,8 @@ void idRenderBackend::PostProcess( const void* data )
|
|||
|
||||
void idRenderBackend::CRTPostProcess()
|
||||
{
|
||||
#if 1
|
||||
#define CRT_QUARTER_RES 1
|
||||
|
||||
nvrhi::ObjectType commandObject = nvrhi::ObjectTypes::D3D12_GraphicsCommandList;
|
||||
if( deviceManager->GetGraphicsAPI() == nvrhi::GraphicsAPI::VULKAN )
|
||||
{
|
||||
|
@ -6484,15 +6485,35 @@ void idRenderBackend::CRTPostProcess()
|
|||
{
|
||||
OPTICK_GPU_EVENT( "Render_CRTPostFX" );
|
||||
|
||||
BlitParameters blitParms;
|
||||
blitParms.sourceTexture = ( nvrhi::ITexture* )globalImages->ldrImage->GetTextureID();
|
||||
blitParms.targetFramebuffer = globalFramebuffers.smaaBlendFBO->GetApiObject();
|
||||
#if CRT_QUARTER_RES
|
||||
if( r_useCRTPostFX.GetInteger() == 3 )
|
||||
{
|
||||
// downscale to retro resolution
|
||||
BlitParameters blitParms;
|
||||
blitParms.sourceTexture = ( nvrhi::ITexture* )globalImages->ldrImage->GetTextureID();
|
||||
blitParms.targetFramebuffer = globalFramebuffers.bloomRenderFBO[0]->GetApiObject();
|
||||
|
||||
blitParms.targetViewport = nvrhi::Viewport( renderSystem->GetWidth(), renderSystem->GetHeight() );
|
||||
commonPasses.BlitTexture( commandList, blitParms, &bindingCache );
|
||||
blitParms.targetViewport = nvrhi::Viewport( renderSystem->GetWidth() / 4, renderSystem->GetHeight() / 4 );
|
||||
commonPasses.BlitTexture( commandList, blitParms, &bindingCache );
|
||||
|
||||
GL_SelectTexture( 0 );
|
||||
globalImages->smaaBlendImage->Bind();
|
||||
GL_SelectTexture( 0 );
|
||||
globalImages->bloomRenderImage[0]->Bind();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
BlitParameters blitParms;
|
||||
blitParms.sourceTexture = ( nvrhi::ITexture* )globalImages->ldrImage->GetTextureID();
|
||||
blitParms.targetFramebuffer = globalFramebuffers.smaaBlendFBO->GetApiObject();
|
||||
|
||||
blitParms.targetViewport = nvrhi::Viewport( renderSystem->GetWidth(), renderSystem->GetHeight() );
|
||||
commonPasses.BlitTexture( commandList, blitParms, &bindingCache );
|
||||
|
||||
renderProgManager.BindShader_CrtEasyMode();
|
||||
|
||||
GL_SelectTexture( 0 );
|
||||
globalImages->smaaBlendImage->Bind();
|
||||
}
|
||||
|
||||
globalFramebuffers.ldrFBO->Bind();
|
||||
|
||||
|
@ -6509,9 +6530,30 @@ void idRenderBackend::CRTPostProcess()
|
|||
}
|
||||
else
|
||||
{
|
||||
BlitParameters blitParms;
|
||||
blitParms.sourceTexture = ( nvrhi::ITexture* )globalImages->ldrImage->GetTextureID();
|
||||
blitParms.targetFramebuffer = globalFramebuffers.smaaBlendFBO->GetApiObject();
|
||||
|
||||
blitParms.targetViewport = nvrhi::Viewport( renderSystem->GetWidth(), renderSystem->GetHeight() );
|
||||
commonPasses.BlitTexture( commandList, blitParms, &bindingCache );
|
||||
|
||||
renderProgManager.BindShader_CrtEasyMode();
|
||||
}
|
||||
|
||||
// screen power of two correction factor
|
||||
idVec4 sourceSizeParam;
|
||||
#if CRT_QUARTER_RES
|
||||
sourceSizeParam.x = renderSystem->GetWidth() / 4;
|
||||
sourceSizeParam.y = renderSystem->GetHeight() / 4;
|
||||
#else
|
||||
sourceSizeParam.x = screenWidth;
|
||||
sourceSizeParam.y = screenHeight;
|
||||
#endif
|
||||
sourceSizeParam.z = 1.0f / sourceSizeParam.x;
|
||||
sourceSizeParam.w = 1.0f / sourceSizeParam.y;
|
||||
|
||||
SetFragmentParm( RENDERPARM_SCREENCORRECTIONFACTOR, sourceSizeParam.ToFloatPtr() ); // rpScreenCorrectionFactor
|
||||
|
||||
float windowCoordParm[4];
|
||||
windowCoordParm[0] = r_crtCurvature.GetFloat();
|
||||
windowCoordParm[1] = r_crtVignette.GetFloat();
|
||||
|
@ -6536,6 +6578,15 @@ void idRenderBackend::CRTPostProcess()
|
|||
|
||||
SetFragmentParm( RENDERPARM_JITTERTEXOFFSET, jitterTexOffset ); // rpJitterTexOffset
|
||||
|
||||
// JINC2 interpolation settings
|
||||
idVec4 jincParms;
|
||||
jincParms.x = 0.44;
|
||||
jincParms.y = 0.82;
|
||||
jincParms.z = 0.5;
|
||||
jincParms.w = 0;
|
||||
|
||||
SetFragmentParm( RENDERPARM_DIFFUSEMODIFIER, jincParms.ToFloatPtr() );
|
||||
|
||||
// Draw
|
||||
DrawElementsWithCounters( &unitSquareSurface );
|
||||
}
|
||||
|
@ -6559,5 +6610,4 @@ void idRenderBackend::CRTPostProcess()
|
|||
|
||||
renderLog.CloseBlock();
|
||||
renderLog.CloseMainBlock();
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -823,6 +823,7 @@ enum bindingLayoutType_t
|
|||
BINDING_LAYOUT_POST_PROCESS_INGAME,
|
||||
BINDING_LAYOUT_POST_PROCESS_FINAL,
|
||||
BINDING_LAYOUT_POST_PROCESS_FINAL2,
|
||||
BINDING_LAYOUT_POST_PROCESS_CRT,
|
||||
|
||||
BINDING_LAYOUT_BLIT,
|
||||
BINDING_LAYOUT_DRAW_AO,
|
||||
|
|
|
@ -340,6 +340,7 @@ void idRenderProgManager::Init( nvrhi::IDevice* device )
|
|||
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 1 ) ); // _blueNoise
|
||||
|
||||
bindingLayouts[BINDING_LAYOUT_POST_PROCESS_FINAL] = { device->createBindingLayout( ppFxBindingLayout ), samplerTwoBindingLayout };
|
||||
bindingLayouts[BINDING_LAYOUT_POST_PROCESS_CRT] = { device->createBindingLayout( ppFxBindingLayout ), samplerTwoBindingLayout };
|
||||
|
||||
auto ppFxBindingLayout2 = nvrhi::BindingLayoutDesc()
|
||||
.setVisibility( nvrhi::ShaderType::All )
|
||||
|
@ -537,9 +538,9 @@ void idRenderProgManager::Init( nvrhi::IDevice* device )
|
|||
{ BUILTIN_POSTPROCESS_RETRO_NES, "builtin/post/retro_nes", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_POST_PROCESS_FINAL },
|
||||
{ BUILTIN_POSTPROCESS_RETRO_GENESIS, "builtin/post/retro_genesis", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_POST_PROCESS_FINAL },
|
||||
{ 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_MATTIAS, "builtin/post/crt_mattias", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_POST_PROCESS_CRT },
|
||||
{ BUILTIN_CRT_NUPIXIE, "builtin/post/crt_newpixie", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_POST_PROCESS_CRT },
|
||||
{ BUILTIN_CRT_EASYMODE, "builtin/post/crt_easymode", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_POST_PROCESS_FINAL }, // FINAL for linear filtering
|
||||
|
||||
{ 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 },
|
||||
|
|
|
@ -2474,7 +2474,7 @@ int idRenderSystemLocal::GetVirtualWidth() const
|
|||
// return SCREEN_WIDTH;
|
||||
//}
|
||||
// jmarshall end
|
||||
return glConfig.nativeScreenWidth;
|
||||
return glConfig.nativeScreenWidth / 2;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2490,7 +2490,7 @@ int idRenderSystemLocal::GetVirtualHeight() const
|
|||
// return SCREEN_HEIGHT;
|
||||
//}
|
||||
// jmarshall end
|
||||
return glConfig.nativeScreenHeight;
|
||||
return glConfig.nativeScreenHeight / 2;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
Texture2D t_CurrentRender : register( t0 VK_DESCRIPTOR_SET( 0 ) );
|
||||
Texture2D t_BlueNoise : register( t1 VK_DESCRIPTOR_SET( 0 ) );
|
||||
|
||||
SamplerState s_LinearClamp : register(s0 VK_DESCRIPTOR_SET( 1 ) );
|
||||
SamplerState s_NearestClamp : register(s0 VK_DESCRIPTOR_SET( 1 ) );
|
||||
SamplerState s_LinearWrap : register(s1 VK_DESCRIPTOR_SET( 1 ) ); // blue noise 256
|
||||
|
||||
|
||||
|
@ -51,7 +51,7 @@ struct PS_OUT
|
|||
};
|
||||
// *INDENT-ON*
|
||||
|
||||
#define TEX2D(c) dilate(t_CurrentRender.Sample( s_LinearClamp, c ).rgb)
|
||||
#define TEX2D(c) dilate(t_CurrentRender.Sample( s_NearestClamp, c ).rgb)
|
||||
#define FIX(c) max(abs(c), 1e-5)
|
||||
|
||||
// Set to 0 to use linear filter and gain speed
|
||||
|
@ -210,16 +210,6 @@ float3 get_mask_weight( float x, Params params )
|
|||
|
||||
|
||||
|
||||
float2 curve( float2 uv, float curvature )
|
||||
{
|
||||
uv = ( uv - 0.5 ) * curvature;
|
||||
uv *= 1.1;
|
||||
uv.x *= 1.0 + pow( ( abs( uv.y ) / 5.0 ), 2.0 );
|
||||
uv.y *= 1.0 + pow( ( abs( uv.x ) / 4.0 ), 2.0 );
|
||||
uv = ( uv / curvature ) + 0.5;
|
||||
uv = uv * 0.92 + 0.04;
|
||||
return uv;
|
||||
}
|
||||
|
||||
void main( PS_IN fragment, out PS_OUT result )
|
||||
{
|
||||
|
|
|
@ -62,10 +62,10 @@ struct PS_OUT
|
|||
|
||||
float4 dilate( float4 col )
|
||||
{
|
||||
#if 1
|
||||
#if 0
|
||||
// FIXME
|
||||
//float4 x = lerp( _float4( 1.0 ), col, params.DILATION );
|
||||
float4 x = lerp( _float4( 1.0 ), col, 1.0 );
|
||||
//float4 x = lerp( _float4( 1.0 ), col, 1.0 );
|
||||
return col * x;
|
||||
#else
|
||||
return col;
|
||||
|
@ -122,7 +122,290 @@ float2 curve( float2 uv, float curvature )
|
|||
return uv;
|
||||
}
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
|
||||
/*
|
||||
Bicubic Catmull-Rom 5-taps (Fast) - ported by Hyllian - 2024
|
||||
|
||||
Samples a texture with B-Spline filtering, using only 4 texture fetches instead of 16.
|
||||
See http://float3.ca/bicubic-filtering-in-fewer-taps/ for more details
|
||||
Source: https://www.shadertoy.com/view/styXDh
|
||||
http://www.profhua.com/Sub/Article/BicubicFiltering/BicubicFiltering.html
|
||||
|
||||
ATENTION: This code only work using LINEAR filter sampling set on Retroarch!
|
||||
|
||||
*/
|
||||
|
||||
float3 get_blurred_pixel( float2 vTexCoord, float4 sourceSize )
|
||||
{
|
||||
// We're going to sample a a 4x4 grid of texels surrounding the target UV coordinate. We'll do this by rounding
|
||||
// down the sample location to get the exact center of our "starting" texel. The starting texel will be at
|
||||
// location [1, 1] in the grid, where [0, 0] is the top left corner.
|
||||
float2 texSize = sourceSize.xy;// / RESOLUTION_DIVISOR;
|
||||
float2 invTexSize = 1.0 / texSize;
|
||||
float2 iTc = vTexCoord * texSize;
|
||||
|
||||
float2 tc = floor( iTc - _float2( 0.5 ) ) + _float2( 0.5 );
|
||||
|
||||
// Compute the fractional offset from our starting texel to our original sample location, which we'll
|
||||
// feed into the B-Spline function to get our filter weights.
|
||||
float2 f = iTc - tc;
|
||||
float2 f2 = f * f;
|
||||
float2 f3 = f2 * f;
|
||||
|
||||
float2 of = _float2( 1.0 ) - f;
|
||||
float2 of2 = of * of;
|
||||
float2 of3 = of2 * of;
|
||||
|
||||
float2 w0 = f2 - 0.5 * ( f3 + f );
|
||||
float2 w1 = 1.5 * f3 - 2.5 * f2 + _float2( 1.0 );
|
||||
float2 w3 = 0.5 * ( f3 - f2 );
|
||||
float2 w2 = _float2( 1.0 ) - w0 - w1 - w3;
|
||||
|
||||
float2 Weight[3];
|
||||
float2 Sample[3];
|
||||
|
||||
Weight[0] = w0;
|
||||
Weight[1] = w1 + w2;
|
||||
Weight[2] = w3;
|
||||
|
||||
Sample[0] = tc - _float2( 1.0 );
|
||||
Sample[1] = tc + w2 / Weight[1];
|
||||
Sample[2] = tc + _float2( 2.0 );
|
||||
|
||||
Sample[0] *= invTexSize;
|
||||
Sample[1] *= invTexSize;
|
||||
Sample[2] *= invTexSize;
|
||||
|
||||
float sampleWeight[5];
|
||||
sampleWeight[0] = Weight[1].x * Weight[0].y;
|
||||
sampleWeight[1] = Weight[0].x * Weight[1].y;
|
||||
sampleWeight[2] = Weight[1].x * Weight[1].y;
|
||||
sampleWeight[3] = Weight[2].x * Weight[1].y;
|
||||
sampleWeight[4] = Weight[1].x * Weight[2].y;
|
||||
|
||||
float3 Ct = t_CurrentRender.Sample( s_LinearClamp, float2( Sample[1].x, Sample[0].y ) ).rgb * sampleWeight[0];
|
||||
float3 Cl = t_CurrentRender.Sample( s_LinearClamp, float2( Sample[0].x, Sample[1].y ) ).rgb * sampleWeight[1];
|
||||
float3 Cc = t_CurrentRender.Sample( s_LinearClamp, float2( Sample[1].x, Sample[1].y ) ).rgb * sampleWeight[2];
|
||||
float3 Cr = t_CurrentRender.Sample( s_LinearClamp, float2( Sample[2].x, Sample[1].y ) ).rgb * sampleWeight[3];
|
||||
float3 Cb = t_CurrentRender.Sample( s_LinearClamp, float2( Sample[1].x, Sample[2].y ) ).rgb * sampleWeight[4];
|
||||
|
||||
float WeightMultiplier = 1.0 / ( sampleWeight[0] + sampleWeight[1] + sampleWeight[2] + sampleWeight[3] + sampleWeight[4] );
|
||||
|
||||
return float3( ( Ct + Cl + Cc + Cr + Cb ) * WeightMultiplier );
|
||||
}
|
||||
|
||||
#elif 1
|
||||
|
||||
/*
|
||||
Bicubic B-Spline 4-taps (Fast) - ported by Hyllian - 2024
|
||||
|
||||
The following code is licensed under the MIT license: https://gist.github.com/TheRealMJP/bc503b0b87b643d3505d41eab8b332ae
|
||||
|
||||
Samples a texture with B-Spline filtering, using only 4 texture fetches instead of 16.
|
||||
See http://float3.ca/bicubic-filtering-in-fewer-taps/ for more details
|
||||
Implementation: https://www.shadertoy.com/view/styXDh
|
||||
|
||||
ATENTION: This code only work using LINEAR filter sampling set on Retroarch!
|
||||
|
||||
*/
|
||||
|
||||
float3 get_blurred_pixel( float2 vTexCoord, float4 sourceSize )
|
||||
{
|
||||
// We're going to sample a a 4x4 grid of texels surrounding the target UV coordinate. We'll do this by rounding
|
||||
// down the sample location to get the exact center of our "starting" texel. The starting texel will be at
|
||||
// location [1, 1] in the grid, where [0, 0] is the top left corner.
|
||||
float2 texSize = sourceSize.xy;// / RESOLUTION_DIVISOR;
|
||||
float2 invTexSize = 1.0 / texSize;
|
||||
float2 iTc = vTexCoord * texSize;
|
||||
|
||||
float2 tc = floor( iTc - _float2( 0.5 ) ) + _float2( 0.5 );
|
||||
|
||||
// Compute the fractional offset from our starting texel to our original sample location, which we'll
|
||||
// feed into the B-Spline function to get our filter weights.
|
||||
float2 f = iTc - tc;
|
||||
float2 f2 = f * f;
|
||||
float2 f3 = f2 * f;
|
||||
|
||||
float2 of = _float2( 1.0 ) - f;
|
||||
float2 of2 = of * of;
|
||||
float2 of3 = of2 * of;
|
||||
|
||||
float2 w0 = of3 / 6.0 ;
|
||||
float2 w1 = ( _float2( 4.0 ) + 3.*f3 - 6.*f2 ) / 6.0;
|
||||
float2 w2 = ( _float2( 4.0 ) + 3.*of3 - 6.*of2 ) / 6.0;
|
||||
float2 w3 = f3 / 6.0;
|
||||
|
||||
float2 Weight[2];
|
||||
float2 Sample[2];
|
||||
|
||||
Weight[0] = w0 + w1;
|
||||
Weight[1] = w2 + w3;
|
||||
|
||||
Sample[0] = tc - ( _float2( 1.0 ) - w1 / Weight[0] );
|
||||
Sample[1] = tc + _float2( 1.0 ) + w3 / Weight[1];
|
||||
|
||||
Sample[0] *= invTexSize;
|
||||
Sample[1] *= invTexSize;
|
||||
|
||||
float sampleWeight[4];
|
||||
sampleWeight[0] = Weight[0].x * Weight[0].y;
|
||||
sampleWeight[1] = Weight[1].x * Weight[0].y;
|
||||
sampleWeight[2] = Weight[0].x * Weight[1].y;
|
||||
sampleWeight[3] = Weight[1].x * Weight[1].y;
|
||||
|
||||
float3 Ctl = t_CurrentRender.Sample( s_LinearClamp, float2( Sample[0].x, Sample[0].y ) ).rgb * sampleWeight[0];
|
||||
float3 Ctr = t_CurrentRender.Sample( s_LinearClamp, float2( Sample[1].x, Sample[0].y ) ).rgb * sampleWeight[1];
|
||||
float3 Cbl = t_CurrentRender.Sample( s_LinearClamp, float2( Sample[0].x, Sample[1].y ) ).rgb * sampleWeight[2];
|
||||
float3 Cbr = t_CurrentRender.Sample( s_LinearClamp, float2( Sample[1].x, Sample[1].y ) ).rgb * sampleWeight[3];
|
||||
|
||||
return float3( Ctl + Ctr + Cbl + Cbr );
|
||||
}
|
||||
|
||||
#elif 1
|
||||
|
||||
/*
|
||||
Hyllian's jinc windowed-jinc 2-lobe with anti-ringing Shader
|
||||
|
||||
Copyright (C) 2011-2014 Hyllian/Jararaca - sergiogdb@gmail.com
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
This is an approximation of Jinc(x)*Jinc(x*r1/r2) for x < 2.5,
|
||||
where r1 and r2 are the first two zeros of jinc function.
|
||||
For a jinc 2-lobe best approximation, use A=0.5 and B=0.825.
|
||||
*/
|
||||
|
||||
// A=0.5, B=0.825 is the best jinc approximation for x<2.5. if B=1.0, it's a lanczos filter.
|
||||
// Increase A to get more blur. Decrease it to get a sharper picture.
|
||||
// B = 0.825 to get rid of dithering. Increase B to get a fine sharpness, though dithering returns.
|
||||
|
||||
/*
|
||||
#pragma parameter JINC2_WINDOW_SINC "Window Sinc Param" 0.44 0.0 1.0 0.01
|
||||
#define JINC2_WINDOW_SINC params.JINC2_WINDOW_SINC
|
||||
#pragma parameter JINC2_SINC "Sinc Param" 0.82 0.0 1.0 0.01
|
||||
#define JINC2_SINC params.JINC2_SINC
|
||||
#pragma parameter JINC2_AR_STRENGTH "Anti-ringing Strength" 0.5 0.0 1.0 0.1
|
||||
#define JINC2_AR_STRENGTH params.JINC2_AR_STRENGTH
|
||||
*/
|
||||
|
||||
#define JINC2_WINDOW_SINC rpDiffuseModifier.x
|
||||
#define JINC2_SINC rpDiffuseModifier.y
|
||||
#define JINC2_AR_STRENGTH rpDiffuseModifier.z
|
||||
|
||||
|
||||
#define halfpi 1.5707963267948966192313216916398
|
||||
#define pi 3.1415926535897932384626433832795
|
||||
#define wa (JINC2_WINDOW_SINC*pi)
|
||||
#define wb (JINC2_SINC*pi)
|
||||
|
||||
// Calculates the distance between two points
|
||||
float d( float2 pt1, float2 pt2 )
|
||||
{
|
||||
float2 v = pt2 - pt1;
|
||||
return sqrt( dot( v, v ) );
|
||||
}
|
||||
|
||||
float3 min4( float3 a, float3 b, float3 c, float3 d )
|
||||
{
|
||||
return min( a, min( b, min( c, d ) ) );
|
||||
}
|
||||
|
||||
float3 max4( float3 a, float3 b, float3 c, float3 d )
|
||||
{
|
||||
return max( a, max( b, max( c, d ) ) );
|
||||
}
|
||||
|
||||
float4 resampler( float4 x )
|
||||
{
|
||||
float4 res;
|
||||
res.x = ( x.x == 0.0 ) ? wa * wb : sin( x.x * wa ) * sin( x.x * wb ) / ( x.x * x.x );
|
||||
res.y = ( x.y == 0.0 ) ? wa * wb : sin( x.y * wa ) * sin( x.y * wb ) / ( x.y * x.y );
|
||||
res.z = ( x.z == 0.0 ) ? wa * wb : sin( x.z * wa ) * sin( x.z * wb ) / ( x.z * x.z );
|
||||
res.w = ( x.w == 0.0 ) ? wa * wb : sin( x.w * wa ) * sin( x.w * wb ) / ( x.w * x.w );
|
||||
return res;
|
||||
}
|
||||
|
||||
float3 get_blurred_pixel( float2 vTexCoord, float4 sourceSize )
|
||||
{
|
||||
float3 color;
|
||||
float4x4 weights;
|
||||
|
||||
//sourceSize.xy /= RESOLUTION_DIVISOR;
|
||||
|
||||
float2 dx = float2( 4.0, 0.0 );
|
||||
float2 dy = float2( 0.0, 4.0 );
|
||||
|
||||
float2 pc = vTexCoord * ( sourceSize.xy ) * _float2( 1.0001 );
|
||||
|
||||
float2 tc = ( floor( pc - float2( 0.5, 0.5 ) ) + float2( 0.5, 0.5 ) );
|
||||
|
||||
weights[0] = resampler( float4( d( pc, tc - dx - dy ), d( pc, tc - dy ), d( pc, tc + dx - dy ), d( pc, tc + 2.0 * dx - dy ) ) );
|
||||
weights[1] = resampler( float4( d( pc, tc - dx ), d( pc, tc ), d( pc, tc + dx ), d( pc, tc + 2.0 * dx ) ) );
|
||||
weights[2] = resampler( float4( d( pc, tc - dx + dy ), d( pc, tc + dy ), d( pc, tc + dx + dy ), d( pc, tc + 2.0 * dx + dy ) ) );
|
||||
weights[3] = resampler( float4( d( pc, tc - dx + 2.0 * dy ), d( pc, tc + 2.0 * dy ), d( pc, tc + dx + 2.0 * dy ), d( pc, tc + 2.0 * dx + 2.0 * dy ) ) );
|
||||
|
||||
//sourceSize /= RESOLUTION_DIVISOR;
|
||||
dx = dx * sourceSize.zw;
|
||||
dy = dy * sourceSize.zw;
|
||||
tc = tc * sourceSize.zw;
|
||||
|
||||
// reading the texels
|
||||
|
||||
float3 c00 = t_CurrentRender.Sample( s_LinearClamp, tc - dx - dy ).xyz;
|
||||
float3 c10 = t_CurrentRender.Sample( s_LinearClamp, tc - dy ).xyz;
|
||||
float3 c20 = t_CurrentRender.Sample( s_LinearClamp, tc + dx - dy ).xyz;
|
||||
float3 c30 = t_CurrentRender.Sample( s_LinearClamp, tc + 2.0 * dx - dy ).xyz;
|
||||
float3 c01 = t_CurrentRender.Sample( s_LinearClamp, tc - dx ).xyz;
|
||||
float3 c11 = t_CurrentRender.Sample( s_LinearClamp, tc ).xyz;
|
||||
float3 c21 = t_CurrentRender.Sample( s_LinearClamp, tc + dx ).xyz;
|
||||
float3 c31 = t_CurrentRender.Sample( s_LinearClamp, tc + 2.0 * dx ).xyz;
|
||||
float3 c02 = t_CurrentRender.Sample( s_LinearClamp, tc - dx + dy ).xyz;
|
||||
float3 c12 = t_CurrentRender.Sample( s_LinearClamp, tc + dy ).xyz;
|
||||
float3 c22 = t_CurrentRender.Sample( s_LinearClamp, tc + dx + dy ).xyz;
|
||||
float3 c32 = t_CurrentRender.Sample( s_LinearClamp, tc + 2.0 * dx + dy ).xyz;
|
||||
float3 c03 = t_CurrentRender.Sample( s_LinearClamp, tc - dx + 2.0 * dy ).xyz;
|
||||
float3 c13 = t_CurrentRender.Sample( s_LinearClamp, tc + 2.0 * dy ).xyz;
|
||||
float3 c23 = t_CurrentRender.Sample( s_LinearClamp, tc + dx + 2.0 * dy ).xyz;
|
||||
float3 c33 = t_CurrentRender.Sample( s_LinearClamp, tc + 2.0 * dx + 2.0 * dy ).xyz;
|
||||
|
||||
// get min/max samples
|
||||
float3 min_sample = min4( c11, c21, c12, c22 );
|
||||
float3 max_sample = max4( c11, c21, c12, c22 );
|
||||
|
||||
color = mul( weights[0], ( float4x3( c00, c10, c20, c30 ) ) ).rgb;
|
||||
color += mul( weights[1], ( float4x3( c01, c11, c21, c31 ) ) ).rgb;
|
||||
color += mul( weights[2], ( float4x3( c02, c12, c22, c32 ) ) ).rgb;
|
||||
color += mul( weights[3], ( float4x3( c03, c13, c23, c33 ) ) ).rgb;
|
||||
|
||||
color = color / ( dot( mul( weights, _float4( 1.0 ) ), _float4( 1.0 ) ) );
|
||||
|
||||
// anti-ringing
|
||||
float3 aux = color;
|
||||
color = clamp( color, min_sample, max_sample );
|
||||
|
||||
color = lerp( aux, color, JINC2_AR_STRENGTH );
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
float3 rgb2yiq( float3 c )
|
||||
{
|
||||
return float3(
|
||||
|
@ -145,7 +428,7 @@ 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 ) );
|
||||
return float2( -( 0.1 + rad ), cos( rad ) );
|
||||
|
||||
}
|
||||
|
||||
|
@ -199,9 +482,7 @@ float3 blur( float2 uv, float f, float d )
|
|||
return float3( clr.xyz ) * b;
|
||||
}
|
||||
|
||||
|
||||
|
||||
float3 get_blurred_pixel( float2 uv )
|
||||
float3 get_blurred_pixel( float2 uv, float4 unused )
|
||||
{
|
||||
float d = 0.0;
|
||||
float s = 0.0;
|
||||
|
@ -232,6 +513,7 @@ float3 get_blurred_pixel( float2 uv )
|
|||
|
||||
return fragColor;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -242,7 +524,7 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
struct Params
|
||||
{
|
||||
float BRIGHT_BOOST;
|
||||
float DILATION;
|
||||
//float DILATION;
|
||||
float GAMMA_INPUT;
|
||||
float GAMMA_OUTPUT;
|
||||
float MASK_SIZE;
|
||||
|
@ -261,15 +543,15 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
};
|
||||
|
||||
Params params;
|
||||
params.BRIGHT_BOOST = 1.5;
|
||||
params.DILATION = 1.0;
|
||||
params.BRIGHT_BOOST = 1.2;
|
||||
//params.DILATION = 1.0;
|
||||
params.GAMMA_INPUT = 2.4;
|
||||
params.GAMMA_OUTPUT = 2.5;
|
||||
params.MASK_SIZE = 1.0;
|
||||
params.MASK_STAGGER = 0.0;
|
||||
params.MASK_STRENGTH = 0.4;
|
||||
params.MASK_STRENGTH = 0.8;
|
||||
params.MASK_STAGGER = 3.0;
|
||||
params.MASK_DOT_HEIGHT = 1.0;
|
||||
params.MASK_DOT_WIDTH = 1.0;
|
||||
params.MASK_DOT_WIDTH = 2.0;
|
||||
params.SCANLINE_CUTOFF = 400.0;
|
||||
params.SCANLINE_BEAM_WIDTH_MAX = 1.5;
|
||||
params.SCANLINE_BEAM_WIDTH_MIN = 1.5;
|
||||
|
@ -279,18 +561,11 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
params.SHARPNESS_H = 0.5;
|
||||
params.SHARPNESS_V = 1.0;
|
||||
|
||||
|
||||
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
|
||||
float4 sourceSize = rpScreenCorrectionFactor;
|
||||
|
||||
float2 vTexCoord = fragment.texcoord0.xy;
|
||||
|
||||
|
@ -322,7 +597,8 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
col2 = filter_lanczos( coeffs, get_color_matrix( tex_co + dy, dx ) );
|
||||
|
||||
#elif ENABLE_NTSC
|
||||
col = col2 = get_blurred_pixel( vTexCoord );
|
||||
//col = col2 = get_blurred_pixel( vTexCoord );
|
||||
col = col2 = get_blurred_pixel( vTexCoord, sourceSize );
|
||||
#else
|
||||
curve_x = curve_distance( dist.x, params.SHARPNESS_H );
|
||||
|
||||
|
@ -337,7 +613,7 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
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 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 ) ) );
|
||||
|
@ -364,6 +640,11 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
result.color = float4( col2, 1.0 );
|
||||
return;
|
||||
#endif
|
||||
|
||||
col2 = col.rgb;
|
||||
col *= _float3( scan_weight );
|
||||
col = lerp( col, col2, scan_bright );
|
||||
|
@ -375,4 +656,6 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
//col = float3( scan_bright, scan_beam, scan_weight );
|
||||
|
||||
result.color = float4( col * params.BRIGHT_BOOST, 1.0 );
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ SOFTWARE.
|
|||
Texture2D t_CurrentRender : register( t0 VK_DESCRIPTOR_SET( 0 ) );
|
||||
Texture2D t_BlueNoise : register( t1 VK_DESCRIPTOR_SET( 0 ) );
|
||||
|
||||
SamplerState s_LinearClamp : register(s0 VK_DESCRIPTOR_SET( 1 ) );
|
||||
SamplerState s_NearestClamp : register(s0 VK_DESCRIPTOR_SET( 1 ) );
|
||||
SamplerState s_LinearWrap : register(s1 VK_DESCRIPTOR_SET( 1 ) ); // blue noise 256
|
||||
|
||||
struct PS_IN
|
||||
|
@ -78,15 +78,15 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
float x = 0.0; //sin( 0.3 * iTime + uv.y * 21.0 ) * sin( 0.7 * iTime + uv.y * 29.0 ) * sin( 0.3 + 0.33 * iTime + uv.y * 31.0 ) * 0.0017;
|
||||
|
||||
float3 col;
|
||||
col.r = t_CurrentRender.Sample( s_LinearClamp, float2( x + uv.x + 0.001, uv.y + 0.001 ) ).x + 0.05;
|
||||
col.g = t_CurrentRender.Sample( s_LinearClamp, float2( x + uv.x + 0.000, uv.y - 0.002 ) ).y + 0.05;
|
||||
col.b = t_CurrentRender.Sample( s_LinearClamp, float2( x + uv.x - 0.002, uv.y + 0.000 ) ).z + 0.05;
|
||||
col.r = t_CurrentRender.Sample( s_NearestClamp, float2( x + uv.x + 0.001, uv.y + 0.001 ) ).x + 0.05;
|
||||
col.g = t_CurrentRender.Sample( s_NearestClamp, float2( x + uv.x + 0.000, uv.y - 0.002 ) ).y + 0.05;
|
||||
col.b = t_CurrentRender.Sample( s_NearestClamp, float2( x + uv.x - 0.002, uv.y + 0.000 ) ).z + 0.05;
|
||||
|
||||
/* Ghosting */
|
||||
#if 1
|
||||
col.r += 0.08 * t_CurrentRender.Sample( s_LinearClamp, 0.75 * float2( x + 0.025, -0.027 ) + float2( uv.x + 0.001, uv.y + 0.001 ) ).x;
|
||||
col.g += 0.05 * t_CurrentRender.Sample( s_LinearClamp, 0.75 * float2( x + -0.022, -0.02 ) + float2( uv.x + 0.000, uv.y - 0.002 ) ).y;
|
||||
col.b += 0.08 * t_CurrentRender.Sample( s_LinearClamp, 0.75 * float2( x + -0.02, -0.018 ) + float2( uv.x - 0.002, uv.y + 0.000 ) ).z;
|
||||
col.r += 0.08 * t_CurrentRender.Sample( s_NearestClamp, 0.75 * float2( x + 0.025, -0.027 ) + float2( uv.x + 0.001, uv.y + 0.001 ) ).x;
|
||||
col.g += 0.05 * t_CurrentRender.Sample( s_NearestClamp, 0.75 * float2( x + -0.022, -0.02 ) + float2( uv.x + 0.000, uv.y - 0.002 ) ).y;
|
||||
col.b += 0.08 * t_CurrentRender.Sample( s_NearestClamp, 0.75 * float2( x + -0.02, -0.018 ) + float2( uv.x - 0.002, uv.y + 0.000 ) ).z;
|
||||
#endif
|
||||
|
||||
/* Level adjustment (curves) */
|
||||
|
|
|
@ -34,7 +34,7 @@ SOFTWARE.
|
|||
Texture2D t_CurrentRender : register( t0 VK_DESCRIPTOR_SET( 0 ) );
|
||||
Texture2D t_BlueNoise : register( t1 VK_DESCRIPTOR_SET( 0 ) );
|
||||
|
||||
SamplerState s_LinearClamp : register(s0 VK_DESCRIPTOR_SET( 1 ) );
|
||||
SamplerState s_NearestClamp : register(s0 VK_DESCRIPTOR_SET( 1 ) );
|
||||
SamplerState s_LinearWrap : register(s1 VK_DESCRIPTOR_SET( 1 ) ); // blue noise 256
|
||||
|
||||
struct PS_IN
|
||||
|
@ -54,10 +54,10 @@ float3 tsample( Texture2D tex, float2 tc, float offs, float2 resolution )
|
|||
{
|
||||
#if 1
|
||||
// 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 ) );
|
||||
float3 s = pow( abs( tex.Sample( s_NearestClamp, float2( tc.x, tc.y ) ).rgb ), _float3( 2.2 ) );
|
||||
return s * _float3( 1.25 );
|
||||
#else
|
||||
float3 s = tex.Sample( s_LinearClamp, float2( tc.x, tc.y ) ).rgb;
|
||||
float3 s = tex.Sample( s_NearestClamp, float2( tc.x, tc.y ) ).rgb;
|
||||
return s;
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue