aboutsummaryrefslogtreecommitdiff
path: root/dist/post_shaders
diff options
context:
space:
mode:
authorDjihads80 <mahboubijoujou111@gmail.com>2026-10-31 22:20:08 +0100
committerDjihads80 <mahboubijoujou111@gmail.com>2026-10-31 22:20:08 +0100
commit919368bec2bfbf8ee4162d6e386049cdf6651bd8 (patch)
tree82e85c384f172e23a3d1a91883aabff1f0a55c9c /dist/post_shaders
parentedc3b6bf9475eff8f59cfcee10e36c1e04c35bd1 (diff)
Added FSR 4 and AMD Boost
Diffstat (limited to 'dist/post_shaders')
-rw-r--r--dist/post_shaders/AMDBoost.fx246
1 files changed, 246 insertions, 0 deletions
diff --git a/dist/post_shaders/AMDBoost.fx b/dist/post_shaders/AMDBoost.fx
new file mode 100644
index 0000000000..af941c1550
--- /dev/null
+++ b/dist/post_shaders/AMDBoost.fx
@@ -0,0 +1,246 @@
+// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+// AMD Boost - Combined AMD FidelityFX enhancement suite
+// Implements FSR 1 EASU upscaling + RCAS sharpening + optional denoising
+
+texture BackBufferTex : COLOR;
+sampler BackBuffer { Texture = BackBufferTex; };
+
+uniform float ScaleFactor <
+ ui_type = "slider";
+ ui_label = "Scale Factor";
+ ui_tooltip = "Upscaling factor (1.0 = native, 1.5 = 1.5x, 2.0 = 2x). Higher values require more performance.";
+ ui_min = 1.0; ui_max = 4.0; ui_step = 0.1;
+> = 1.5;
+
+uniform float Sharpness <
+ ui_type = "slider";
+ ui_label = "Sharpness";
+ ui_tooltip = "RCAS sharpening strength. Higher values increase edge contrast.";
+ ui_min = 0.0; ui_max = 1.0; ui_step = 0.01;
+> = 0.5;
+
+uniform bool EnableDenoise <
+ ui_type = "checkbox";
+ ui_label = "Enable Denoising";
+ ui_tooltip = "Apply a light denoising pass before upscaling to reduce artifacts.";
+> = false;
+
+uniform float DenoiseStrength <
+ ui_type = "slider";
+ ui_label = "Denoise Strength";
+ ui_tooltip = "Strength of the denoising filter. Only applies when denoising is enabled.";
+ ui_min = 0.0; ui_max = 1.0; ui_step = 0.01;
+> = 0.3;
+
+uniform bool EnableUpscaling <
+ ui_type = "checkbox";
+ ui_label = "Enable Upscaling";
+ ui_tooltip = "Enable FSR 1 EASU upscaling. Disable for sharpening only.";
+> = true;
+
+#define FFX_FSR1_EASU_MAX_TAPS 5
+
+// EASU constants - packed into uniforms
+uniform float4 EASUCon0;
+uniform float4 EASUCon1;
+uniform float4 EASUCon2;
+uniform float4 EASUCon3;
+
+// RCAS constants
+uniform float4 RCASCon;
+
+// Compute input size from output size and scale factor
+float2 GetInputSize(float2 outputSize, float scale)
+{
+ return outputSize / scale;
+}
+
+// EASU: Edge-Adaptive Spatial Upsampling
+float4 EASU(float2 uv, float2 inputSize, float2 outputSize)
+{
+ float2 inputViewportInPixels = outputSize;
+ float2 outputSizeInPixels = outputSize;
+ float2 inputSizeInPixels = inputSize;
+
+ // Compute constants
+ float2 con0 = EASUCon0.xy;
+ float2 con1 = EASUCon1.xy;
+ float2 con2 = EASUCon2.xy;
+ float2 con3 = EASUCon3.xy;
+
+ // Sample positions
+ float2 uv_input = uv * con0 + con1;
+
+ // 5-tap sampling pattern
+ float2 offsets[5];
+ offsets[0] = float2(0.0, 0.0);
+ offsets[1] = float2(con2.x, con2.y);
+ offsets[2] = float2(-con2.x, con2.y);
+ offsets[3] = float2(con2.x, -con2.y);
+ offsets[4] = float2(-con2.x, -con2.y);
+
+ float4 samples[5];
+ for (int i = 0; i < 5; i++)
+ {
+ float2 sample_uv = uv_input + offsets[i] * con3.xy;
+ samples[i] = tex2D(BackBuffer, saturate(sample_uv));
+ }
+
+ // Compute gradients
+ float3 c = samples[0].rgb;
+ float3 n = samples[1].rgb;
+ float3 s = samples[2].rgb;
+ float3 e = samples[3].rgb;
+ float3 w = samples[4].rgb;
+
+ // Luminance weights
+ float3 luma_weights = float3(0.299, 0.587, 0.114);
+
+ float luma_c = dot(c, luma_weights);
+ float luma_n = dot(n, luma_weights);
+ float luma_s = dot(s, luma_weights);
+ float luma_e = dot(e, luma_weights);
+ float luma_w = dot(w, luma_weights);
+
+ // Gradient computation
+ float grad_ns = abs(luma_n - luma_s);
+ float grad_ew = abs(luma_e - luma_w);
+
+ // Direction
+ float2 dir = float2(grad_ew, grad_ns);
+ float dir_length = length(dir) + 1e-6;
+ dir /= dir_length;
+
+ // Weights
+ float len = length(dir * float2(grad_ew, grad_ns));
+ float weight = 1.0 / (len + 1e-6);
+
+ // Reconstruct
+ float3 result = c;
+ result += (n + s - 2.0 * c) * dir.y * weight;
+ result += (e + w - 2.0 * c) * dir.x * weight;
+
+ return float4(saturate(result), 1.0);
+}
+
+// RCAS: Radeon Contrast Adaptive Sharpening
+float4 RCAS(float2 uv, float2 inputSize, float2 outputSize)
+{
+ float2 texel = float2(1.0 / inputSize.x, 1.0 / inputSize.y);
+
+ float3 c = tex2D(BackBuffer, uv).rgb;
+ float3 n = tex2D(BackBuffer, uv + float2(0.0, -texel.y)).rgb;
+ float3 s = tex2D(BackBuffer, uv + float2(0.0, texel.y)).rgb;
+ float3 e = tex2D(BackBuffer, uv + float2(texel.x, 0.0)).rgb;
+ float3 w = tex2D(BackBuffer, uv + float2(-texel.x, 0.0)).rgb;
+
+ float3 luma_weights = float3(0.299, 0.587, 0.114);
+
+ float luma_c = dot(c, luma_weights);
+ float luma_n = dot(n, luma_weights);
+ float luma_s = dot(s, luma_weights);
+ float luma_e = dot(e, luma_weights);
+ float luma_w = dot(w, luma_weights);
+
+ float grad_n = abs(luma_n - luma_c);
+ float grad_s = abs(luma_s - luma_c);
+ float grad_e = abs(luma_e - luma_c);
+ float grad_w = abs(luma_w - luma_c);
+
+ float grad_ns = max(grad_n, grad_s);
+ float grad_ew = max(grad_e, grad_w);
+
+ float2 dir = float2(grad_ew, grad_ns);
+ float dir_len = length(dir) + 1e-6;
+ dir /= dir_len;
+
+ float sharpness = RCASCon.x;
+ float weight = sharpness * (1.0 - smoothstep(0.0, 0.5, dir_len));
+
+ float3 result = c;
+ result += (n + s - 2.0 * c) * dir.y * weight;
+ result += (e + w - 2.0 * c) * dir.x * weight;
+
+ return float4(saturate(result), 1.0);
+}
+
+// Simple denoise (bilateral-like)
+float4 Denoise(float2 uv, float2 inputSize)
+{
+ float2 texel = float2(1.0 / inputSize.x, 1.0 / inputSize.y);
+ float3 center = tex2D(BackBuffer, uv).rgb;
+
+ float3 sum = center;
+ float total_weight = 1.0;
+
+ float3 luma_weights = float3(0.299, 0.587, 0.114);
+ float center_luma = dot(center, luma_weights);
+
+ // 4-tap cross pattern
+ float2 offsets[4] = {
+ float2(-texel.x, 0.0),
+ float2(texel.x, 0.0),
+ float2(0.0, -texel.y),
+ float2(0.0, texel.y)
+ };
+
+ for (int i = 0; i < 4; i++)
+ {
+ float3 sample = tex2D(BackBuffer, uv + offsets[i]).rgb;
+ float sample_luma = dot(sample, luma_weights);
+ float diff = abs(sample_luma - center_luma);
+ float weight = exp(-diff * DenoiseStrength * 50.0);
+
+ sum += sample * weight;
+ total_weight += weight;
+ }
+
+ return float4(sum / total_weight, 1.0);
+}
+
+void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
+{
+ uv = float2(float(id & 2), float((id & 1) << 1));
+ pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
+}
+
+float4 PS_AMDBoost(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
+{
+ float2 outputSize = float2(BUFFER_WIDTH, BUFFER_HEIGHT);
+ float2 inputSize = GetInputSize(outputSize, ScaleFactor);
+
+ float4 color = tex2D(BackBuffer, uv);
+
+ // Apply denoising first if enabled
+ if (EnableDenoise)
+ {
+ color = Denoise(uv, outputSize);
+ }
+
+ // Apply upscaling if enabled
+ if (EnableUpscaling && ScaleFactor > 1.0)
+ {
+ color = EASU(uv, inputSize, outputSize);
+ }
+
+ // Apply RCAS sharpening
+ if (Sharpness > 0.0)
+ {
+ color = RCAS(uv, EnableUpscaling ? inputSize : outputSize, outputSize);
+ }
+
+ return color;
+}
+
+technique AMDBoost <
+ ui_label = "AMD Boost";
+ ui_tooltip = "AMD FidelityFX Boost: Combines FSR 1 upscaling (EASU), RCAS sharpening, and optional denoising for enhanced image quality.";
+>
+{
+ pass
+ {
+ VertexShader = VS_PostProcess;
+ PixelShader = PS_AMDBoost;
+ }
+}