FSR: Improve quality of Film Grain and Anti-Aliasing

- New implementation of Film Grain that doesn't suck, so we can turn it up a nod by default. Supports RGB noise and shaping the distribution curve to control noise modulation. The previous implementation was just a placeholder, it was very basic.
- Greatly increased Anti-Aliasing quality in default preset.
- Include license headers to make clear that all my contributions are released on the public domain under the terms of the Unlicense. Anyone can do whatever they want with this.
This commit is contained in:
Jonatas Esteves 2021-09-08 18:16:54 -03:00
parent dd9994482c
commit b0b12b6a64
4 changed files with 55 additions and 20 deletions

View file

@ -10,6 +10,8 @@ filter_linear1 = true
scale_type1 = source scale_type1 = source
scale1 = 1.0 scale1 = 1.0
parameters = "FSR_SHARPENING;FSR_FILMGRAIN" parameters = "FSR_SHARPENING;FSR_FILMGRAIN;FSR_GRAINCOLOR;FSR_GRAINPDF"
FSR_SHARPENING = 0.3 FSR_SHARPENING = 0.3
FSR_FILMGRAIN = 0.10 FSR_FILMGRAIN = 0.3
FSR_GRAINCOLOR = 1.0
FSR_GRAINPDF = 0.3

View file

@ -1,4 +1,5 @@
#version 450 #version 450
// SPDX-License-Identifier: Unlicense
#pragma name FSR_EASU #pragma name FSR_EASU
// FSR - [EASU] EDGE ADAPTIVE SPATIAL UPSAMPLING // FSR - [EASU] EDGE ADAPTIVE SPATIAL UPSAMPLING
@ -40,15 +41,9 @@ layout(set = 0, binding = 2) uniform sampler2D Source;
#define FSR_EASU_F 1 #define FSR_EASU_F 1
AU4 con0, con1, con2, con3; AU4 con0, con1, con2, con3;
AF4 FsrEasuRF(AF2 p) { AF4 FsrEasuRF(AF2 p) { return textureGather(Source, p, 0); }
return textureGather(Source, p, 0); AF4 FsrEasuGF(AF2 p) { return textureGather(Source, p, 1); }
} AF4 FsrEasuBF(AF2 p) { return textureGather(Source, p, 2); }
AF4 FsrEasuGF(AF2 p) {
return textureGather(Source, p, 1);
}
AF4 FsrEasuBF(AF2 p) {
return textureGather(Source, p, 2);
}
#include "ffx_fsr1.h" #include "ffx_fsr1.h"

View file

@ -1,4 +1,5 @@
#version 450 #version 450
// SPDX-License-Identifier: Unlicense
#pragma name FSR_RCAS #pragma name FSR_RCAS
// FSR - [RCAS] ROBUST CONTRAST ADAPTIVE SHARPENING // FSR - [RCAS] ROBUST CONTRAST ADAPTIVE SHARPENING
@ -8,7 +9,9 @@
// scale1 = 1.0 // scale1 = 1.0
#pragma parameter FSR_SHARPENING "FSR RCAS Sharpening Amount (Lower = Sharper)" 0.2 0.0 2.0 0.1 #pragma parameter FSR_SHARPENING "FSR RCAS Sharpening Amount (Lower = Sharper)" 0.2 0.0 2.0 0.1
#pragma parameter FSR_FILMGRAIN "FSR LFGA Film Grain Intensity" 0.10 0.0 1.0 0.02 #pragma parameter FSR_FILMGRAIN "FSR LFGA Film Grain Intensity" 0.3 0.0 2.0 0.02
#pragma parameter FSR_GRAINCOLOR "FSR LFGA Film Grain Color: Gray | RGB" 1.0 0.0 1.0 1.0
#pragma parameter FSR_GRAINPDF "FSR LFGA Grain PDF Curve (0.5 = Triangular, Lower = Gaussian)" 0.3 0.1 0.5 0.05
layout(push_constant) uniform Push { layout(push_constant) uniform Push {
vec4 SourceSize; vec4 SourceSize;
@ -17,6 +20,8 @@ layout(push_constant) uniform Push {
uint FrameCount; uint FrameCount;
float FSR_SHARPENING; float FSR_SHARPENING;
float FSR_FILMGRAIN; float FSR_FILMGRAIN;
float FSR_GRAINCOLOR;
float FSR_GRAINPDF;
} params; } params;
layout(std140, set = 0, binding = 0) uniform UBO { layout(std140, set = 0, binding = 0) uniform UBO {
@ -45,14 +50,31 @@ layout(set = 0, binding = 2) uniform sampler2D Source;
#define FSR_RCAS_F 1 #define FSR_RCAS_F 1
AU4 con0; AU4 con0;
AF4 FsrRcasLoadF(ASU2 p) { AF4 FsrRcasLoadF(ASU2 p) { return AF4(texelFetch(Source, p, 0)); }
return AF4(texelFetch(Source, ASU2(p), 0));
}
void FsrRcasInputF(inout AF1 r, inout AF1 g, inout AF1 b) {} void FsrRcasInputF(inout AF1 r, inout AF1 g, inout AF1 b) {}
#include "ffx_fsr1.h" #include "ffx_fsr1.h"
// prng: A simple but effective pseudo-random number generator [0;1[
float prng(vec2 uv, float time) {
return fract(sin(dot(uv + fract(time), vec2(12.9898, 78.233))) * 43758.5453);
}
// pdf: [-0.5;0.5[
// Removes noise modulation effect by reshaping the uniform/rectangular noise
// distribution (RPDF) into a Triangular (TPDF) or Gaussian Probability Density
// Function (GPDF).
// shape = 1.0: Rectangular
// shape = 0.5: Triangular
// shape < 0.5: Gaussian (0.2~0.4)
float pdf(float noise, float shape) {
float orig = noise * 2.0 - 1.0;
noise = pow(abs(orig), shape);
noise *= sign(orig);
noise -= sign(orig);
return noise * 0.5;
}
void main() { void main() {
FsrRcasCon(con0, params.FSR_SHARPENING); FsrRcasCon(con0, params.FSR_SHARPENING);
@ -62,8 +84,17 @@ void main() {
// FSR - [LFGA] LINEAR FILM GRAIN APPLICATOR // FSR - [LFGA] LINEAR FILM GRAIN APPLICATOR
if (params.FSR_FILMGRAIN > 0.0) { if (params.FSR_FILMGRAIN > 0.0) {
AF1 noise = fract(10000 * sin(((vTexCoord.x + vTexCoord.y * A_2PI) * params.FrameCount))); if (params.FSR_GRAINCOLOR == 0.0) {
FsrLfgaF(Gamma2Color, AF3_(noise - 0.5), params.FSR_FILMGRAIN); float noise = pdf(prng(vTexCoord, params.FrameCount * 0.11), params.FSR_GRAINPDF);
FsrLfgaF(Gamma2Color, vec3(noise), params.FSR_FILMGRAIN);
} else {
vec3 rgbNoise = vec3(
pdf(prng(vTexCoord, params.FrameCount * 0.11), params.FSR_GRAINPDF),
pdf(prng(vTexCoord, params.FrameCount * 0.13), params.FSR_GRAINPDF),
pdf(prng(vTexCoord, params.FrameCount * 0.17), params.FSR_GRAINPDF)
);
FsrLfgaF(Gamma2Color, rgbNoise, params.FSR_FILMGRAIN);
}
} }
FragColor = vec4(Gamma2Color, 1.0); FragColor = vec4(Gamma2Color, 1.0);

View file

@ -35,7 +35,14 @@ filter_linear5 = true
scale_type5 = source scale_type5 = source
scale5 = 1.0 scale5 = 1.0
parameters = "SMAA_EDT;FSR_SHARPENING;FSR_FILMGRAIN" parameters = "SMAA_EDT;SMAA_THRESHOLD;SMAA_MAX_SEARCH_STEPS;SMAA_MAX_SEARCH_STEPS_DIAG;SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR;SMAA_CORNER_ROUNDING;FSR_SHARPENING;FSR_FILMGRAIN;FSR_GRAINCOLOR;FSR_GRAINPDF"
SMAA_EDT = 1.0 SMAA_EDT = 1.0
SMAA_THRESHOLD = 0.05
SMAA_MAX_SEARCH_STEPS = 40
SMAA_MAX_SEARCH_STEPS_DIAG = 20
SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR = 2.5
SMAA_CORNER_ROUNDING = 50.0
FSR_SHARPENING = 0.1 FSR_SHARPENING = 0.1
FSR_FILMGRAIN = 0.12 FSR_FILMGRAIN = 0.3
FSR_GRAINCOLOR = 1.0
FSR_GRAINPDF = 0.3