GS: Add fancy downsampling shaders.

This commit is contained in:
KrossX 2022-12-21 14:12:50 -03:00 committed by refractionpcsx2
parent 7fbc63b8e8
commit 32aa24f6fd
9 changed files with 188 additions and 9 deletions

View File

@ -395,4 +395,46 @@ PS_OUTPUT ps_filter_lottes(PS_INPUT input)
return output;
}
PS_OUTPUT ps_4x_rgss(PS_INPUT input)
{
PS_OUTPUT output;
float2 dxy = float2(ddx(input.t.x), ddy(input.t.y));
float3 color = 0;
float s = 1.0/8.0;
float l = 3.0/8.0;
color += sample_c(input.t + float2( s, l) * dxy).rgb;
color += sample_c(input.t + float2( l,-s) * dxy).rgb;
color += sample_c(input.t + float2(-s,-l) * dxy).rgb;
color += sample_c(input.t + float2(-l, s) * dxy).rgb;
output.c = float4(color * 0.25,1);
return output;
}
PS_OUTPUT ps_automagical_supersampling(PS_INPUT input)
{
PS_OUTPUT output;
float2 ratio = (u_source_size / u_target_size) * 0.5;
float2 steps = floor(ratio);
float3 col = sample_c(input.t).rgb;
float div = 1;
for (float y = 0; y < steps.y; y++)
{
for (float x = 0; x < steps.x; x++)
{
float2 offset = float2(x,y) - ratio * 0.5;
col += sample_c(input.t + offset * u_rcp_source_resolution * 2.0).rgb;
div++;
}
}
output.c = float4(col / div, 1);
return output;
}
#endif

View File

@ -54,6 +54,11 @@ vec4 sample_c()
return texture(TextureSampler, PSin_t);
}
vec4 sample_c(vec2 uv)
{
return texture(TextureSampler, uv);
}
vec4 ps_crt(uint i)
{
vec4 mask[4] = vec4[4](
@ -384,4 +389,44 @@ void ps_filter_lottes()
#endif
#ifdef ps_4x_rgss
void ps_4x_rgss()
{
vec2 dxy = vec2(dFdx(PSin_t.x), dFdy(PSin_t.y));
vec3 color = vec3(0);
float s = 1.0/8.0;
float l = 3.0/8.0;
color += sample_c(PSin_t + vec2( s, l) * dxy).rgb;
color += sample_c(PSin_t + vec2( l,-s) * dxy).rgb;
color += sample_c(PSin_t + vec2(-s,-l) * dxy).rgb;
color += sample_c(PSin_t + vec2(-l, s) * dxy).rgb;
SV_Target0 = vec4(color * 0.25,1);
}
#endif
#ifdef ps_automagical_supersampling
void ps_automagical_supersampling()
{
vec2 ratio = (u_source_size / u_target_size) * 0.5;
vec2 steps = floor(ratio);
vec3 col = sample_c(PSin_t).rgb;
float div = 1;
for (float y = 0; y < steps.y; y++)
{
for (float x = 0; x < steps.x; x++)
{
vec2 offset = vec2(x,y) - ratio * 0.5;
col += sample_c(PSin_t + offset * u_rcp_source_resolution * 2.0).rgb;
div++;
}
}
SV_Target0 = vec4(col / div, 1);
}
#endif
#endif

View File

@ -359,4 +359,44 @@ void ps_filter_lottes()
#endif
#ifdef ps_4x_rgss
void ps_4x_rgss()
{
vec2 dxy = vec2(dFdx(v_tex.x), dFdy(v_tex.y));
vec3 color = vec3(0);
float s = 1.0/8.0;
float l = 3.0/8.0;
color += sample_c(v_tex + vec2( s, l) * dxy).rgb;
color += sample_c(v_tex + vec2( l,-s) * dxy).rgb;
color += sample_c(v_tex + vec2(-s,-l) * dxy).rgb;
color += sample_c(v_tex + vec2(-l, s) * dxy).rgb;
o_col0 = vec4(color * 0.25,1);
}
#endif
#ifdef ps_automagical_supersampling
void ps_automagical_supersampling()
{
vec2 ratio = (u_source_size / u_target_size) * 0.5;
vec2 steps = floor(ratio);
vec3 col = sample_c(v_tex).rgb;
float div = 1;
for (float y = 0; y < steps.y; y++)
{
for (float x = 0; x < steps.x; x++)
{
vec2 offset = vec2(x,y) - ratio * 0.5;
col += sample_c(v_tex + offset * u_rcp_source_resolution * 2.0).rgb;
div++;
}
}
o_col0 = vec4(col / div, 1);
}
#endif
#endif

View File

@ -1479,6 +1479,16 @@
<string extracomment="Lottes = Timothy Lottes, the creator of the shader filter. Leave as-is. CRT= Cathode Ray Tube, an old type of television technology.">Lottes CRT</string>
</property>
</item>
<item>
<property name="text">
<string>4xRGSS downsampling (4x Rotated Grid SuperSampling)</string>
</property>
</item>
<item>
<property name="text">
<string>NxAGSS downsampling (Nx Automatic Grid SuperSampling)</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">

View File

@ -74,6 +74,8 @@ const char* shaderName(PresentShader value)
case PresentShader::TRIANGULAR_FILTER: return "ps_filter_triangular";
case PresentShader::COMPLEX_FILTER: return "ps_filter_complex";
case PresentShader::LOTTES_FILTER: return "ps_filter_lottes";
case PresentShader::SUPERSAMPLE_4xRGSS: return "ps_4x_rgss";
case PresentShader::SUPERSAMPLE_AUTO: return "ps_automagical_supersampling";
// clang-format on
default:
ASSERT(0);

View File

@ -131,6 +131,8 @@ enum class PresentShader
TRIANGULAR_FILTER,
COMPLEX_FILTER,
LOTTES_FILTER,
SUPERSAMPLE_4xRGSS,
SUPERSAMPLE_AUTO,
Count
};

View File

@ -44,10 +44,11 @@
#include <thread>
#include <mutex>
static constexpr std::array<PresentShader, 6> s_tv_shader_indices = {
static constexpr std::array<PresentShader, 8> s_tv_shader_indices = {
PresentShader::COPY, PresentShader::SCANLINE,
PresentShader::DIAGONAL_FILTER, PresentShader::TRIANGULAR_FILTER,
PresentShader::COMPLEX_FILTER, PresentShader::LOTTES_FILTER};
PresentShader::COMPLEX_FILTER, PresentShader::LOTTES_FILTER,
PresentShader::SUPERSAMPLE_4xRGSS, PresentShader::SUPERSAMPLE_AUTO};
static std::deque<std::thread> s_screenshot_threads;
static std::mutex s_screenshot_threads_mutex;

View File

@ -328,3 +328,40 @@ fragment float4 ps_filter_lottes(ConvertShaderData data [[stage_in]], ConvertPSR
{
return LottesCRTPass(res, uniform).Run(data.p);
}
fragment float4 ps_4x_rgss(ConvertShaderData data [[stage_in]], ConvertPSRes res)
{
float2 dxy = float2(dfdx(data.t.x), dfdy(data.t.y));
float3 color = 0;
float s = 1.0/8.0;
float l = 3.0/8.0;
color += res.sample(data.t + float2( s, l) * dxy).rgb;
color += res.sample(data.t + float2( l,-s) * dxy).rgb;
color += res.sample(data.t + float2(-s,-l) * dxy).rgb;
color += res.sample(data.t + float2(-l, s) * dxy).rgb;
return float4(color * 0.25,1);
}
fragment float4 ps_automagical_supersampling(ConvertShaderData data [[stage_in]], ConvertPSRes res,
constant GSMTLPresentPSUniform& cb [[buffer(GSMTLBufferIndexUniforms)]])
{
float2 ratio = (cb.source_size / cb.target_size) * 0.5;
float2 steps = floor(ratio);
float3 col = res.sample(data.t).rgb;
float div = 1;
for (float y = 0; y < steps.y; y++)
{
for (float x = 0; x < steps.x; x++)
{
float2 offset = float2(x,y) - ratio * 0.5;
col += res.sample(data.t + offset * cb.rcp_source_resolution * 2.0).rgb;
div++;
}
}
return float4(col / div, 1);
}

View File

@ -3349,7 +3349,7 @@ void FullscreenUI::DrawGraphicsSettingsPage()
1, 100, "%d", shadeboost_active);
static constexpr const char* s_tv_shaders[] = {
"None (Default)", "Scanline Filter", "Diagonal Filter", "Triangular Filter", "Wave Filter", "Lottes CRT"};
"None (Default)", "Scanline Filter", "Diagonal Filter", "Triangular Filter", "Wave Filter", "Lottes CRT", "4xRGSS", "NxAGSS"};
DrawIntListSetting(
bsi, "TV Shaders", "Selects post-processing TV shader.", "EmuCore/GS", "TVShader", 0, s_tv_shaders, std::size(s_tv_shaders));
}