feat(renderer): add CRT shader filter with configurable effects

Add CRT (Cathode Ray Tube) shader implementation as scaling filter
options (CRT EasyMode and CRT Royale) in the Window Adapting Filter
dropdown. Provides classic TV effects including scanlines, phosphor
masks, curvature distortion, gamma correction, bloom, brightness, and
alpha transparency.

- Add CRTEasyMode and CRTRoyale to ScalingFilter enum
- Implement vulkan_crt_easymode.frag shader with single-pass effects
- Integrate CRT filter into WindowAdaptPass rendering pipeline
- Add configurable CRT parameters to settings with user-friendly labels
- Add UI translations for desktop and Android platforms
- Support CRT push constants in present pipeline

The CRT filter appears alongside other scaling filters like FSR and
FSR 2.0. CRT parameter settings are only active when a CRT filter
is selected.

Signed-off-by: Zephyron <zephyron@citron-emu.org>
This commit is contained in:
Zephyron
2026-01-01 18:18:05 +10:00
parent d8c1cad245
commit efef746299
12 changed files with 320 additions and 16 deletions

View File

@@ -1,5 +1,5 @@
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project
// SPDX-FileCopyrightText: Copyright 2026 citron Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
@@ -350,6 +350,71 @@ struct Values {
true,
true};
// CRT Shader Settings (only active when CRT filter is selected)
SwitchableSetting<float, true> crt_scanline_strength{linkage,
1.0f, // 100/100 = 1.0 (range 0-200, actual 0.0-2.0)
0.0f,
2.0f,
"crt_scanline_strength",
Category::Renderer,
Specialization::Scalar,
true,
true};
SwitchableSetting<float, true> crt_curvature{linkage,
0.0f,
0.0f,
1.0f,
"crt_curvature",
Category::Renderer,
Specialization::Scalar,
true,
true};
SwitchableSetting<float, true> crt_gamma{linkage,
1.0f, // 100 maps to 1.0 (range 1-300, actual 1.0-3.0)
1.0f,
3.0f,
"crt_gamma",
Category::Renderer,
Specialization::Scalar,
true,
true};
SwitchableSetting<float, true> crt_bloom{linkage,
0.33f, // 33/100 = 0.33 (range 0-100, actual 0.0-1.0)
0.0f,
1.0f,
"crt_bloom",
Category::Renderer,
Specialization::Scalar,
true,
true};
SwitchableSetting<int, true> crt_mask_type{linkage,
1, // Already correct
0,
2,
"crt_mask_type",
Category::Renderer,
Specialization::Scalar,
true,
true}; // 0=none, 1=aperture, 2=shadow
SwitchableSetting<float, true> crt_brightness{linkage,
1.0f, // Default brightness (1.0 = no change)
0.0f,
2.0f,
"crt_brightness",
Category::Renderer,
Specialization::Scalar,
true,
true};
SwitchableSetting<float, true> crt_alpha{linkage,
1.0f, // Default alpha (1.0 = fully opaque)
0.0f,
1.0f,
"crt_alpha",
Category::Renderer,
Specialization::Scalar,
true,
true};
SwitchableSetting<int, true> lanczos_quality{linkage,
3, // Default value

View File

@@ -1,5 +1,5 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project
// SPDX-FileCopyrightText: Copyright 2026 citron Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
@@ -673,7 +673,9 @@ enum class ScalingFilter : u32 {
Lanczos = 6,
Fsr = 7,
Fsr2 = 8,
MaxEnum = 9,
CRTEasyMode = 9,
CRTRoyale = 10,
MaxEnum = 11,
};
template <>
@@ -689,6 +691,8 @@ EnumMetadata<ScalingFilter>::Canonicalizations() {
{"Lanczos", ScalingFilter::Lanczos},
{"Fsr", ScalingFilter::Fsr},
{"Fsr2", ScalingFilter::Fsr2},
{"CRTEasyMode", ScalingFilter::CRTEasyMode},
{"CRTRoyale", ScalingFilter::CRTRoyale},
{"MaxEnum", ScalingFilter::MaxEnum},
};
}
@@ -876,6 +880,7 @@ inline u32 EnumMetadata<ExtendedDynamicState>::Index() {
return 26;
}
template <typename Type>
inline std::string CanonicalizeEnum(Type id) {
const auto group = EnumMetadata<Type>::Canonicalizations();