TAA Phase 5: expose native TAA in the UI (Anti-Aliasing dropdown)

Adds AntiAliasing.Taa and a 'TAA' entry to Settings > Graphics > Anti-Aliasing,
so the native temporal AA is a normal user-selectable option alongside FXAA/SMAA
(it is a post-process effect, not a scaling filter). Selecting it instantiates
TemporalFilter as the active IPostProcessingEffect; applies live, no restart.
RYUJINX_TAA=1 still force-enables it as a dev override. On the OpenGL backend TAA
falls back to no AA (Vulkan-only feature). Validated in game via the UI.

Bakes the in-game-validated defaults so UI users get the tuned look with no env
vars: history blend 0.80, variance clamp 1.25 (RYUJINX_TAA_* still override).
This commit is contained in:
2026-06-28 21:41:25 -04:00
parent df3240c17f
commit caea82cbb4
5 changed files with 21 additions and 17 deletions
@@ -11,5 +11,6 @@ namespace Ryujinx.Common.Configuration
SmaaMedium,
SmaaHigh,
SmaaUltra,
Taa,
}
}
+1
View File
@@ -324,6 +324,7 @@ namespace Ryujinx.Graphics.OpenGL
_antiAliasing = new FxaaPostProcessingEffect(_renderer);
break;
case AntiAliasing.None:
case AntiAliasing.Taa: // TAA is a Vulkan-only effect; on the GL backend it falls back to no AA.
_antiAliasing?.Dispose();
_antiAliasing = null;
break;
@@ -20,10 +20,10 @@ namespace Ryujinx.Graphics.Vulkan.Effects
/// the dominant cost), then the field is bilinear-upscaled and scaled by N when the blend reprojects the
/// history. Motion estimation is self-contained (reuses the DLSS shaders) so TAA works with DLSS off.
///
/// Gated entirely on RYUJINX_TAA=1: when unset the present path never constructs or runs this, so the
/// default render is byte-identical. Tunables (no rebuild): RYUJINX_TAA_BLEND (history weight, default
/// 0.90), RYUJINX_TAA_MV_SIGN (reprojection direction, default +1), RYUJINX_TAA_CLAMP (variance-box
/// half-width in std-devs, default 1.0), RYUJINX_TAA_MV_DOWNSCALE (flow resolution divisor 1/2/4, default 2).
/// Selected from the UI as an Anti-Aliasing option (AntiAliasing.Taa); RYUJINX_TAA=1 also force-enables it
/// (dev override). Tunables (no rebuild): RYUJINX_TAA_BLEND (history weight, default 0.80), RYUJINX_TAA_MV_SIGN
/// (reprojection direction, default +1), RYUJINX_TAA_CLAMP (variance-box half-width in std-devs, default 1.25),
/// RYUJINX_TAA_MV_DOWNSCALE (flow resolution divisor 1/2/4, default 2).
/// </summary>
internal class TemporalFilter : IPostProcessingEffect
{
@@ -91,7 +91,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
return blend;
}
return 0.90f;
return 0.80f; // validated in-game default (sharp + steady); RYUJINX_TAA_BLEND overrides.
}
private static float ParseSign()
@@ -113,7 +113,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
return gamma;
}
return 1.0f;
return 1.25f; // validated in-game default (lets native texture detail through); RYUJINX_TAA_CLAMP overrides.
}
private static int ParseDownscale()
+11 -11
View File
@@ -37,7 +37,6 @@ namespace Ryujinx.Graphics.Vulkan
private bool _updateEffect;
private IPostProcessingEffect _effect;
private IScalingFilter _scalingFilter;
private Effects.TemporalFilter _taa;
private Dlss.DlssUpscaler _dlss;
private bool _isLinear;
private float _scalingFilterLevel;
@@ -395,14 +394,6 @@ namespace Ryujinx.Graphics.Vulkan
view = _effect.Run(view, cbs, _width, _height);
}
// Native temporal anti-aliasing (clean-room), gated on RYUJINX_TAA=1. Runs at render resolution
// before the spatial upscale/blit, like a post-processing effect. Phase 0 is a pass-through.
if (Effects.TemporalFilter.IsEnabled)
{
_taa ??= new Effects.TemporalFilter(_gd, _device);
view = _taa.Run(view, cbs, _width, _height);
}
int srcX0, srcX1, srcY0, srcY1;
if (crop.Left == 0 && crop.Right == 0)
@@ -615,12 +606,22 @@ namespace Ryujinx.Graphics.Vulkan
{
_updateEffect = false;
switch (_currentAntiAliasing)
// RYUJINX_TAA=1 forces the native temporal filter regardless of the UI selection (dev override).
AntiAliasing antiAliasing = Effects.TemporalFilter.IsEnabled ? AntiAliasing.Taa : _currentAntiAliasing;
switch (antiAliasing)
{
case AntiAliasing.Fxaa:
_effect?.Dispose();
_effect = new FxaaPostProcessingEffect(_gd, _device);
break;
case AntiAliasing.Taa:
if (_effect is not Effects.TemporalFilter)
{
_effect?.Dispose();
_effect = new Effects.TemporalFilter(_gd, _device);
}
break;
case AntiAliasing.None:
_effect?.Dispose();
_effect = null;
@@ -791,7 +792,6 @@ namespace Ryujinx.Graphics.Vulkan
_effect?.Dispose();
_scalingFilter?.Dispose();
_taa?.Dispose();
_dlss?.Dispose();
}
}
@@ -290,6 +290,8 @@
Content="{ext:Locale SmaaHigh}" />
<ComboBoxItem
Content="{ext:Locale SmaaUltra}" />
<ComboBoxItem
Content="TAA" />
</ComboBox>
</StackPanel>
</StackPanel>