From 6440a011bc5a2611aa6f209c89aa085d902c1a2a Mon Sep 17 00:00:00 2001 From: Asmodean- Date: Wed, 4 Feb 2015 08:42:20 +0000 Subject: [PATCH 1/5] post-processing updates --- bin/shaders/GSdx.fx | 98 ++++++++++++++++---------------- bin/shaders/GSdx_FX_Settings.ini | 7 +-- 2 files changed, 51 insertions(+), 54 deletions(-) diff --git a/bin/shaders/GSdx.fx b/bin/shaders/GSdx.fx index 21ea83ca7e..818f73448b 100644 --- a/bin/shaders/GSdx.fx +++ b/bin/shaders/GSdx.fx @@ -112,6 +112,13 @@ float RGBLuminance(float3 color) return dot(color.rgb, lumCoeff); } +float AvgLuminance(float3 color) +{ + return sqrt((color.x * color.x * lumCoeff.x) + + (color.y * color.y * lumCoeff.y) + + (color.z * color.z * lumCoeff.z)); +} + float4 sample_tex(SamplerState texSample, float2 t) { #if (GLSL == 1) @@ -208,7 +215,7 @@ struct FxaaTex { SamplerState smpl; Texture2D tex; }; float FxaaLuma(float4 rgba) { - rgba.w = RGBLuminance(rgba.xyz); + rgba.w = AvgLuminance(rgba.xyz); return rgba.w; } @@ -222,7 +229,7 @@ float4 FxaaPixelShader(float2 pos, FxaaTex tex, float2 fxaaRcpFrame, float fxaaS float4 rgbyM = FxaaTexTop(tex, posM); float4 luma4A = FxaaTexAlpha4(tex, posM); float4 luma4B = FxaaTexOffAlpha4(tex, posM, int2(-1, -1)); - rgbyM.w = RGBLuminance(rgbyM.xyz); + rgbyM.w = AvgLuminance(rgbyM.xyz); #define lumaM rgbyM.w #define lumaE luma4A.z @@ -234,7 +241,7 @@ float4 FxaaPixelShader(float2 pos, FxaaTex tex, float2 fxaaRcpFrame, float fxaaS #else float4 rgbyM = FxaaTexTop(tex, posM); - rgbyM.w = RGBLuminance(rgbyM.xyz); + rgbyM.w = AvgLuminance(rgbyM.xyz); #define lumaM rgbyM.w float lumaS = FxaaLuma(FxaaTexOff(tex, posM, int2( 0, 1), fxaaRcpFrame.xy)); @@ -937,10 +944,10 @@ float3 LinearToRGBGamma(in float3 color, in float gamma) float4 GammaPass(float4 color, float2 texcoord) { - const float GammaConst = 2.233; + static const float GammaConst = 2.233; color.rgb = RGBGammaToLinear(color.rgb, GammaConst); color.rgb = LinearToRGBGamma(color.rgb, float(Gamma)); - color.a = RGBLuminance(color.rgb); + color.a = AvgLuminance(color.rgb); return color; } @@ -998,7 +1005,7 @@ float4 TexSharpenPass(float4 color, float2 texcoord) sharpenLuma = clamp(sharpenLuma, -float(SharpenClamp), float(SharpenClamp)); color.rgb = color.rgb + sharpenLuma; - color.a = RGBLuminance(color.rgb); + color.a = AvgLuminance(color.rgb); #if (DebugSharpen == 1) color = saturate(0.5f + (sharpenLuma * 4)).rrrr; @@ -1016,9 +1023,9 @@ float4 TexSharpenPass(float4 color, float2 texcoord) float4 VibrancePass(float4 color, float2 texcoord) { #if (GLSL == 1) - float3 luma = float3(RGBLuminance(color.rgb)); + float3 luma = float3(AvgLuminance(color.rgb)); #else - float luma = RGBLuminance(color.rgb); + float luma = AvgLuminance(color.rgb); #endif float colorMax = max(color.r, max(color.g, color.b)); @@ -1027,7 +1034,7 @@ float4 VibrancePass(float4 color, float2 texcoord) float colorSaturation = colorMax - colorMin; color.rgb = lerp(luma, color.rgb, (1.0 + (Vibrance * (1.0 - (sign(Vibrance) * colorSaturation))))); - color.a = RGBLuminance(color.rgb); + color.a = AvgLuminance(color.rgb); return saturate(color); //Debug: return colorSaturation.xxxx; } @@ -1050,15 +1057,14 @@ float3 BlendScreen(in float3 color, in float3 bloom) float3 BlendLuma(in float3 color, in float3 bloom) { - return lerp((color * bloom), (1.0 - ((1.0 - color) * (1.0 - bloom))), RGBLuminance(color + bloom)); + float lumavg = AvgLuminance(color + bloom); + return lerp((color * bloom), (1.0 - ((1.0 - color) * (1.0 - bloom))), lumavg); } float3 BlendGlow(in float3 color, in float3 bloom) { - float3 glow = smoothstep(0.0, 1.0, color); - glow = lerp((color + bloom) - (color * bloom), (bloom + bloom) - (bloom * bloom), glow); - - return glow; + float glow = smoothstep(0.0, 1.0, AvgLuminance(color.rgb)); + return lerp((color + bloom) - (color * bloom), (bloom + bloom) - (bloom * bloom), glow); } float3 BlendOverlay(in float3 color, in float3 bloom) @@ -1069,11 +1075,6 @@ float3 BlendOverlay(in float3 color, in float3 bloom) return overlay; } -float4 BrightPassFilter(in float4 color) -{ - return float4(color.rgb * pow(abs(max(color.r, max(color.g, color.b))), float(BloomCutoff)), color.a); -} - float4 PyramidFilter(in SamplerState tex, in float2 texcoord, in float2 width) { float4 color = sample_tex(tex, texcoord + float2(0.5, 0.5) * width); @@ -1103,7 +1104,6 @@ float4 BloomPass(float4 color, float2 texcoord) float defocus = 1.25; float anflare = 4.00; - color = BrightPassFilter(color); float4 bloom = PyramidFilter(TextureSampler, texcoord, invDefocus * defocus); float2 dx = float2(invDefocus.x * float(BloomWidth), 0.0); @@ -1147,8 +1147,8 @@ float4 BloomPass(float4 color, float2 texcoord) bloom.rgb = BloomType(bloom.rgb, bloomBlend.rgb); bloom.rgb = BloomCorrection(bloom.rgb); - color.a = RGBLuminance(color.rgb); - bloom.a = RGBLuminance(bloom.rgb); + color.a = AvgLuminance(color.rgb); + bloom.a = AvgLuminance(bloom.rgb); bloom.a *= anflare; color = lerp(color, bloom, float(BloomStrength)); @@ -1160,12 +1160,12 @@ float4 BloomPass(float4 color, float2 texcoord) [COLOR CORRECTION/TONE MAPPING CODE SECTION] ------------------------------------------------------------------------------*/ -float3 ScaleLuma(in float3 L) +float4 ScaleBlk(in float4 color) { - const float W = 1.00; // Linear White Point Value - const float K = 1.12; // Scale - - return (1.0 + K * L / (W * W)) * L / (L + K); + color = float4(color.rgb * pow(abs(max(color.r, + max(color.g, color.b))), float(BlackLevels)), color.a); + + return color; } float3 FilmicTonemap(in float3 color) @@ -1173,7 +1173,7 @@ float3 FilmicTonemap(in float3 color) float3 Q = color.xyz; float A = 0.10; - float B = float(BlackLevels); + float B = 0.30; float C = 0.10; float D = float(ToneAmount); float E = 0.02; @@ -1201,10 +1201,9 @@ float3 CrossShift(in float3 color) colMood.g = float(GreenShift) * CrossMatrix[1].x + CrossMatrix[1].y; colMood.b = float(BlueShift) * CrossMatrix[2].x + CrossMatrix[2].y; - float fLum = RGBLuminance(color.rgb); + float fLum = AvgLuminance(color.rgb); #if (GLSL == 1) - // Is HLSL float3(x) equivalent to float3(x,x,x) ? (Yes) colMood = lerp(float3(0.0), colMood, saturate(fLum * 2.0)); colMood = lerp(colMood, float3(1.0), saturate(fLum - 0.5) * 2.0); #else @@ -1231,10 +1230,10 @@ float3 ColorCorrection(float3 color) float4 TonemapPass(float4 color, float2 texcoord) { - const float delta = 0.001f; - const float wpoint = pow(1.002f, 2.0f); + const float delta = 0.001; + const float wpoint = pow(1.002, 2.0); - color.rgb = ScaleLuma(color.rgb); + color = ScaleBlk(color); if (CorrectionPalette == 1) { color.rgb = ColorCorrection(color.rgb); } if (FilmicProcess == 1) { color.rgb = CrossShift(color.rgb); } @@ -1247,9 +1246,9 @@ float4 TonemapPass(float4 color, float2 texcoord) 0.3575761, 0.7151522, 0.1191920, // 2nd column 0.1804375, 0.0721750, 0.9503041 ); // 3rd column #else - const float3x3 RGB2XYZ = { 0.4124564, 0.3575761, 0.1804375, - 0.2126729, 0.7151522, 0.0721750, - 0.0193339, 0.1191920, 0.9503041 }; + static const float3x3 RGB2XYZ = { 0.4124564, 0.3575761, 0.1804375, + 0.2126729, 0.7151522, 0.0721750, + 0.0193339, 0.1191920, 0.9503041 }; #endif #if (GLSL == 1) @@ -1266,6 +1265,7 @@ float4 TonemapPass(float4 color, float2 texcoord) Yxy.b = XYZ.g / (XYZ.r + XYZ.g + XYZ.b); // y = Y / (X + Y + Z) if (CorrectionPalette == 2) { Yxy.rgb = ColorCorrection(Yxy.rgb); } + if (TonemapType == 2) { Yxy.r = FilmicTonemap(Yxy.rgb).r; } // (Lp) Map average luminance to the middlegrey zone by scaling pixel luminance float Lp = Yxy.r * float(Exposure) / (float(Luminance) + delta); @@ -1273,8 +1273,6 @@ float4 TonemapPass(float4 color, float2 texcoord) // (Ld) Scale all luminance within a displayable range of 0 to 1 Yxy.r = (Lp * (1.0 + Lp / wpoint)) / (1.0 + Lp); - if (TonemapType == 2) { Yxy.r = FilmicTonemap(Yxy.rgb).r; } - // Yxy -> XYZ conversion XYZ.r = Yxy.r * Yxy.g / Yxy.b; // X = Y * x / y XYZ.g = Yxy.r; // copy luminance Y @@ -1289,9 +1287,9 @@ float4 TonemapPass(float4 color, float2 texcoord) -1.5371385, 1.8760108, -0.2040259, // 2nd column -0.4985314, 0.0415560, 1.0572252 ); // 3rd column #else - const float3x3 XYZ2RGB = { 3.2404542,-1.5371385,-0.4985314, - -0.9692660, 1.8760108, 0.0415560, - 0.0556434,-0.2040259, 1.0572252 }; + static const float3x3 XYZ2RGB = { 3.2404542,-1.5371385,-0.4985314, + -0.9692660, 1.8760108, 0.0415560, + 0.0556434,-0.2040259, 1.0572252 }; #endif #if (GLSL == 1) @@ -1299,7 +1297,7 @@ float4 TonemapPass(float4 color, float2 texcoord) #else color.rgb = mul(XYZ2RGB, XYZ); #endif - color.a = RGBLuminance(color.rgb); + color.a = AvgLuminance(color.rgb); return color; } @@ -1315,9 +1313,9 @@ float4 ContrastPass(float4 color, float2 texcoord) #if (CurveType != 2) #if (GLSL == 1) - float3 luma = float3(RGBLuminance(color.rgb)); + float3 luma = float3(AvgLuminance(color.rgb)); #else - float3 luma = (float3)RGBLuminance(color.rgb); + float3 luma = (float3)AvgLuminance(color.rgb); #endif float3 chroma = color.rgb - luma; #endif @@ -1358,7 +1356,7 @@ float4 ContrastPass(float4 color, float2 texcoord) color.rgb = lerp(color.rgb, LColor, CurveBlend); #endif - color.a = RGBLuminance(color.rgb); + color.a = AvgLuminance(color.rgb); return saturate(color); } @@ -1437,7 +1435,7 @@ float4 CelPass(float4 color, float2 texcoord) col[i].b = round(col[i].b * thresholds.b) / thresholds.b; #endif - lum[i] = RGBLuminance(col[i].xyz); + lum[i] = AvgLuminance(col[i].xyz); yuv = GetYUV(col[i]); #if (UseYuvLuma == 0) @@ -1469,7 +1467,7 @@ float4 CelPass(float4 color, float2 texcoord) color.rgb = lerp(shadedColor + edge * -EdgeStrength, pow(edge, EdgeFilter) * -EdgeStrength + color.rgb, 0.5); #endif - color.a = RGBLuminance(color.rgb); + color.a = AvgLuminance(color.rgb); return saturate(color); } @@ -1577,7 +1575,7 @@ float4 ColorGrading(float4 color, float2 texcoord) } color.rgb = HSVtoRGB(HSVColor); - color.a = RGBLuminance(color.rgb); + color.a = AvgLuminance(color.rgb); return saturate(color); } @@ -1608,7 +1606,7 @@ float4 ScanlinesPass(float4 color, float2 texcoord, float4 fragcoord) } else { - intensity = smoothstep(0.2, ScanlineBrightness, color) + normalize(float4(color.xyz, RGBLuminance(color.xyz))); + intensity = smoothstep(0.2, ScanlineBrightness, color) + normalize(float4(color.xyz, AvgLuminance(color.xyz))); } float level = (4.0 - texcoord.x) * ScanlineIntensity; @@ -1673,7 +1671,7 @@ float4 DitherPass(float4 color, float2 texcoord) color.rgb += RGBShift; #endif - color.a = RGBLuminance(color.rgb); + color.a = AvgLuminance(color.rgb); return color; } diff --git a/bin/shaders/GSdx_FX_Settings.ini b/bin/shaders/GSdx_FX_Settings.ini index 7097a6ffd8..f263106319 100644 --- a/bin/shaders/GSdx_FX_Settings.ini +++ b/bin/shaders/GSdx_FX_Settings.ini @@ -53,7 +53,7 @@ ------------------------------------------------------------------------------*/ //##[FXAA OPTIONS]## -#define FxaaSubpixMax 0.25 //[0.00 to 1.00] Amount of subpixel aliasing removal. Higher values: softer. Lower values: sharper. 0.00: Edge only. +#define FxaaSubpixMax 0.00 //[0.00 to 1.00] Amount of subpixel aliasing removal. Higher values: softer. Lower values: sharper. 0.00: Edge only. #define FxaaQuality 4 //[1|2|3|4] Overall Fxaa quality preset (pixel coverage). 1: Low, 2: Medium, 3: High, 4: Ultra. #define FxaaEarlyExit 1 //[0 or 1] Use Fxaa early exit pathing. When enabled: Only luma edge pixels are antialiased. When disabled: the entire scene is antialiased(FSAA). @@ -75,7 +75,6 @@ #define BloomStrength 0.250 //[0.100 to 1.000] Overall strength of the bloom. You may want to readjust for each blend type. #define BlendStrength 1.000 //[0.100 to 1.000] Strength of the bloom blend. Lower for less blending, higher for more. (Default: 1.000). #define BloomWidth 4.000 //[1.000 to 8.000] Width of the bloom 'glow' spread. 0.000 = off. Scales with BloomStrength. (Default: 4.000). -#define BloomCutoff 0.05 //[0.00 to 1.00] Threshold for the bloom affecting darker areas. This is done automatically by the bloom, but I've included this setting to provide some control. #define BloomReds 1.00 //[0.00 to 8.00] Red channel component of the RGB correction curve. Higher values equals red reduction. 1.00 is default. #define BloomGreens 1.00 //[0.00 to 8.00] Green channel component of the RGB correction curve. Higher values equals green reduction. 1.00 is default. #define BloomBlues 1.00 //[0.00 to 8.00] Blue channel component of the RGB correction curve. Higher values equals blue reduction. 1.00 is default. @@ -83,7 +82,7 @@ //##[TONEMAP OPTIONS]## #define TonemapType 1 //[0|1|2] Type of base tone mapping operator. 0 is LDR, 1 is HDR(original), 2 is HDR filmic(palette alterations for more of a film style). #define ToneAmount 0.25 //[0.00 to 1.00] Tonemap strength (scene correction) higher for stronger tone mapping, lower for lighter. (Default: ~ 0.20) -#define BlackLevels 0.30 //[0.00 to 1.00] Black level balance (shadow correction). Increase to lighten blacks, lower to deepen them. (Default: ~ 0.30) +#define BlackLevels 0.08 //[0.00 to 1.00] Black level balance (shadow correction). Increase to deepen blacks, lower to lighten them. (Default: ~ 0.10) #define Exposure 1.00 //[0.10 to 2.00] White correction (brightness) Higher values for more Exposure, lower for less. #define Luminance 1.00 //[0.10 to 2.00] Luminance average (luminance correction) Higher values to decrease luminance average, lower values to increase luminance. #define WhitePoint 1.02 //[0.10 to 2.00] Whitepoint avg (lum correction) Use to alter the scene whitepoint average. Raising can give a cinema look. @@ -99,7 +98,7 @@ #define RedShift 0.50 //[0.10 to 1.00] Red colour component shift of the filmic tone shift. Alters the red balance of the shift. Requires FilmicProcess. #define GreenShift 0.45 //[0.10 to 1.00] Green colour component shift of the filmic tone shift. Alters the green balance of the shift. Requires FilmicProcess. #define BlueShift 0.45 //[0.10 to 1.00] Blue colour component shift of the filmic tone shift. Alters the blue balance of the shift. Requires FilmicProcess. -#define ShiftRatio 0.33 //[0.10 to 1.00] The blending ratio for the base colour and the colour shift. Higher for a stronger effect. Requires FilmicProcess. +#define ShiftRatio 0.28 //[0.10 to 1.00] The blending ratio for the base colour and the colour shift. Higher for a stronger effect. Requires FilmicProcess. //##[SHARPEN OPTIONS]## #define SharpeningType 2 //[1 or 2] The type of sharpening to use. Type 1 is a High Pass Gaussian. Type 2 is a higher quality(slightly slower) Bicubic Sampling type. From 9521b0021bdda1e5212fa429c5a6938afb21f0cb Mon Sep 17 00:00:00 2001 From: Kieran Hanrahan Date: Fri, 13 Mar 2015 18:48:40 +0000 Subject: [PATCH 2/5] GSdx FX 2.30 preview --- bin/shaders/GSdx_FX_Settings.ini | 231 ++++++++++++++++--------------- 1 file changed, 123 insertions(+), 108 deletions(-) diff --git a/bin/shaders/GSdx_FX_Settings.ini b/bin/shaders/GSdx_FX_Settings.ini index f263106319..2b9b8f476d 100644 --- a/bin/shaders/GSdx_FX_Settings.ini +++ b/bin/shaders/GSdx_FX_Settings.ini @@ -1,5 +1,5 @@ /*===============================================================================*\ -|######################## [GSdx FX Suite v2.20] ########################| +|######################## [GSdx FX Suite v2.30] ########################| |########################## By Asmodean ##########################| || || || This program is free software; you can redistribute it and/or || @@ -10,146 +10,161 @@ || This program is distributed in the hope that it will be useful, || || but WITHOUT ANY WARRANTY; without even the implied warranty of || || MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the || -|| GNU General Public License for more details. (c)2014 || +|| GNU General Public License for more details. (c)2015 || || || |#################################################################################| \*===============================================================================*/ //#NOTICE: This post-processing suite requires Direct3D10(Shader Model 4.0), or higher. /*------------------------------------------------------------------------------ - [DEFINITIONS & ON/OFF OPTIONS] + [DEFINITIONS & ON/OFF OPTIONS] ------------------------------------------------------------------------------*/ -//---------------------------#[CHOOSE EFFECTS]#--------------------------------\\ +//--------------------------#[CHOOSE EFFECTS]#--------------------------------\\ -//-#[ANTIALIASING TECHNIQUES] [1=ON|0=OFF] #READ: For best results: Use gsdx fx antialiasing OR FS filtering. Not both. -#define UHQ_FXAA 0 //#High Quality Fast Approximate Anti Aliasing. Adapted for GSdx from Timothy Lottes FXAA 3.11. If using GSdx's internal FXAA, this equals FXAA2x. [3D] +//#[ANTIALIASING TECHNIQUES] [1=ON|0=OFF] #READ: For best results: Use gsdx fx antialiasing OR filtering. Not both together. +#define UHQ_FXAA 0 //# High Quality Fast Approximate Anti Aliasing. If GSdx's internal FXAA is also enabled, this equals FXAA2x.[3D] -//-#[FS SCALING TECHNIQUES] [1=ON|0=OFF] #READ: For best results: Only enable one type of filtering at one time. Use post antialiasing OR FS filtering, not both. -#define BILINEAR_FILTERING 0 //#BiLinear Fullscreen Texture Filtering. BiLinear filtering - light to medium filtering of textures. [2D] -#define BICUBIC_FILTERING 0 //#Bicubic Fullscreen Texture Filtering. BiCubic filtering - medium to strong filtering of textures. [2D] -#define GAUSSIAN_FILTERING 0 //#Gaussian Fullscreen Texture Filtering. Gaussian filtering - strong to extra strong filtering of textures. [2D] -#define BICUBLIC_SCALER 0 //#Bicubic Interpolation Scaling. Uses BCS on up scaling, and downsampling of games, for smoother scaling. -#define LANCZOS_SCALER 0 //#Lanczos Interpolation Scaling. Uses Lanczos on up scaling, and downsampling of games for smoother scaling. +//#[FS SCALING TECHNIQUES] [1=ON|0=OFF] #READ: For best results: Only enable one type of filtering at one time. Use post antialiasing OR FS filtering, not both. +#define BILINEAR_FILTERING 0 //# Bilinear Fullscreen Texture Filtering. BiLinear filtering - light to medium filtering of textures.[2D] +#define BICUBIC_FILTERING 0 //# Bicubic Fullscreen Texture Filtering. BiCubic filtering - medium to strong filtering of textures.[2D] +#define GAUSSIAN_FILTERING 0 //# Gaussian Fullscreen Texture Filtering. Gaussian filtering - strong to extra strong filtering of textures.[2D] +#define BICUBLIC_SCALER 0 //# Bicubic Interpolation Scaling. Uses BCS on up scaling, and downsampling of games, for smoother scaling. +#define LANCZOS_SCALER 0 //# Lanczos Interpolation Scaling. Uses Lanczos on up scaling, and downsampling of games for smoother scaling. -//-#[LIGHTING & COLOUR] [1=ON|0=OFF] #READ: These can all be turned on & off independently of each other. [For High Dynamic Range(HDR) use Bloom & Tonemapping together] -#define BLENDED_BLOOM 1 //#High Quality Bloom, using blend techniques. Blooms naturally, per environment. -#define SCENE_TONEMAPPING 1 //#HDR Scene Tonemapping & RGB Colour Correction. Corrects colour, and tone maps the scene. -#define GAMMA_CORRECTION 1 //#RGB Gamma Correction. sRGB->Linear->sRGB correction curve. Enable for games with incorrect gamma. -#define TEXTURE_SHARPEN 0 //#Bicubic Texture Unsharpen Mask. Looks similar to a negative texture LOD bias. Enhances texture fidelity. -#define PIXEL_VIBRANCE 0 //#Pixel Vibrance. Intelligently adjusts pixel vibrance depending on original saturation. -#define S_CURVE_CONTRAST 0 //#S-Curve Scene Contrast Enhancement. Locally adjusts contrast using S-curves. -#define COLOR_GRADING 0 //#Post-Complement Colour Grading. Alters individual colour components on a scene, to enhance selected colour tones. -#define CEL_SHADING 0 //#PX Cel Shading. Simulates the look of animation/toon. Typically best suited for animated style games. +//#[LIGHTING & COLOUR] [1=ON|0=OFF] #READ: These can all be turned on & off independently of each other. [For High Dynamic Range(HDR) use Bloom & Tonemapping together] +#define BLENDED_BLOOM 1 //# High Quality SP Bloom. Soft lighting with blending techniques, for a natural looking bloom. +#define SCENE_TONEMAPPING 1 //# HDR Scene Tonemapping. Layered component conversion, and applies scene tone mapping. +#define COLOR_CORRECTION 1 //# Component Color Correction. Colorspace conversion, with correction curves, and multiple palette types. +#define CROSS_PROCESSING 0 //# Filmic Cross Processing. Alters the tone of the scene, crossing the game's color set, with another. +#define GAMMA_CORRECTION 0 //# RGB Gamma Correction. Fixed expansion to variable compression gamma correction curve. +#define PIXEL_VIBRANCE 0 //# Pixel Vibrance. Intelligently adjusts pixel vibrance depending on original color saturation. +#define COLOR_GRADING 0 //# Post-Complement Colour Grading. Alters individual colour components on a scene, to enhance selected colour tones. +#define TEXTURE_SHARPEN 0 //# Bicubic Texture Unsharpen Mask. Looks similar to a negative texture LOD bias. Enhances texture fidelity. +#define CURVE_CONTRAST 0 //# S-Curve Scene Contrast Enhancement. Locally adjusts contrast using a four-point cubic bezier spline. +#define CEL_SHADING 0 //# PX Cel Shading. Simulates the look of animation/toon. Typically best suited for animated style games. +#define PAINT_SHADING 0 //# Paint Shading. Creates the effect of a painted scene. Adapted from ENB series, it's pretty performance heavy. -//-#[TV EMU TECHNIQUES] [1=ON|0=OFF] #READ: These can all be turned on & off independently of each other. These effects are typically used to simulated older TVs/CRT etc. -#define SCANLINES 0 //#Scanlines to simulate the look of a CRT TV. Typically suited to sprite games. Note: Works best at Native Res. -#define VIGNETTE 0 //#Darkens the edges of the screen, to make it look more like it was shot with a camera lens. -#define DITHERING 0 //#Subpixel Dithering to simulate more colors than your monitor can display. Smoothes gradiants, this can reduce color banding. -#define PX_BORDER 0 //#Creates a pixel border, as a workaround for the bright edge that using hardware antialiasing(MSAA) can cause. (Ported by request from SFX). +//#[TV EMU TECHNIQUES] [1=ON|0=OFF] #READ: These can all be turned on & off independently of each other. These effects are typically used to simulated older TVs/CRT etc. +#define SCANLINES 0 //# Scanlines to simulate the look of a CRT TV. Typically suited to sprite games. Note: Works best at Native Res. +#define VIGNETTE 0 //# Darkens the edges of the screen, to make it look more like it was shot with a camera lens. +#define SP_DITHERING 0 //# Subpixel Dithering to simulate more colors than your monitor can display. Smoothes gradiants, this can reduce color banding. +#define PX_BORDER 0 //# Creates a pixel border, as a workaround for the bright edge that using hardware antialiasing(MSAA) can cause. (Ported by request from SFX). /*------------------------------------------------------------------------------ [EFFECT CONFIG OPTIONS] ------------------------------------------------------------------------------*/ -//##[FXAA OPTIONS]## -#define FxaaSubpixMax 0.00 //[0.00 to 1.00] Amount of subpixel aliasing removal. Higher values: softer. Lower values: sharper. 0.00: Edge only. -#define FxaaQuality 4 //[1|2|3|4] Overall Fxaa quality preset (pixel coverage). 1: Low, 2: Medium, 3: High, 4: Ultra. -#define FxaaEarlyExit 1 //[0 or 1] Use Fxaa early exit pathing. When enabled: Only luma edge pixels are antialiased. When disabled: the entire scene is antialiased(FSAA). +//##[UHQ_FXAA] +#define FxaaSubpixMax 0.00 //[0.00 to 1.00] Amount of subpixel aliasing removal. Higher values: softer. Lower values: sharper. 0.00: Edge only. +#define FxaaQuality 4 //[1|2|3|4] Overall Fxaa quality preset (pixel coverage). 1: Low, 2: Medium, 3: High, 4: Ultra. +#define FxaaEarlyExit 1 //[0 or 1] Use Fxaa early exit pathing. When enabled: Only luma edge pixels are antialiased. When disabled: the entire scene is antialiased(FSAA). -//##[BILINEAR OPTIONS]## -#define FilterStrength 1.00 //[0.10 to 1.50] Bilinear filtering strength. Controls the overall strength of the filtering. -#define OffsetAmount 0.0 //[0.0 to 1.5] Pixel offset amount. If you want to use an st offset, 0.5 is generally recommended. 0.0 is off. +//##[BILINEAR_FILTERING] +#define FilterStrength 1.00 //[0.10 to 1.50] Bilinear filtering strength. Controls the overall strength of the filtering. +#define OffsetAmount 0.0 //[0.0 to 1.5] Pixel offset amount. If you want to use an st offset, 0.5 is generally recommended. 0.0 is off. -//##[BICUBIC OPTIONS]## -#define Interpolation Triangular //[CatMullRom, Bell, BSpline, Triangular, Cubic] Type of interpolation to use. From left to right is lighter<-->stronger filtering. -#define BicubicStrength 0.75 //[0.10 to 1.50] Bicubic filtering strength. Controls the overall strength of the filtering. -#define PixelOffset 0.0 //[0.0 to 1.5] Pixel offset amount. If you want to use an st offset, 0.5 is generally recommended. 0.0 is off. +//##[BICUBIC_FILTERING] +#define Interpolation Triangular //[CatMullRom, Bell, BSpline, Triangular, Cubic] Type of interpolation to use. From left to right is lighter<-->stronger filtering. +#define BicubicStrength 0.75 //[0.10 to 1.50] Bicubic filtering strength. Controls the overall strength of the filtering. +#define PixelOffset 0.0 //[0.0 to 1.5] Pixel offset amount. If you want to use an st offset, 0.5 is generally recommended. 0.0 is off. -//##[GAUSSIAN OPTIONS]## -#define FilterAmount 1.00 //[0.10 to 1.50] Gaussian filtering strength. Controls the overall strength of the filtering. -#define GaussianSpread 0.75 //[0.50 to 4.00] The filtering spread & offset levels. Controls the sampling spread of the filtering. +//##[GAUSSIAN_FILTERING] +#define FilterAmount 1.00 //[0.10 to 1.50] Gaussian filtering strength. Controls the overall strength of the filtering. +#define GaussianSpread 0.75 //[0.50 to 4.00] The filtering spread & offset levels. Controls the sampling spread of the filtering. -//##[BLOOM OPTIONS]## -#define BloomType BlendGlow //[BlendGlow, BlendLuma, BlendAddLight, BlendScreen, BlendOverlay] The type of blending for the bloom. Glow & Overlay are dynamic. -#define BloomStrength 0.250 //[0.100 to 1.000] Overall strength of the bloom. You may want to readjust for each blend type. -#define BlendStrength 1.000 //[0.100 to 1.000] Strength of the bloom blend. Lower for less blending, higher for more. (Default: 1.000). -#define BloomWidth 4.000 //[1.000 to 8.000] Width of the bloom 'glow' spread. 0.000 = off. Scales with BloomStrength. (Default: 4.000). -#define BloomReds 1.00 //[0.00 to 8.00] Red channel component of the RGB correction curve. Higher values equals red reduction. 1.00 is default. -#define BloomGreens 1.00 //[0.00 to 8.00] Green channel component of the RGB correction curve. Higher values equals green reduction. 1.00 is default. -#define BloomBlues 1.00 //[0.00 to 8.00] Blue channel component of the RGB correction curve. Higher values equals blue reduction. 1.00 is default. +//##[BLENDED BLOOM] +#define BloomType BlendGlow //[BlendGlow, BlendAddGlow, BlendAddLight, BlendScreen, BlendLuma, BlendOverlay] The type of blended bloom. Light<->Dark. +#define BloomStrength 0.220 //[0.000 to 1.000] Overall strength of the bloom. You may want to readjust for each blend type. +#define BlendStrength 1.000 //[0.000 to 1.000] Strength of the blending. This is a modifier based on bloom. 1.0 equates to 100% strength. +#define BloomDefocus 2.000 //[1.000 to 4.000] The initial bloom defocus value. Increases the softness of light, bright objects, etc. +#define BloomWidth 3.200 //[1.000 to 8.000] Width of the bloom. Adjusts the width of the spread and soft glow. Scales with BloomStrength. +#define BloomReds 0.020 //[0.000 to 1.000] Red channel correction of the bloom. Raising will increase the bloom of reds. +#define BloomGreens 0.010 //[0.000 to 1.000] Green channel correction of the bloom. Raising will increase the bloom of greens. +#define BloomBlues 0.010 //[0.000 to 1.000] Blue channel correction of the bloom. Raising will increase the bloom of blues. -//##[TONEMAP OPTIONS]## -#define TonemapType 1 //[0|1|2] Type of base tone mapping operator. 0 is LDR, 1 is HDR(original), 2 is HDR filmic(palette alterations for more of a film style). -#define ToneAmount 0.25 //[0.00 to 1.00] Tonemap strength (scene correction) higher for stronger tone mapping, lower for lighter. (Default: ~ 0.20) -#define BlackLevels 0.08 //[0.00 to 1.00] Black level balance (shadow correction). Increase to deepen blacks, lower to lighten them. (Default: ~ 0.10) -#define Exposure 1.00 //[0.10 to 2.00] White correction (brightness) Higher values for more Exposure, lower for less. -#define Luminance 1.00 //[0.10 to 2.00] Luminance average (luminance correction) Higher values to decrease luminance average, lower values to increase luminance. -#define WhitePoint 1.02 //[0.10 to 2.00] Whitepoint avg (lum correction) Use to alter the scene whitepoint average. Raising can give a cinema look. +//##[SCENE TONEMAPPING] +#define TonemapType 1 //[0|1|2] Type of base tone mapping operator. 0 is LDR, 1 is HDR(original), 2 is HDR Filmic(slight grading). +#define FilmOperator 1 //[0 or 1] Enables the use of Filmic ALU tone mapping operations that can produce a nice cinematic look. +#define FilmStrength 0.25 //[0.000 to 1.000] Strength of the filmic tone mapping. Higher for a stronger effect. This is a dependency of FilmicALU. +#define ToneAmount 0.300 //[0.050 to 1.000] Tonemap strength (tone correction). Higher for stronger tone mapping, lower for lighter. +#define BlackLevels 0.050 //[0.000 to 1.000] Black level balance (shadow correction). Increase to deepen blacks, lower to lighten them. +#define Exposure 1.000 //[0.100 to 2.000] White correction (brightness). Higher values for more scene exposure, lower for less. +#define Luminance 1.002 //[0.100 to 2.000] Luminance average (luminance correction). Higher values will lower scene luminance average. +#define WhitePoint 1.002 //[0.100 to 2.000] Whitepoint average (wp lum correction). Higher values will lower the maximum scene white point. -//##[CORRECTION OPTIONS]## -#define CorrectionPalette 1 //[0|1|2|3] The colour correction palette type. 1: RGB, 2: YUV, 3: XYZ, 0: off. 1 is default. This requires tone mapping enabled. -#define RedCurve 1.00 //[1.00 to 8.00] Red channel component of the RGB correction curve. Higher values equals red reduction. 1.00 is default. -#define GreenCurve 1.00 //[1.00 to 8.00] Green channel component of the RGB correction curve. Higher values equals green reduction. 1.00 is default. -#define BlueCurve 1.00 //[1.00 to 8.00] Blue channel component of the RGB correction curve. Higher values equals blue reduction. 1.00 is default. +//##[COLOR CORRECTION] +#define CorrectionPalette 1 //[1|2|3|4|5] The colorspace palette type. 1: RGB, 2: YXY, 3: XYZ, 4: HSV, 5: YUV. Each one will produce a different combination of shades & hues. +#define ChannelR 2.00 //[0.00 to 8.00] R(1), Y(2), X(3), H(4), Y(5) component channel varies with the colorspace used. Higher values increase correction strength. +#define ChannelG 1.20 //[0.00 to 8.00] G(1), X(2), Y(3), S(4), U(5) component channel varies with the colorspace used. Higher values increase correction strength. +#define ChannelB 1.60 //[0.00 to 8.00] B(1), Y(2), Z(3), V(4), V(5) component channel varies with the colorspace used. Higher values increase correction strength. +#define PaletteStrength 1.00 //[0.00 to 2.00] The interpolated strength ratio between the base color, and the corrected color. Raise to increase saturation. -//##[FILMIC OPTIONS]## -#define FilmicProcess 0 //[0 or 1] Filmic cross processing. Alters the mood of the scene, for more of a filmic look. Typically best suited to realistic style games. -#define RedShift 0.50 //[0.10 to 1.00] Red colour component shift of the filmic tone shift. Alters the red balance of the shift. Requires FilmicProcess. -#define GreenShift 0.45 //[0.10 to 1.00] Green colour component shift of the filmic tone shift. Alters the green balance of the shift. Requires FilmicProcess. -#define BlueShift 0.45 //[0.10 to 1.00] Blue colour component shift of the filmic tone shift. Alters the blue balance of the shift. Requires FilmicProcess. -#define ShiftRatio 0.28 //[0.10 to 1.00] The blending ratio for the base colour and the colour shift. Higher for a stronger effect. Requires FilmicProcess. +//##[CROSS PROCESSING] +#define FilmicProcess 1 //[1|2|3] The color conversion type for the cross process. 1: cool, 2: warm, 3: dusk. You can achieve different results with each. +#define RedShift 0.55 //[0.10 to 1.00] Red color component shift of the filmic processing. Alters the red balance of the shift. +#define GreenShift 0.50 //[0.10 to 1.00] Green color component shift of the filmic processing. Alters the green balance of the shift. +#define BlueShift 0.55 //[0.10 to 1.00] Blue color component shift of the filmic processing. Alters the blue balance of the shift. +#define ShiftRatio 0.50 //[0.10 to 2.00] The blending ratio for the base color and the color shift. Higher for a stronger effect. -//##[SHARPEN OPTIONS]## -#define SharpeningType 2 //[1 or 2] The type of sharpening to use. Type 1 is a High Pass Gaussian. Type 2 is a higher quality(slightly slower) Bicubic Sampling type. -#define SharpenStrength 0.75 //[0.10 to 1.00] Strength of the texture luma sharpening effect. This is the maximum strength that will be used. -#define SharpenClamp 0.015 //[0.005 to 0.500] Reduces the clamping/limiting on the maximum amount of sharpening each pixel recieves. Raise this to reduce the clamping. -#define SharpenBias 1.00 //[1.00 to 4.00] Sharpening edge bias. Lower values for clean subtle sharpen, and higher values for a deeper textured sharpen. -#define DebugSharpen 0 //[0 or 1] Visualize the sharpening effect. Useful for fine-tuning. Best to disable other effects, to see edge detection clearly. +//##[TEXTURE SHARPEN] +#define SharpenStrength 0.75 //[0.10 to 2.00] Strength of the texture sharpening effect. This is the maximum strength that will be used. +#define SharpenClamp 0.012 //[0.005 to 0.500] Reduces the clamping/limiting on the maximum amount of sharpening each pixel recieves. Raise this to reduce the clamping. +#define SharpenBias 1.00 //[1.00 to 4.00] Sharpening edge bias. Lower values for clean subtle sharpen, and higher values for a deeper textured sharpen. +#define DebugSharpen 0 //[0 or 1] Visualize the sharpening effect. Useful for fine-tuning. Best to disable other effects, to see edge detection clearly. -//##[GRADING OPTIONS]## -#define RedGrading 1.00 //[0.0 to 3.0] Red colour grading coefficient. Adjust to influence the red channel coefficients of the grading, and highlight tones. -#define GreenGrading 1.00 //[0.0 to 3.0] Green colour grading coefficient. Adjust to influence the Green channel coefficients of the grading, and highlight tones. -#define BlueGrading 1.00 //[0.0 to 3.0] Blue colour grading coefficient. Adjust to influence the Blue channel coefficients of the grading, and highlight tones. -#define GradingStrength 0.25 //[0.00 to 1.00] The overall max strength of the colour grading effect. Raise to increase, lower to decrease the amount. -#define Correlation 1.00 //[0.10 to 1.00] Correlation between the base colour, and the grading influence. Lower = more of the scene is graded, Higher = less of the scene is graded. +//##[PIXEL VIBRANCE] +#define Vibrance 0.15 //[-1.00 to 1.00] Overall vibrance strength. Locally adjusts the vibrance of pixels depending on their original saturation. +#define RedVibrance 1.00 //[-8.00 to 8.00] Red channel coefficient of the vibrance strength. Adjusting the vibrance of the red channel independently. +#define GreenVibrance 1.00 //[-8.00 to 8.00] Green channel coefficient of the vibrance strength. Adjusting the vibrance of the green channel independently. +#define BlueVibrance 1.00 //[-8.00 to 8.00] Blue channel coefficient of the vibrance strength. Adjusting the vibrance of the blue channel independently. -//##[CSHADE OPTIONS]## -#define EdgeStrength 1.50 //[0.00 to 4.00] Overall strength of the cel edge outline effect. 0.00 = no outlines. -#define EdgeFilter 0.60 //[0.10 to 2.00] Filters out fainter cel edges. Use it for balancing the cel edge density. EG: for faces, foliage, etc. Raise to filter out more edges. -#define EdgeThickness 1.00 //[0.50 to 4.00] Thickness of the cel edges. Increase for thicker outlining. Note: when downsampling, raise this further to keep the edges as noticeable. -#define PaletteType 2 //[1|2|3] The colour palette to use. 1 is Game Original, 2 is Animated Shading, 3 is Water Painting (Default is 2: Animated Shading). #!Options below don't affect palette 1. -#define UseYuvLuma 0 //[0 or 1] Uses YUV luma calculations, or base colour luma calculations. Yuv luma can produce a better shaded look, but if it looks odd, disable it for that game. -#define LumaConversion 1 //[0 or 1] Uses BT.601, or BT.709, RGB<-YUV->RGB conversions. Some games prefer 601, but most prefer 709. BT.709 is typically recommended. -#define ColorRounding 1 //[0 or 1] Uses rounding methods on colors. This can emphasise shaded toon colors. Looks good in some games, and odd in others. Try it in-game and see. +//##[COLOR_GRADING] +#define RedGrading 1.20 //[0.00 to 3.00] Red colour grading coefficient. Adjust to influence the red channel coefficients of the grading, and highlight tones. +#define GreenGrading 1.10 //[0.00 to 3.00] Green colour grading coefficient. Adjust to influence the Green channel coefficients of the grading, and highlight tones. +#define BlueGrading 1.10 //[0.00 to 3.00] Blue colour grading coefficient. Adjust to influence the Blue channel coefficients of the grading, and highlight tones. +#define GradingStrength 0.25 //[0.00 to 1.00] The overall max strength of the colour grading effect. Raise to increase, lower to decrease the amount. +#define Correlation 1.00 //[0.10 to 1.00] Correlation between the base colour, and the grading influence. Lower = more of the scene is graded, Higher = less of the scene is graded. -//##[SCANLINE OPTIONS]## -#define ScanlineType 0 //[0|1|2] The type & orientation of the scanlines. 0 is x(horizontal), 1 is y(vertical), 2 is both(xy) -#define ScanlineScale 0.50 //[0.20 to 2.00] The scaling & thickness of the scanlines. Changing this can help with PCSX2 IR scaling problems. -#define ScanlineIntensity 0.18 //[0.10 to 1.00] The intensity of the scanlines. Defaults: 0.18 for ScanlineType 0|1|2, 0.50 for ScanlineType 3. -#define ScanlineBrightness 1.00 //[0.50 to 2.00] The brightness of the scanlines. Defaults: 2.00 for ScanlineType 0|1|2, 1.50 for ScanlineType 3. +//##[CEL SHADING] +#define EdgeStrength 1.00 //[0.00 to 4.00] Overall strength of the cel edge outline effect. Affects the overall density. 0.00: no outlines. +#define EdgeFilter 0.60 //[0.10 to 2.00] Filters out fainter cel edges. Use it for balancing the cel edge density. EG: for faces, foliage, etc. +#define EdgeThickness 1.00 //[0.50 to 4.00] Thickness of the cel edges. Increase for thicker outlining. Note: when downsampling, raise this to keep the same thickness. +#define PaletteType 2 //[1|2|3] The color palette to use. 1 is Game Original, 2 is Animated Shading, 3 is Water Painting (Default is 2: Animated Shading). +#define UseYuvLuma 0 //[0 or 1] Uses YUV luma calculations, or base color luma calculations. Yuv luma can produce a better shaded look. +#define LumaConversion 1 //[0 or 1] Uses BT.601, or BT.709, RGB<-YUV->RGB conversions. Some games prefer 601, but most prefer 709. BT.709 is typically recommended. +#define ColorRounding 1 //[0 or 1] Uses rounding methods on colors. This can emphasise shaded toon colors. Looks good in some games, and odd in others. -//##[VIGNETTE OPTIONS]## -#define VignetteRatio 1.77 //[0.15 to 6.00] Sets the espect ratio of the vignette. 1.77 for 16:9, 1.60 for 16:10, 1.33 for 4:3, 1.00 for 1:1. -#define VignetteRadius 1.10 //[0.50 to 3.00] Radius of the vignette effect. Lower values for stronger radial effect from center -#define VignetteAmount 0.25 //[0.00 to 1.00] Strength of black edge occlusion. Increase for higher strength, decrease for lower. -#define VignetteSlope 12 //[2|4|8|10|12|16] How far away from the center the vignetting will start. +//##[PAINT SHADING] +#define PaintMethod 2 //[1 or 2] The algorithm used for paint effect. 1: water painting, 2: oil painting. You may want to readjust the radius between the two. +#define PaintRadius 4 //[2 to 8] Radius of the painted effect, increasing the radius also requires longer loops, so higher values require more performance. +#define PaintStrength 1.00 //[0.00 to 1.00] The overall interpolated strength of the paint effect. Where 1.0 equates to 100% strength. -//##[CONTRAST OPTIONS]## -#define CurveType 0 //[0|1|2] Choose what to apply contrast to. 0 = Luma, 1 = Chroma, 2 = both Luma and Chroma. Default is 0 (Luma) -#define CurvesContrast 0.35 //[0.00 to 2.00] The amount of contrast you want. Controls the overall strength of the texture sharpening. +//##[CURVE_CONTRAST] +#define CurveType 0 //[0|1|2] Choose what to apply contrast to. 0 = Luma, 1 = Chroma, 2 = both Luma and Chroma. Default is 0 (Luma) +#define CurvesContrast 0.35 //[0.00 to 2.00] The amount of contrast you want. Controls the overall strength of the texture sharpening. -//##[VIBRANCE OPTIONS]## -#define Vibrance 0.20 //[-1.00 to 1.00] Adjust the vibrance of pixels depending on their original saturation. 0.00 is original vibrance. +//##[GAMMA_CORRECTION] +#define Gamma 2.20 //[1.5 to 4.0] Gamma correction. Decrease for lower gamma(darker). Increase for higher gamma(brighter). (Default: 2.2) -//##[GAMMA OPTIONS]## -#define Gamma 2.20 //[1.5 to 4.0] Gamma correction. Decrease for lower gamma(darker). Increase for higher gamma(brighter). (Default: 2.2) +//##[SCANLINES] +#define ScanlineType 0 //[0|1|2] The type & orientation of the scanlines. 0 is x(horizontal), 1 is y(vertical), 2 is both(xy) +#define ScanlineScale 0.50 //[0.20 to 2.00] The scaling & thickness of the scanlines. Changing this can help with PCSX2 IR scaling problems. +#define ScanlineIntensity 0.18 //[0.10 to 1.00] The intensity of the scanlines. Defaults: 0.18 for ScanlineType 0|1|2, 0.50 for ScanlineType 3. +#define ScanlineBrightness 1.02 //[0.50 to 2.00] The brightness of the scanlines. Defaults: 2.00 for ScanlineType 0|1|2, 1.50 for ScanlineType 3. -//##[DITHERING OPTIONS]## -#define DitherMethod 2 //[1 or 2] 1 is Ordering dithering(faster, lower quality), 2 is Random dithering (better dithering, but not as fast) +//##[VIGNETTE] +#define VignetteRatio 1.77 //[0.15 to 6.00] Sets the espect ratio of the vignette. 1.77 for 16:9, 1.60 for 16:10, 1.33 for 4:3, 1.00 for 1:1. +#define VignetteRadius 1.10 //[0.50 to 3.00] Radius of the vignette effect. Lower values for stronger radial effect from center +#define VignetteAmount 0.25 //[0.00 to 1.00] Strength of black edge occlusion. Increase for higher strength, decrease for lower. +#define VignetteSlope 12 //[2|4|8|10|12|16] How far away from the center the vignetting will start. -//##[BORDER OPTIONS]## -#define BorderWidth float2(2, 2) //[0 to 2048, 0 to 2048] (X,Y)-width of the border. Measured in pixels. -#define BorderColor float3(0, 0, 0) //[0 to 255, 0 to 255, 0 to 255] What color the border should be. In integer RGB colors, meaning 0,0,0 is black and 255,255,255 is full white. +//##[SUBPIXEL DITHERING] +#define DitherMethod 2 //[1 or 2] 1: Ordered grid dithering(faster), 2: random dithering(higher quality). Hardware dithering is also enabled by default. +#define ShowMethod 0 //[0 or 1] Shows the dithering method, based of the type of dithering selected. Useful for debugging, and confirmation of working order. + +//##[PX_BORDER] +#define BorderWidth float2(2, 2) //[0 to 2048, 0 to 2048] (X,Y)-width of the border. Measured in pixels. +#define BorderColor float3(0, 0, 0) //[0 to 255, 0 to 255, 0 to 255] What color the border should be. In integer RGB colors, meaning 0,0,0 is black and 255,255,255 is full white. //[END OF USER OPTIONS] From 0fbe94eb4152d66486ae1c21f3b58542283791b3 Mon Sep 17 00:00:00 2001 From: Kieran Hanrahan Date: Fri, 13 Mar 2015 19:01:09 +0000 Subject: [PATCH 3/5] GSfx FX 2.3 preview Where to begin o.o I'd be here all night marking off all of the changes from the previous version. Basic rundown; I've reworked, and rewrote most of it, and seperated effects that I had embedded in others. I've added some new effects, improved the options, and their descriptions. Completely rewrote the color processing logic. Rewrote and improved the logic of many other of the effects. Expanded, and improved the options, and descriptions. etc, etc. Current effects include; * FXAA 3.11 - * Bilinear Texture Filtering * Bicubic Texture Filtering * Gaussian Texture Filtering * Bicubic Scaling * Lanczos Scaling - * Blended Bloom (6 different blend types) * HDR Scene Tone Mapping (4 different operator types) * Color Correction (5 colorspace types) * Cross Processing (3 conversion types) * Post-Complement Colour Grading * Gamma Correction Curve * Pixel Vibrance Adjustment * Texture Unsharp Mask * Contrast Enhancement * Px Cel Shading * Paint Shading - * Sub-pixel Dithering * Scanline Emulation * Vignette Effect * Pixel Border With a plethora of options for them. Enjoy =) --- bin/shaders/GSdx.fx | 1089 ++++++++++++++++++++++++++++--------------- 1 file changed, 703 insertions(+), 386 deletions(-) diff --git a/bin/shaders/GSdx.fx b/bin/shaders/GSdx.fx index 818f73448b..a1b3c920ca 100644 --- a/bin/shaders/GSdx.fx +++ b/bin/shaders/GSdx.fx @@ -1,5 +1,5 @@ /*===============================================================================*\ -|######################## [GSdx FX Suite v2.20] ########################| +|######################## [GSdx FX Suite v2.30] ########################| |########################## By Asmodean ##########################| || || || This program is free software; you can redistribute it and/or || @@ -10,7 +10,7 @@ || This program is distributed in the hope that it will be useful, || || but WITHOUT ANY WARRANTY; without even the implied warranty of || || MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the || -|| GNU General Public License for more details. (c)2014 || +|| GNU General Public License for more details. (c)2015 || || || |#################################################################################| \*===============================================================================*/ @@ -33,12 +33,14 @@ /*------------------------------------------------------------------------------ [GLOBALS|FUNCTIONS] ------------------------------------------------------------------------------*/ -#if (GLSL == 1) +#if GLSL == 1 #define int2 ivec2 #define float2 vec2 #define float3 vec3 #define float4 vec4 +#define float4x4 mat4 +#define float3x3 mat3 #define float4x3 mat4x3 #define static #define frac fract @@ -102,26 +104,107 @@ struct PS_OUTPUT }; #endif -static float2 screenSize = _xyFrame; +static float Epsilon = 1e-10; static float2 pixelSize = _rcpFrame.xy; -static float2 invDefocus = float2(1.0 / 3840.0, 1.0 / 2160.0); +static float2 screenSize = _xyFrame; static const float3 lumCoeff = float3(0.2126729, 0.7151522, 0.0721750); -float RGBLuminance(float3 color) +//Conversion matrices +float3 RGBtoXYZ(float3 rgb) { - return dot(color.rgb, lumCoeff); + const float3x3 m = float3x3( + 0.4124564, 0.3575761, 0.1804375, + 0.2126729, 0.7151522, 0.0721750, + 0.0193339, 0.1191920, 0.9503041); + + return mul(m, rgb); } +float3 XYZtoRGB(float3 xyz) +{ + const float3x3 m = float3x3( + 3.2404542,-1.5371385,-0.4985314, + -0.9692660, 1.8760108, 0.0415560, + 0.0556434,-0.2040259, 1.0572252); + + return mul(m, xyz); +} + +float3 RGBtoYUV(float3 RGB) +{ + const float3x3 m = float3x3( + 0.2126, 0.7152, 0.0722, + -0.09991,-0.33609, 0.436, + 0.615, -0.55861, -0.05639); + + return mul(m, RGB); +} + +float3 YUVtoRGB(float3 YUV) +{ + const float3x3 m = float3x3( + 1.000, 0.000, 1.28033, + 1.000,-0.21482,-0.38059, + 1.000, 2.12798, 0.000); + + return mul(m, YUV); +} + +//Converting XYZ to Yxy +float3 XYZtoYxy(float3 xyz) +{ + float w = (xyz.r + xyz.g + xyz.b); + float3 Yxy; + + Yxy.r = xyz.g; + Yxy.g = xyz.r / w; + Yxy.b = xyz.g / w; + + return Yxy; +} + +//Converting Yxy to XYZ +float3 YxytoXYZ(float3 Yxy) +{ + float3 xyz; + xyz.g = Yxy.r; + xyz.r = Yxy.r * Yxy.g / Yxy.b; + xyz.b = Yxy.r * (1.0 - Yxy.g - Yxy.b) / Yxy.b; + + return xyz; +} + +//Average relative luminance float AvgLuminance(float3 color) { - return sqrt((color.x * color.x * lumCoeff.x) + - (color.y * color.y * lumCoeff.y) + - (color.z * color.z * lumCoeff.z)); + return sqrt( + (color.x * color.x * lumCoeff.x) + + (color.y * color.y * lumCoeff.y) + + (color.z * color.z * lumCoeff.z)); } +float smootherstep(float a, float b, float x) +{ + x = saturate((x - a) / (b - a)); + return x*x*x*(x*(x * 6 - 15) + 10); +} + +/* +float4 DebugClipping(float4 color) +{ + if (color.x >= 0.99999 && color.y >= 0.99999 && + color.z >= 0.99999) color.xyz = float3(1.0f, 0.0f, 0.0f); + + if (color.x <= 0.00001 && color.y <= 0.00001 && + color.z <= 0.00001) color.xyz = float3(0.0f, 0.0f, 1.0f); + + return color; +} +*/ + float4 sample_tex(SamplerState texSample, float2 t) { -#if (GLSL == 1) +#if GLSL == 1 return texture(texSample, t); #else return Texture.Sample(texSample, t); @@ -130,7 +213,7 @@ float4 sample_tex(SamplerState texSample, float2 t) float4 sample_texLevel(SamplerState texSample, float2 t, float lod) { -#if (GLSL == 1) +#if GLSL == 1 return textureLod(texSample, t, lod); #else return Texture.SampleLevel(texSample, t, lod); @@ -141,32 +224,32 @@ float4 sample_texLevel(SamplerState texSample, float2 t, float lod) [FXAA CODE SECTION] ------------------------------------------------------------------------------*/ -#if (UHQ_FXAA == 1) -#if (SHADER_MODEL >= 0x500) +#if UHQ_FXAA == 1 +#if SHADER_MODEL >= 0x500 #define FXAA_HLSL_5 1 #define FXAA_GATHER4_ALPHA 1 -#elif (GLSL == 1) +#elif GLSL == 1 #define FXAA_GATHER4_ALPHA 1 #else #define FXAA_HLSL_4 1 #define FXAA_GATHER4_ALPHA 0 #endif -#if (FxaaQuality == 4) +#if FxaaQuality == 4 #define FxaaEdgeThreshold 0.063 #define FxaaEdgeThresholdMin 0.000 -#elif (FxaaQuality == 3) +#elif FxaaQuality == 3 #define FxaaEdgeThreshold 0.125 #define FxaaEdgeThresholdMin 0.0312 -#elif (FxaaQuality == 2) +#elif FxaaQuality == 2 #define FxaaEdgeThreshold 0.166 #define FxaaEdgeThresholdMin 0.0625 -#elif (FxaaQuality == 1) +#elif FxaaQuality == 1 #define FxaaEdgeThreshold 0.250 #define FxaaEdgeThresholdMin 0.0833 #endif -#if (FXAA_HLSL_5 == 1) +#if FXAA_HLSL_5 == 1 struct FxaaTex { SamplerState smpl; Texture2D tex; }; #define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0) #define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o) @@ -175,7 +258,7 @@ struct FxaaTex { SamplerState smpl; Texture2D tex; }; #define FxaaDiscard clip(-1) #define FxaaSat(x) saturate(x) -#elif (FXAA_HLSL_4 == 1) +#elif FXAA_HLSL_4 == 1 struct FxaaTex { SamplerState smpl; Texture2D tex; }; #define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0) #define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o) @@ -183,14 +266,14 @@ struct FxaaTex { SamplerState smpl; Texture2D tex; }; #define FxaaSat(x) saturate(x) #endif -#if (GLSL == 1) +#if GLSL == 1 #define FxaaBool bool #define FxaaDiscard discard #define FxaaSat(x) clamp(x, 0.0, 1.0) #define FxaaTex sampler2D #define FxaaTexTop(t, p) textureLod(t, p, 0.0) #define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o) -#if (FXAA_GATHER4_ALPHA == 1) +#if FXAA_GATHER4_ALPHA == 1 // use #extension GL_ARB_gpu_shader5 : enable #define FxaaTexAlpha4(t, p) textureGather(t, p, 3) #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3) @@ -225,7 +308,7 @@ float4 FxaaPixelShader(float2 pos, FxaaTex tex, float2 fxaaRcpFrame, float fxaaS posM.x = pos.x; posM.y = pos.y; - #if (FXAA_GATHER4_ALPHA == 1) + #if FXAA_GATHER4_ALPHA == 1 float4 rgbyM = FxaaTexTop(tex, posM); float4 luma4A = FxaaTexAlpha4(tex, posM); float4 luma4B = FxaaTexOffAlpha4(tex, posM, int2(-1, -1)); @@ -264,11 +347,11 @@ float4 FxaaPixelShader(float2 pos, FxaaTex tex, float2 fxaaRcpFrame, float fxaaS float rangeMaxClamped = max(fxaaEdgeThresholdMin, rangeMaxScaled); bool earlyExit = range < rangeMaxClamped; - #if (FxaaEarlyExit == 1) + #if FxaaEarlyExit == 1 if(earlyExit) { return rgbyM; } #endif - #if (FXAA_GATHER4_ALPHA == 0) + #if FXAA_GATHER4_ALPHA == 0 float lumaNW = FxaaLuma(FxaaTexOff(tex, posM, int2(-1,-1), fxaaRcpFrame.xy)); float lumaSE = FxaaLuma(FxaaTexOff(tex, posM, int2( 1, 1), fxaaRcpFrame.xy)); float lumaNE = FxaaLuma(FxaaTexOff(tex, posM, int2( 1,-1), fxaaRcpFrame.xy)); @@ -522,7 +605,7 @@ float4 FxaaPixelShader(float2 pos, FxaaTex tex, float2 fxaaRcpFrame, float fxaaS float4 FxaaPass(float4 FxaaColor, float2 texcoord) { - #if(GLSL == 1) + #if GLSL == 1 tex = TextureSampler; FxaaColor = FxaaPixelShader(texcoord, TextureSampler, pixelSize.xy, FxaaSubpixMax, FxaaEdgeThreshold, FxaaEdgeThresholdMin); #else @@ -640,8 +723,8 @@ float Cubic(float coeff) [BILINEAR FILTERING CODE SECTION] ------------------------------------------------------------------------------*/ -#if (BILINEAR_FILTERING == 1) -float4 SampleBiLinear(in SamplerState texSample, in float2 texcoord) +#if BILINEAR_FILTERING == 1 +float4 SampleBiLinear(SamplerState texSample, float2 texcoord) { float texelSizeX = pixelSize.x; float texelSizeY = pixelSize.y; @@ -683,8 +766,8 @@ float4 BiLinearPass(float4 color, float2 texcoord) [BICUBIC FILTERING CODE SECTION] ------------------------------------------------------------------------------*/ -#if (BICUBIC_FILTERING == 1) -float4 BicubicFilter(in SamplerState texSample, in float2 texcoord) +#if BICUBIC_FILTERING == 1 +float4 BicubicFilter(SamplerState texSample, float2 texcoord) { float texelSizeX = pixelSize.x; float texelSizeY = pixelSize.y; @@ -701,23 +784,20 @@ float4 BicubicFilter(in SamplerState texSample, in float2 texcoord) float2 uvCoord = float2(float(nX) / screenSize.x + PixelOffset / screenSize.x, float(nY) / screenSize.y + PixelOffset / screenSize.y); - for (int m = -1; m <= 2; m++) - { - for (int n = -1; n <= 2; n++) - { - float4 Samples = sample_tex(texSample, uvCoord + - float2(texelSizeX * float(m), texelSizeY * float(n))); + for (int m = -1; m <= 2; m++) { + for (int n = -1; n <= 2; n++) { - float vc1 = Interpolation(float(m) - a); - float4 vecCoeff1 = float4(vc1, vc1, vc1, vc1); + float4 Samples = sample_tex(texSample, uvCoord + + float2(texelSizeX * float(m), texelSizeY * float(n))); - float vc2 = Interpolation(-(float(n) - b)); - float4 vecCoeff2 = float4(vc2, vc2, vc2, vc2); + float vc1 = Interpolation(float(m) - a); + float4 vecCoeff1 = float4(vc1, vc1, vc1, vc1); - nSum = nSum + (Samples * vecCoeff2 * vecCoeff1); - nDenom = nDenom + (vecCoeff2 * vecCoeff1); - } - } + float vc2 = Interpolation(-(float(n) - b)); + float4 vecCoeff2 = float4(vc2, vc2, vc2, vc2); + + nSum = nSum + (Samples * vecCoeff2 * vecCoeff1); + nDenom = nDenom + (vecCoeff2 * vecCoeff1); }} return nSum / nDenom; } @@ -791,8 +871,8 @@ float4 GaussianPass(float4 color, float2 texcoord) [BICUBIC SCALER CODE SECTION] ------------------------------------------------------------------------------*/ -#if (BICUBLIC_SCALER == 1) -float4 BicubicScaler(in SamplerState tex, in float2 uv, in float2 texSize) +#if BICUBLIC_SCALER == 1 +float4 BicubicScaler(SamplerState tex, float2 uv, float2 texSize) { float2 inputSize = float2(1.0/texSize.x, 1.0/texSize.y); @@ -800,7 +880,7 @@ float4 BicubicScaler(in SamplerState tex, in float2 uv, in float2 texSize) float2 index = floor(coord_hg); float2 f = coord_hg - index; - #if (GLSL == 1) + #if GLSL == 1 mat4 M = mat4( -1.0, 3.0,-3.0, 1.0, 3.0,-6.0, 3.0, 0.0, -3.0, 0.0, 3.0, 0.0, 1.0, 4.0, 1.0, 0.0 ); #else @@ -915,8 +995,7 @@ float4 LanczosScalerPass(float4 color, float2 texcoord) [GAMMA CORRECTION CODE SECTION] ------------------------------------------------------------------------------*/ -#if (GAMMA_CORRECTION == 1) -float3 RGBGammaToLinear(in float3 color, in float gamma) +float3 EncodeGamma(float3 color, float gamma) { color = saturate(color); color.r = (color.r <= 0.0404482362771082) ? @@ -929,7 +1008,7 @@ float3 RGBGammaToLinear(in float3 color, in float gamma) return color; } -float3 LinearToRGBGamma(in float3 color, in float gamma) +float3 DecodeGamma(float3 color, float gamma) { color = saturate(color); color.r = (color.r <= 0.00313066844250063) ? @@ -942,23 +1021,23 @@ float3 LinearToRGBGamma(in float3 color, in float gamma) return color; } +#if GAMMA_CORRECTION == 1 float4 GammaPass(float4 color, float2 texcoord) { - static const float GammaConst = 2.233; - color.rgb = RGBGammaToLinear(color.rgb, GammaConst); - color.rgb = LinearToRGBGamma(color.rgb, float(Gamma)); + static const float GammaConst = 2.233333; + color.rgb = EncodeGamma(color.rgb, GammaConst); + color.rgb = DecodeGamma(color.rgb, float(Gamma)); color.a = AvgLuminance(color.rgb); return color; } #endif - /*------------------------------------------------------------------------------ [TEXTURE SHARPEN CODE SECTION] ------------------------------------------------------------------------------*/ -#if (TEXTURE_SHARPEN == 1) -float4 SampleBicubic(in SamplerState texSample, in float2 texcoord) +#if TEXTURE_SHARPEN == 1 +float4 SampleBicubic(SamplerState texSample, float2 texcoord) { float texelSizeX = pixelSize.x * float(SharpenBias); float texelSizeY = pixelSize.y * float(SharpenBias); @@ -974,23 +1053,20 @@ float4 SampleBicubic(in SamplerState texSample, in float2 texcoord) float2 uvCoord = float2(float(nX) / screenSize.x, float(nY) / screenSize.y); - for (int m = -1; m <= 2; m++) - { - for (int n = -1; n <= 2; n++) - { - float4 Samples = sample_tex(texSample, uvCoord + - float2(texelSizeX * float(m), texelSizeY * float(n))); + for (int m = -1; m <= 2; m++) { + for (int n = -1; n <= 2; n++) { - float vc1 = Cubic(float(m) - a); - float4 vecCoeff1 = float4(vc1, vc1, vc1, vc1); + float4 Samples = sample_tex(texSample, uvCoord + + float2(texelSizeX * float(m), texelSizeY * float(n))); - float vc2 = Cubic(-(float(n) - b)); - float4 vecCoeff2 = float4(vc2, vc2, vc2, vc2); + float vc1 = Cubic(float(m) - a); + float4 vecCoeff1 = float4(vc1, vc1, vc1, vc1); - nSum = nSum + (Samples * vecCoeff2 * vecCoeff1); - nDenom = nDenom + (vecCoeff2 * vecCoeff1); - } - } + float vc2 = Cubic(-(float(n) - b)); + float4 vecCoeff2 = float4(vc2, vc2, vc2, vc2); + + nSum = nSum + (Samples * vecCoeff2 * vecCoeff1); + nDenom = nDenom + (vecCoeff2 * vecCoeff1); }} return nSum / nDenom; } @@ -1007,8 +1083,8 @@ float4 TexSharpenPass(float4 color, float2 texcoord) color.rgb = color.rgb + sharpenLuma; color.a = AvgLuminance(color.rgb); - #if (DebugSharpen == 1) - color = saturate(0.5f + (sharpenLuma * 4)).rrrr; + #if DebugSharpen == 1 + color = saturate(0.5f + (sharpenLuma * 4)).xxxx; #endif return saturate(color); @@ -1016,13 +1092,15 @@ float4 TexSharpenPass(float4 color, float2 texcoord) #endif /*------------------------------------------------------------------------------ - [VIBRANCE CODE SECTION] + [PIXEL VIBRANCE CODE SECTION] ------------------------------------------------------------------------------*/ -#if (PIXEL_VIBRANCE == 1) +#if PIXEL_VIBRANCE == 1 float4 VibrancePass(float4 color, float2 texcoord) { - #if (GLSL == 1) + float vib = Vibrance; + + #if GLSL == 1 float3 luma = float3(AvgLuminance(color.rgb)); #else float luma = AvgLuminance(color.rgb); @@ -1032,8 +1110,9 @@ float4 VibrancePass(float4 color, float2 texcoord) float colorMin = min(color.r, min(color.g, color.b)); float colorSaturation = colorMax - colorMin; + float3 colorCoeff = float3(RedVibrance * vib, GreenVibrance * vib, BlueVibrance * vib); - color.rgb = lerp(luma, color.rgb, (1.0 + (Vibrance * (1.0 - (sign(Vibrance) * colorSaturation))))); + color.rgb = lerp(luma, color.rgb, (1.0 + (colorCoeff * (1.0 - (sign(colorCoeff) * colorSaturation))))); color.a = AvgLuminance(color.rgb); return saturate(color); //Debug: return colorSaturation.xxxx; @@ -1044,111 +1123,122 @@ float4 VibrancePass(float4 color, float2 texcoord) [BLENDED BLOOM CODE SECTION] ------------------------------------------------------------------------------*/ -#if (BLENDED_BLOOM == 1) -float3 BlendAddLight(in float3 color, in float3 bloom) +#if BLENDED_BLOOM == 1 +float3 BlendAddLight(float3 bloom, float3 blend) { - return saturate(color + bloom); + return saturate(bloom + blend); } -float3 BlendScreen(in float3 color, in float3 bloom) +float3 BlendScreen(float3 bloom, float3 blend) { - return (color + bloom) - (color * bloom); + return (bloom + blend) - (bloom * blend); } -float3 BlendLuma(in float3 color, in float3 bloom) +float3 BlendAddGlow(float3 bloom, float3 blend) { - float lumavg = AvgLuminance(color + bloom); - return lerp((color * bloom), (1.0 - ((1.0 - color) * (1.0 - bloom))), lumavg); + float glow = smootherstep(0.0, 1.0, AvgLuminance(bloom)); + return lerp(saturate(bloom + blend), + (blend + blend) - (blend * blend), glow); } -float3 BlendGlow(in float3 color, in float3 bloom) +float3 BlendGlow(float3 bloom, float3 blend) { - float glow = smoothstep(0.0, 1.0, AvgLuminance(color.rgb)); - return lerp((color + bloom) - (color * bloom), (bloom + bloom) - (bloom * bloom), glow); + float glow = smootherstep(0.0, 1.0, AvgLuminance(bloom)); + return lerp((bloom + blend) - (bloom * blend), + (blend + blend) - (blend * blend), glow); } -float3 BlendOverlay(in float3 color, in float3 bloom) +float3 BlendLuma(float3 bloom, float3 blend) { - float3 overlay = step(0.5, color); - overlay = lerp((color * bloom * 2.0), (1.0 - (2.0 * (1.0 - color) * (1.0 - bloom))), overlay); - - return overlay; + float lumavg = smootherstep(0.0, 1.0, AvgLuminance(bloom + blend)); + return lerp((bloom * blend), (1.0 - + ((1.0 - bloom) * (1.0 - blend))), lumavg); } -float4 PyramidFilter(in SamplerState tex, in float2 texcoord, in float2 width) +float3 BlendOverlay(float3 bloom, float3 blend) { - float4 color = sample_tex(tex, texcoord + float2(0.5, 0.5) * width); - color += sample_tex(tex, texcoord + float2(-0.5, 0.5) * width); - color += sample_tex(tex, texcoord + float2(0.5, -0.5) * width); - color += sample_tex(tex, texcoord + float2(-0.5, -0.5) * width); - color *= 0.25; + float3 overlay = step(0.5, bloom); + return lerp((bloom * blend * 2.0), (1.0 - (2.0 * + (1.0 - bloom) * (1.0 - blend))), overlay); +} - return color; +float4 PyramidFilter(sampler tex, float2 texcoord, float2 width) +{ + float4 X = sample_tex(tex, texcoord + float2(0.5, 0.5) * width); + float4 Y = sample_tex(tex, texcoord + float2(-0.5, 0.5) * width); + float4 Z = sample_tex(tex, texcoord + float2(0.5, -0.5) * width); + float4 W = sample_tex(tex, texcoord + float2(-0.5, -0.5) * width); + + return (X + Y + Z + W) / 4.0; } float3 BloomCorrection(float3 color) { - float X = 1.0 / (1.0 + exp(float(BloomReds) / 2.0)); - float Y = 1.0 / (1.0 + exp(float(BloomGreens) / 2.0)); - float Z = 1.0 / (1.0 + exp(float(BloomBlues) / 2.0)); + float3 bloom = color; - color.r = (1.0 / (1.0 + exp(float(-BloomReds) * (color.r - 0.5))) - X) / (1.0 - 2.0 * X); - color.g = (1.0 / (1.0 + exp(float(-BloomGreens) * (color.g - 0.5))) - Y) / (1.0 - 2.0 * Y); - color.b = (1.0 / (1.0 + exp(float(-BloomBlues) * (color.b - 0.5))) - Z) / (1.0 - 2.0 * Z); + bloom.r = 2.0 / 3.0 * (1.0 - (bloom.r * bloom.r)); + bloom.g = 2.0 / 3.0 * (1.0 - (bloom.g * bloom.g)); + bloom.b = 2.0 / 3.0 * (1.0 - (bloom.b * bloom.b)); + + bloom.r = saturate(color.r + float(BloomReds) * bloom.r); + bloom.g = saturate(color.g + float(BloomGreens) * bloom.g); + bloom.b = saturate(color.b + float(BloomBlues) * bloom.b); + + color = saturate(bloom); return color; } float4 BloomPass(float4 color, float2 texcoord) { - float defocus = 1.25; - float anflare = 4.00; + float anflare = 4.0; - float4 bloom = PyramidFilter(TextureSampler, texcoord, invDefocus * defocus); + float2 defocus = float2(BloomDefocus, BloomDefocus); + float4 bloom = PyramidFilter(TextureSampler, texcoord, pixelSize * defocus); - float2 dx = float2(invDefocus.x * float(BloomWidth), 0.0); - float2 dy = float2(0.0, invDefocus.y * float(BloomWidth)); + float2 dx = float2(pixelSize.x * float(BloomWidth), 0.0); + float2 dy = float2(0.0, pixelSize.y * float(BloomWidth)); - float2 mdx = mul(2.0, dx); - float2 mdy = mul(2.0, dy); + float2 mdx = mul(dx, 2.0); + float2 mdy = mul(dy, 2.0); - float4 bloomBlend = bloom * 0.22520613262190495; + float4 blend = bloom * 0.22520613262190495; - bloomBlend += 0.002589001911021066 * sample_tex(TextureSampler, texcoord - mdx + mdy); - bloomBlend += 0.010778807494659370 * sample_tex(TextureSampler, texcoord - dx + mdy); - bloomBlend += 0.024146616900339800 * sample_tex(TextureSampler, texcoord + mdy); - bloomBlend += 0.010778807494659370 * sample_tex(TextureSampler, texcoord + dx + mdy); - bloomBlend += 0.002589001911021066 * sample_tex(TextureSampler, texcoord + mdx + mdy); + blend += 0.002589001911021066 * sample_tex(TextureSampler, texcoord - mdx + mdy); + blend += 0.010778807494659370 * sample_tex(TextureSampler, texcoord - dx + mdy); + blend += 0.024146616900339800 * sample_tex(TextureSampler, texcoord + mdy); + blend += 0.010778807494659370 * sample_tex(TextureSampler, texcoord + dx + mdy); + blend += 0.002589001911021066 * sample_tex(TextureSampler, texcoord + mdx + mdy); - bloomBlend += 0.010778807494659370 * sample_tex(TextureSampler, texcoord - mdx + dy); - bloomBlend += 0.044875475183061630 * sample_tex(TextureSampler, texcoord - dx + dy); - bloomBlend += 0.100529757860782610 * sample_tex(TextureSampler, texcoord + dy); - bloomBlend += 0.044875475183061630 * sample_tex(TextureSampler, texcoord + dx + dy); - bloomBlend += 0.010778807494659370 * sample_tex(TextureSampler, texcoord + mdx + dy); + blend += 0.010778807494659370 * sample_tex(TextureSampler, texcoord - mdx + dy); + blend += 0.044875475183061630 * sample_tex(TextureSampler, texcoord - dx + dy); + blend += 0.100529757860782610 * sample_tex(TextureSampler, texcoord + dy); + blend += 0.044875475183061630 * sample_tex(TextureSampler, texcoord + dx + dy); + blend += 0.010778807494659370 * sample_tex(TextureSampler, texcoord + mdx + dy); - bloomBlend += 0.024146616900339800 * sample_tex(TextureSampler, texcoord - mdx); - bloomBlend += 0.100529757860782610 * sample_tex(TextureSampler, texcoord - dx); - bloomBlend += 0.100529757860782610 * sample_tex(TextureSampler, texcoord + dx); - bloomBlend += 0.024146616900339800 * sample_tex(TextureSampler, texcoord + mdx); + blend += 0.024146616900339800 * sample_tex(TextureSampler, texcoord - mdx); + blend += 0.100529757860782610 * sample_tex(TextureSampler, texcoord - dx); + blend += 0.100529757860782610 * sample_tex(TextureSampler, texcoord + dx); + blend += 0.024146616900339800 * sample_tex(TextureSampler, texcoord + mdx); - bloomBlend += 0.010778807494659370 * sample_tex(TextureSampler, texcoord - mdx - dy); - bloomBlend += 0.044875475183061630 * sample_tex(TextureSampler, texcoord - dx - dy); - bloomBlend += 0.100529757860782610 * sample_tex(TextureSampler, texcoord - dy); - bloomBlend += 0.044875475183061630 * sample_tex(TextureSampler, texcoord + dx - dy); - bloomBlend += 0.010778807494659370 * sample_tex(TextureSampler, texcoord + mdx - dy); + blend += 0.010778807494659370 * sample_tex(TextureSampler, texcoord - mdx - dy); + blend += 0.044875475183061630 * sample_tex(TextureSampler, texcoord - dx - dy); + blend += 0.100529757860782610 * sample_tex(TextureSampler, texcoord - dy); + blend += 0.044875475183061630 * sample_tex(TextureSampler, texcoord + dx - dy); + blend += 0.010778807494659370 * sample_tex(TextureSampler, texcoord + mdx - dy); - bloomBlend += 0.002589001911021066 * sample_tex(TextureSampler, texcoord - mdx - mdy); - bloomBlend += 0.010778807494659370 * sample_tex(TextureSampler, texcoord - dx - mdy); - bloomBlend += 0.024146616900339800 * sample_tex(TextureSampler, texcoord - mdy); - bloomBlend += 0.010778807494659370 * sample_tex(TextureSampler, texcoord + dx - mdy); - bloomBlend += 0.002589001911021066 * sample_tex(TextureSampler, texcoord + mdx - mdy); - bloomBlend = lerp(color, bloomBlend, float(BlendStrength)); + blend += 0.002589001911021066 * sample_tex(TextureSampler, texcoord - mdx - mdy); + blend += 0.010778807494659370 * sample_tex(TextureSampler, texcoord - dx - mdy); + blend += 0.024146616900339800 * sample_tex(TextureSampler, texcoord - mdy); + blend += 0.010778807494659370 * sample_tex(TextureSampler, texcoord + dx - mdy); + blend += 0.002589001911021066 * sample_tex(TextureSampler, texcoord + mdx - mdy); + blend = lerp(color, blend, float(BlendStrength)); - bloom.rgb = BloomType(bloom.rgb, bloomBlend.rgb); - bloom.rgb = BloomCorrection(bloom.rgb); + bloom.xyz = BloomType(bloom.xyz, blend.xyz); + bloom.xyz = BloomCorrection(bloom.xyz); - color.a = AvgLuminance(color.rgb); - bloom.a = AvgLuminance(bloom.rgb); + color.a = AvgLuminance(color.xyz); + bloom.a = AvgLuminance(bloom.xyz); bloom.a *= anflare; color = lerp(color, bloom, float(BloomStrength)); @@ -1156,163 +1246,314 @@ float4 BloomPass(float4 color, float2 texcoord) return color; } #endif + /*------------------------------------------------------------------------------ - [COLOR CORRECTION/TONE MAPPING CODE SECTION] + [SCENE TONE MAPPING CODE SECTION] ------------------------------------------------------------------------------*/ -float4 ScaleBlk(in float4 color) +#if SCENE_TONEMAPPING == 1 +float3 FilmicCurve(float3 color) { - color = float4(color.rgb * pow(abs(max(color.r, - max(color.g, color.b))), float(BlackLevels)), color.a); - + float3 T = color; + float tnamn = ToneAmount; + + float A = 0.100; + float B = 0.300; + float C = 0.100; + float D = tnamn; + float E = 0.020; + float F = 0.300; + float W = 1.012; + + T.r = ((T.r*(A*T.r + C*B) + D*E) / (T.r*(A*T.r + B) + D*F)) - E / F; + T.g = ((T.g*(A*T.g + C*B) + D*E) / (T.g*(A*T.g + B) + D*F)) - E / F; + T.b = ((T.b*(A*T.b + C*B) + D*E) / (T.b*(A*T.b + B) + D*F)) - E / F; + + float denom = ((W*(A*W + C*B) + D*E) / (W*(A*W + B) + D*F)) - E / F; + float3 white = float3(denom, denom, denom); + + T = T / white; + color = saturate(T); + return color; } -float3 FilmicTonemap(in float3 color) +float3 FilmicTonemap(float3 color) { - float3 Q = color.xyz; + float3 tone = color; - float A = 0.10; - float B = 0.30; - float C = 0.10; - float D = float(ToneAmount); - float E = 0.02; - float F = 0.30; - float W = float(WhitePoint); + float3 black = float3(0.0, 0.0, 0.0); + tone = max(black, tone); - float3 numerator = ((Q*(A*Q + C*B) + D*E) / (Q*(A*Q + B) + D*F)) - E / F; - float denominator = ((W*(A*W + C*B) + D*E) / (W*(A*W + B) + D*F)) - E / F; + tone.r = (tone.r * (6.2 * tone.r + 0.5)) / (tone.r * (6.2 * tone.r + 1.66) + 0.066); + tone.g = (tone.g * (6.2 * tone.g + 0.5)) / (tone.g * (6.2 * tone.g + 1.66) + 0.066); + tone.b = (tone.b * (6.2 * tone.b + 0.5)) / (tone.b * (6.2 * tone.b + 1.66) + 0.066); - color.xyz = numerator / denominator; + static const float gamma = 2.42; + tone = EncodeGamma(tone, gamma); - return saturate(color); -} + color = lerp(color, tone, float(FilmStrength)); -float3 CrossShift(in float3 color) -{ - float3 colMood; - - float2 CrossMatrix[3] = { - float2 (0.96, 0.04), - float2 (0.99, 0.01), - float2 (0.97, 0.03), }; - - colMood.r = float(RedShift) * CrossMatrix[0].x + CrossMatrix[0].y; - colMood.g = float(GreenShift) * CrossMatrix[1].x + CrossMatrix[1].y; - colMood.b = float(BlueShift) * CrossMatrix[2].x + CrossMatrix[2].y; - - float fLum = AvgLuminance(color.rgb); - - #if (GLSL == 1) - colMood = lerp(float3(0.0), colMood, saturate(fLum * 2.0)); - colMood = lerp(colMood, float3(1.0), saturate(fLum - 0.5) * 2.0); - #else - colMood = lerp(0.0, colMood, saturate(fLum * 2.0)); - colMood = lerp(colMood, 1.0, saturate(fLum - 0.5) * 2.0); - #endif - float3 colOutput = lerp(color, colMood, saturate(fLum * float(ShiftRatio))); - - return colOutput; -} - -float3 ColorCorrection(float3 color) -{ - float X = 1.0 / (1.0 + exp(float(RedCurve) / 2.0)); - float Y = 1.0 / (1.0 + exp(float(GreenCurve) / 2.0)); - float Z = 1.0 / (1.0 + exp(float(BlueCurve) / 2.0)); - - color.r = (1.0 / (1.0 + exp(float(-RedCurve) * (color.r - 0.5))) - X) / (1.0 - 2.0 * X); - color.g = (1.0 / (1.0 + exp(float(-GreenCurve) * (color.g - 0.5))) - Y) / (1.0 - 2.0 * Y); - color.b = (1.0 / (1.0 + exp(float(-BlueCurve) * (color.b - 0.5))) - Z) / (1.0 - 2.0 * Z); - - return saturate(color); + return color; } float4 TonemapPass(float4 color, float2 texcoord) { - const float delta = 0.001; - const float wpoint = pow(1.002, 2.0); + float luminanceAverage = AvgLuminance(Luminance); + float bmax = max(color.r, max(color.g, color.b)); + + float blevel = pow(saturate(bmax), float(BlackLevels)); + color.rgb = color.rgb * blevel; - color = ScaleBlk(color); - - if (CorrectionPalette == 1) { color.rgb = ColorCorrection(color.rgb); } - if (FilmicProcess == 1) { color.rgb = CrossShift(color.rgb); } - if (TonemapType == 1) { color.rgb = FilmicTonemap(color.rgb); } + if (FilmOperator == 1) { color.rgb = FilmicTonemap(color.rgb); } + if (TonemapType == 1) { color.rgb = FilmicCurve(color.rgb); } // RGB -> XYZ conversion - #if (GLSL == 1) - // GLSL is column major whereas HLSL is row major ... - const mat3 RGB2XYZ = mat3 ( 0.4124564, 0.2126729, 0.0193339, // first column (not row) - 0.3575761, 0.7151522, 0.1191920, // 2nd column - 0.1804375, 0.0721750, 0.9503041 ); // 3rd column - #else - static const float3x3 RGB2XYZ = { 0.4124564, 0.3575761, 0.1804375, + const float3x3 RGB2XYZ = float3x3(0.4124564, 0.3575761, 0.1804375, 0.2126729, 0.7151522, 0.0721750, - 0.0193339, 0.1191920, 0.9503041 }; - #endif + 0.0193339, 0.1191920, 0.9503041); - #if (GLSL == 1) - float3 XYZ = RGB2XYZ * color.rgb; - #else float3 XYZ = mul(RGB2XYZ, color.rgb); - #endif // XYZ -> Yxy conversion float3 Yxy; - Yxy.r = XYZ.g; // copy luminance Y - Yxy.g = XYZ.r / (XYZ.r + XYZ.g + XYZ.b); // x = X / (X + Y + Z) - Yxy.b = XYZ.g / (XYZ.r + XYZ.g + XYZ.b); // y = Y / (X + Y + Z) + Yxy.r = XYZ.g; // copy luminance Y + Yxy.g = XYZ.r / (XYZ.r + XYZ.g + XYZ.b); // x = X / (X + Y + Z) + Yxy.b = XYZ.g / (XYZ.r + XYZ.g + XYZ.b); // y = Y / (X + Y + Z) - if (CorrectionPalette == 2) { Yxy.rgb = ColorCorrection(Yxy.rgb); } - if (TonemapType == 2) { Yxy.r = FilmicTonemap(Yxy.rgb).r; } + // (Wt) Tone mapped scaling of the initial wp before input modifiers + float Wt = saturate(Yxy.r / AvgLuminance(XYZ)); + + if (TonemapType == 2) { Yxy.r = FilmicCurve(Yxy).r; } // (Lp) Map average luminance to the middlegrey zone by scaling pixel luminance - float Lp = Yxy.r * float(Exposure) / (float(Luminance) + delta); + float Lp = Yxy.r * float(Exposure) / (luminanceAverage + Epsilon); + + // (Wp) White point calculated, based on the toned white, and input modifier + float Wp = dot(abs(Wt), float(WhitePoint)); // (Ld) Scale all luminance within a displayable range of 0 to 1 - Yxy.r = (Lp * (1.0 + Lp / wpoint)) / (1.0 + Lp); + Yxy.r = (Lp * (1.0 + Lp / (Wp * Wp))) / (1.0 + Lp); // Yxy -> XYZ conversion XYZ.r = Yxy.r * Yxy.g / Yxy.b; // X = Y * x / y XYZ.g = Yxy.r; // copy luminance Y XYZ.b = Yxy.r * (1.0 - Yxy.g - Yxy.b) / Yxy.b; // Z = Y * (1-x-y) / y - if (CorrectionPalette == 3) { XYZ.rgb = ColorCorrection(XYZ.rgb); } - // XYZ -> RGB conversion - #if (GLSL == 1) - // GLSL is column major whereas HLSL is row major ... - const mat3 XYZ2RGB = mat3 ( 3.2404542, -0.9692660, 0.0556434, // first column (not row) - -1.5371385, 1.8760108, -0.2040259, // 2nd column - -0.4985314, 0.0415560, 1.0572252 ); // 3rd column - #else - static const float3x3 XYZ2RGB = { 3.2404542,-1.5371385,-0.4985314, + const float3x3 XYZ2RGB = float3x3(3.2404542,-1.5371385,-0.4985314, -0.9692660, 1.8760108, 0.0415560, - 0.0556434,-0.2040259, 1.0572252 }; - #endif + 0.0556434,-0.2040259, 1.0572252); - #if (GLSL == 1) - color.rgb = XYZ2RGB * XYZ; - #else color.rgb = mul(XYZ2RGB, XYZ); - #endif color.a = AvgLuminance(color.rgb); return color; } +#endif + +/*------------------------------------------------------------------------------ + [CROSS PROCESSING CODE SECTION] +------------------------------------------------------------------------------*/ + +#if CROSS_PROCESSING == 1 +float MidLuminance(float3 color) +{ + return sqrt( + (color.x * color.x * 0.3333) + + (color.y * color.y * 0.3333) + + (color.z * color.z * 0.3333)); +} + +float3 CrossShift(float3 color) +{ + float3 cross; + + float2 CrossMatrix[3] = { + float2 (0.960, 0.040 * color.x), + float2 (0.980, 0.020 * color.y), + float2 (0.970, 0.030 * color.z), }; + + cross.x = float(RedShift) * CrossMatrix[0].x + CrossMatrix[0].y; + cross.y = float(GreenShift) * CrossMatrix[1].x + CrossMatrix[1].y; + cross.z = float(BlueShift) * CrossMatrix[2].x + CrossMatrix[2].y; + + float lum = MidLuminance(color); + float3 black = float3(0.0, 0.0, 0.0); + float3 white = float3(1.0, 1.0, 1.0); + + cross = lerp(black, cross, saturate(lum * 2.0)); + cross = lerp(cross, white, saturate(lum - 0.5) * 2.0); + color = lerp(color, cross, saturate(lum * float(ShiftRatio))); + + return color; +} + +float4 CrossPass(float4 color, float2 texcoord) +{ + #if FilmicProcess == 1 + color.rgb = CrossShift(color.rgb); + + #elif FilmicProcess == 2 + float3 XYZ = RGBtoXYZ(color.rgb); + float3 Yxy = XYZtoYxy(XYZ); + + Yxy = CrossShift(Yxy); + XYZ = YxytoXYZ(Yxy); + + color.rgb = XYZtoRGB(XYZ); + + #elif FilmicProcess == 3 + float3 XYZ = RGBtoXYZ(color.rgb); + float3 Yxy = XYZtoYxy(XYZ); + + XYZ = YxytoXYZ(Yxy); + XYZ = CrossShift(XYZ); + + color.rgb = XYZtoRGB(XYZ); + #endif + + color.a = AvgLuminance(color.rgb); + + return saturate(color); +} +#endif + +/*------------------------------------------------------------------------------ + [COLOR CORRECTION CODE SECTION] +------------------------------------------------------------------------------*/ + +// Converting pure hue to RGB +float3 HUEtoRGB(float H) +{ + float R = abs(H * 6.0 - 3.0) - 1.0; + float G = 2.0 - abs(H * 6.0 - 2.0); + float B = 2.0 - abs(H * 6.0 - 4.0); + + return saturate(float3(R, G, B)); +} + +// Converting RGB to hue/chroma/value +float3 RGBtoHCV(float3 RGB) +{ + float4 BG = float4(RGB.bg,-1.0, 2.0 / 3.0); + float4 GB = float4(RGB.gb, 0.0,-1.0 / 3.0); + + float4 P = (RGB.g < RGB.b) ? BG : GB; + + float4 XY = float4(P.xyw, RGB.r); + float4 YZ = float4(RGB.r, P.yzx); + + float4 Q = (RGB.r < P.x) ? XY : YZ; + + float C = Q.x - min(Q.w, Q.y); + float H = abs((Q.w - Q.y) / (6.0 * C + Epsilon) + Q.z); + + return float3(H, C, Q.x); +} + +// Converting RGB to HSV +float3 RGBtoHSV(float3 RGB) +{ + float3 HCV = RGBtoHCV(RGB); + float S = HCV.y / (HCV.z + Epsilon); + + return float3(HCV.x, S, HCV.z); +} + +// Converting HSV to RGB +float3 HSVtoRGB(float3 HSV) +{ + float3 RGB = HUEtoRGB(HSV.x); + return ((RGB - 1.0) * HSV.y + 1.0) * HSV.z; +} + +#if COLOR_CORRECTION == 1 +// Pre correction color mask +float3 PreCorrection(float3 color) +{ + float3 RGB = color; + + RGB.r = 2.0 / 3.0 * (1.0 - (RGB.r * RGB.r)); + RGB.g = 2.0 / 3.0 * (1.0 - (RGB.g * RGB.g)); + RGB.b = 2.0 / 3.0 * (1.0 - (RGB.b * RGB.b)); + + RGB.r = saturate(color.r + (float(ChannelR) / 200.0) * RGB.r); + RGB.g = saturate(color.g + (float(ChannelG) / 200.0) * RGB.g); + RGB.b = saturate(color.b + (float(ChannelB) / 200.0) * RGB.b); + + color = saturate(RGB); + + return color; +} + +float3 ColorCorrection(float3 color) +{ + float X = 1.0 / (1.0 + exp(float(ChannelR) / 2.0)); + float Y = 1.0 / (1.0 + exp(float(ChannelG) / 2.0)); + float Z = 1.0 / (1.0 + exp(float(ChannelB) / 2.0)); + + color.r = (1.0 / (1.0 + exp(float(-ChannelR) * (color.r - 0.5))) - X) / (1.0 - 2.0 * X); + color.g = (1.0 / (1.0 + exp(float(-ChannelG) * (color.g - 0.5))) - Y) / (1.0 - 2.0 * Y); + color.b = (1.0 / (1.0 + exp(float(-ChannelB) * (color.b - 0.5))) - Z) / (1.0 - 2.0 * Z); + + return saturate(color); +} + +float4 CorrectionPass(float4 color, float2 texcoord) +{ + float3 colorspace = PreCorrection(color.rgb); + + #if CorrectionPalette == 1 + colorspace = ColorCorrection(colorspace); + + #elif CorrectionPalette == 2 + float3 XYZ = RGBtoXYZ(colorspace); + float3 Yxy = XYZtoYxy(XYZ); + + Yxy = ColorCorrection(Yxy); + XYZ = YxytoXYZ(Yxy); + colorspace = XYZtoRGB(XYZ); + + #elif CorrectionPalette == 3 + float3 XYZ = RGBtoXYZ(colorspace); + float3 Yxy = XYZtoYxy(XYZ); + + XYZ = YxytoXYZ(Yxy); + XYZ = ColorCorrection(XYZ); + colorspace = XYZtoRGB(XYZ); + + #elif CorrectionPalette == 4 + float3 hsv = RGBtoHSV(colorspace); + hsv = ColorCorrection(hsv); + colorspace = HSVtoRGB(hsv); + + #elif CorrectionPalette == 5 + float3 yuv = RGBtoYUV(colorspace); + yuv = ColorCorrection(yuv); + colorspace = YUVtoRGB(yuv); + #endif + + color.rgb = lerp(color.rgb, colorspace, float(PaletteStrength)); + color.a = AvgLuminance(color.rgb); + + return color; +} +#endif + /*------------------------------------------------------------------------------ [S-CURVE CONTRAST CODE SECTION] ------------------------------------------------------------------------------*/ -#if (S_CURVE_CONTRAST == 1) +#if CURVE_CONTRAST == 1 float4 ContrastPass(float4 color, float2 texcoord) { float CurveBlend = CurvesContrast; - #if (CurveType != 2) - #if (GLSL == 1) + #if CurveType != 2 + #if GLSL == 1 float3 luma = float3(AvgLuminance(color.rgb)); #else float3 luma = (float3)AvgLuminance(color.rgb); @@ -1320,7 +1561,7 @@ float4 ContrastPass(float4 color, float2 texcoord) float3 chroma = color.rgb - luma; #endif - #if (CurveType == 2) + #if CurveType == 2 float3 x = color.rgb; #elif (CurveType == 1) float3 x = chroma; @@ -1344,7 +1585,7 @@ float4 ContrastPass(float4 color, float2 texcoord) x = dest; - #if (CurveType == 0) //Only Luma + #if CurveType == 0 //Only Luma x = lerp(luma, x, CurveBlend); color.rgb = x + chroma; #elif (CurveType == 1) //Only Chroma @@ -1363,47 +1604,11 @@ float4 ContrastPass(float4 color, float2 texcoord) #endif /*------------------------------------------------------------------------------ - [CEL SHADING CODE SECTION] + [CEL SHADING CODE SECTION] ------------------------------------------------------------------------------*/ -#if (CEL_SHADING == 1) -float3 GetYUV(float3 RGB) -{ - #if (GLSL == 1) - const mat3 RGB2YUV = mat3(0.2126, 0.7152, 0.0722, - -0.09991,-0.33609, 0.436, - 0.615, -0.55861, -0.05639); - - return (RGB * RGB2YUV); - #else - const float3x3 RGB2YUV = { 0.2126, 0.7152, 0.0722, - -0.09991,-0.33609, 0.436, - 0.615, -0.55861, -0.05639 }; - - return mul(RGB2YUV, RGB); - - #endif -} - -float3 GetRGB(float3 YUV) -{ - #if (GLSL == 1) - const mat3 YUV2RGB = mat3(1.000, 0.000, 1.28033, - 1.000,-0.21482,-0.38059, - 1.000, 2.12798, 0.000); - - return (YUV * YUV2RGB); - #else - const float3x3 YUV2RGB = { 1.000, 0.000, 1.28033, - 1.000,-0.21482,-0.38059, - 1.000, 2.12798, 0.000 }; - - return mul(YUV2RGB, YUV); - - #endif -} - -float4 CelPass(float4 color, float2 texcoord) +#if CEL_SHADING == 1 +float4 CelPass(float4 color, float2 uv0) { float3 yuv; float3 sum = color.rgb; @@ -1427,44 +1632,44 @@ float4 CelPass(float4 color, float2 texcoord) for (int i = 0; i < NUM; i++) { - col[i] = sample_tex(TextureSampler, texcoord + set[i] * RoundingOffset).rgb; + col[i] = sample_tex(TextureSampler, uv0 + set[i] * RoundingOffset).rgb; - #if (ColorRounding == 1) + #if ColorRounding == 1 col[i].r = round(col[i].r * thresholds.r) / thresholds.r; col[i].g = round(col[i].g * thresholds.g) / thresholds.g; col[i].b = round(col[i].b * thresholds.b) / thresholds.b; #endif lum[i] = AvgLuminance(col[i].xyz); - yuv = GetYUV(col[i]); + yuv = RGBtoYUV(col[i]); - #if (UseYuvLuma == 0) + #if UseYuvLuma == 0 yuv.r = round(yuv.r * thresholds.r) / thresholds.r; #else yuv.r = saturate(round(yuv.r * lum[i]) / thresholds.r + lum[i]); #endif - yuv = GetRGB(yuv); + yuv = YUVtoRGB(yuv); sum += yuv; } float3 shadedColor = (sum / NUM); float2 pixel = float2(pixelSize.x * EdgeThickness, pixelSize.y * EdgeThickness); - float edgeX = dot(sample_tex(TextureSampler, texcoord + pixel).rgb, lumCoeff); - edgeX = dot(float4(sample_tex(TextureSampler, texcoord - pixel).rgb, edgeX), float4(lumCoeff, -1.0)); + float edgeX = dot(sample_tex(TextureSampler, uv0 + pixel).rgb, lumCoeff); + edgeX = dot(float4(sample_tex(TextureSampler, uv0 - pixel).rgb, edgeX), float4(lumCoeff, -1.0)); - float edgeY = dot(sample_tex(TextureSampler, texcoord + float2(pixel.x, -pixel.y)).rgb, lumCoeff); - edgeY = dot(float4(sample_tex(TextureSampler, texcoord + float2(-pixel.x, pixel.y)).rgb, edgeY), float4(lumCoeff, -1.0)); + float edgeY = dot(sample_tex(TextureSampler, uv0 + float2(pixel.x, -pixel.y)).rgb, lumCoeff); + edgeY = dot(float4(sample_tex(TextureSampler, uv0 + float2(-pixel.x, pixel.y)).rgb, edgeY), float4(lumCoeff, -1.0)); float edge = dot(float2(edgeX, edgeY), float2(edgeX, edgeY)); - #if (PaletteType == 1) - color.rgb = lerp(color.rgb, color.rgb + pow(edge, EdgeFilter) * -EdgeStrength, EdgeStrength); + #if PaletteType == 1 + color.rgb = lerp(color.rgb, color.rgb + pow(edge, EdgeFilter) * -EdgeStrength, EdgeStrength); #elif (PaletteType == 2) - color.rgb = lerp(color.rgb + pow(edge, EdgeFilter) * -EdgeStrength, shadedColor, 0.30); + color.rgb = lerp(color.rgb + pow(edge, EdgeFilter) * -EdgeStrength, shadedColor, 0.25); #elif (PaletteType == 3) - color.rgb = lerp(shadedColor + edge * -EdgeStrength, pow(edge, EdgeFilter) * -EdgeStrength + color.rgb, 0.5); + color.rgb = lerp(shadedColor + edge * -EdgeStrength, pow(edge, EdgeFilter) * -EdgeStrength + color.rgb, 0.5); #endif color.a = AvgLuminance(color.rgb); @@ -1473,11 +1678,127 @@ float4 CelPass(float4 color, float2 texcoord) } #endif +/*------------------------------------------------------------------------------ + [PAINT SHADING CODE SECTION] +------------------------------------------------------------------------------*/ + +#if PAINT_SHADING == 1 +float3 PaintShading(float3 color, float2 texcoord) +{ + #if PaintMethod == 1 + float2 tex; + int k, j, lum, cmax = 0; + + float C0, C1, C2, C3, C4, C5, C6, C7, C8, C9; + float3 A, B, C, D, E, F, G, H, I, J, shade; + + for (k = int(-PaintRadius); k < (int(PaintRadius) + 1); k++){ + for (j = int(-PaintRadius); j < (int(PaintRadius) + 1); j++){ + + tex.x = texcoord.x + pixelSize.x * k; + tex.y = texcoord.y + pixelSize.y * j; + + shade = sample_tex(TextureSampler, tex).xyz; + + lum = AvgLuminance(shade) * 9.0; + + C0 = (lum == 0) ? C0 + 1 : C0; + C1 = (lum == 1) ? C1 + 1 : C1; + C2 = (lum == 2) ? C2 + 1 : C2; + C3 = (lum == 3) ? C3 + 1 : C3; + C4 = (lum == 4) ? C4 + 1 : C4; + C5 = (lum == 5) ? C5 + 1 : C5; + C6 = (lum == 6) ? C6 + 1 : C6; + C7 = (lum == 7) ? C7 + 1 : C7; + C8 = (lum == 8) ? C8 + 1 : C8; + C9 = (lum == 9) ? C9 + 1 : C9; + + A = (lum == 0) ? A + shade : A; + B = (lum == 1) ? B + shade : B; + C = (lum == 2) ? C + shade : C; + D = (lum == 3) ? D + shade : D; + E = (lum == 4) ? E + shade : E; + F = (lum == 5) ? F + shade : F; + G = (lum == 6) ? G + shade : G; + H = (lum == 7) ? H + shade : H; + I = (lum == 8) ? I + shade : I; + J = (lum == 9) ? J + shade : J; + }} + + if (C0 > cmax){ cmax = C0; color.xyz = A / cmax; } + if (C1 > cmax){ cmax = C1; color.xyz = B / cmax; } + if (C2 > cmax){ cmax = C2; color.xyz = C / cmax; } + if (C3 > cmax){ cmax = C3; color.xyz = D / cmax; } + if (C4 > cmax){ cmax = C4; color.xyz = E / cmax; } + if (C5 > cmax){ cmax = C5; color.xyz = F / cmax; } + if (C6 > cmax){ cmax = C6; color.xyz = G / cmax; } + if (C7 > cmax){ cmax = C7; color.xyz = H / cmax; } + if (C8 > cmax){ cmax = C8; color.xyz = I / cmax; } + if (C9 > cmax){ cmax = C9; color.xyz = J / cmax; } + + #else + int j, i; + + float3 m0, m1, m2, m3, k0, k1, k2, k3, shade; + float n = float((PaintRadius + 1.0) * (PaintRadius + 1.0)); + + for (j = int(-PaintRadius); j <= 0; ++j) { + for (i = int(-PaintRadius); i <= 0; ++i) { + + shade = sample_tex(TextureSampler, texcoord + float2(i, j) / screenSize).rgb; + m0 += shade; k0 += shade * shade; }} + + for (j = int(-PaintRadius); j <= 0; ++j) { + for (i = 0; i <= int(PaintRadius); ++i) { + shade = sample_tex(TextureSampler, texcoord + float2(i, j) / screenSize).rgb; + m1 += shade; k1 += shade * shade; }} + + for (j = 0; j <= int(PaintRadius); ++j) { + for (i = 0; i <= int(PaintRadius); ++i) { + shade = sample_tex(TextureSampler, texcoord + float2(i, j) / screenSize).rgb; + m2 += shade; k2 += shade * shade; }} + + float min_sigma2 = 1e+2; + m0 /= n; k0 = abs(k0 / n - m0 * m0); + + float sigma2 = k0.r + k0.g + k0.b; + if (sigma2 < min_sigma2) { + min_sigma2 = sigma2; color = m0; } + + m1 /= n; k1 = abs(k1 / n - m1 * m1); + sigma2 = k1.r + k1.g + k1.b; + + if (sigma2 < min_sigma2) { + min_sigma2 = sigma2; + color = m1; } + + m2 /= n; k2 = abs(k2 / n - m2 * m2); + sigma2 = k2.r + k2.g + k2.b; + + if (sigma2 < min_sigma2) { + min_sigma2 = sigma2; + color = m2; } + #endif + + return color; +} + +float4 PaintPass(float4 color, float2 texcoord) +{ + float3 paint = PaintShading(color.rgb, texcoord); + color.rgb = lerp(color.rgb, paint, float(PaintStrength)); + color.a = AvgLuminance(color.rgb); + + return color; +} +#endif + + /*------------------------------------------------------------------------------ [COLOR GRADING CODE SECTION] ------------------------------------------------------------------------------*/ -#if (COLOR_GRADING == 1) +#if COLOR_GRADING == 1 float RGBCVtoHUE(float3 RGB, float C, float V) { float3 Delta = (V - RGB) / C; @@ -1491,37 +1812,6 @@ float RGBCVtoHUE(float3 RGB, float C, float V) return frac(H / 6); } -float3 RGBtoHSV(float3 RGB) -{ - float3 HSV = float3(0.0, 0.0, 0.0); - HSV.z = max(RGB.r, max(RGB.g, RGB.b)); - float M = min(RGB.r, min(RGB.g, RGB.b)); - float C = HSV.z - M; - - if (C != 0) - { - HSV.x = RGBCVtoHUE(RGB, C, HSV.z); - HSV.y = C / HSV.z; - } - - return HSV; -} - -float3 HUEtoRGB(float H) -{ - float R = abs(H * 6 - 3) - 1; - float G = 2 - abs(H * 6 - 2); - float B = 2 - abs(H * 6 - 4); - - return saturate(float3(R, G, B)); -} - -float3 HSVtoRGB(float3 HSV) -{ - float3 RGB = HUEtoRGB(HSV.x); - return ((RGB - 1) * HSV.y + 1) * HSV.z; -} - float3 HSVComplement(float3 HSV) { float3 complement = HSV; @@ -1585,16 +1875,16 @@ float4 ColorGrading(float4 color, float2 texcoord) [SCANLINES CODE SECTION] ------------------------------------------------------------------------------*/ -#if (SCANLINES == 1) +#if SCANLINES == 1 float4 ScanlinesPass(float4 color, float2 texcoord, float4 fragcoord) { float4 intensity; - #if (GLSL == 1) + #if GLSL == 1 fragcoord = gl_FragCoord; #endif - #if (ScanlineType == 0) + #if ScanlineType == 0 if (frac(fragcoord.y * 0.25) > ScanlineScale) #elif (ScanlineType == 1) if (frac(fragcoord.x * 0.25) > ScanlineScale) @@ -1621,7 +1911,7 @@ float4 ScanlinesPass(float4 color, float2 texcoord, float4 fragcoord) [VIGNETTE CODE SECTION] ------------------------------------------------------------------------------*/ -#if (VIGNETTE == 1) +#if VIGNETTE == 1 float4 VignettePass(float4 color, float2 texcoord) { const float2 VignetteCenter = float2(0.500, 0.500); @@ -1642,33 +1932,48 @@ float4 VignettePass(float4 color, float2 texcoord) [SUBPIXEL DITHERING CODE SECTION] ------------------------------------------------------------------------------*/ -#if (DITHERING == 1) -float4 DitherPass(float4 color, float2 texcoord) +#if SP_DITHERING == 1 +float Randomize(float2 texcoord) { - float ditherSize = 2.0; - float ditherBits = 8.0; - - #if DitherMethod == 2 //random subpixel dithering - float seed = dot(texcoord, float2(12.9898, 78.233)); float sine = sin(seed); - float noise = frac(sine * 43758.5453 + texcoord.x); + float noise = frac(sine * 43758.5453); + return noise; +} + +float4 DitherPass(float4 color, float2 texcoord) +{ + float ditherBits = 8.0; + + #if DitherMethod == 2 //random dithering + + float noise = Randomize(texcoord); float ditherShift = (1.0 / (pow(2.0, ditherBits) - 1.0)); float ditherHalfShift = (ditherShift * 0.5); ditherShift = ditherShift * noise - ditherHalfShift; color.rgb += float3(-ditherShift, ditherShift, -ditherShift); - #else //Ordered dithering + #if ShowMethod == 1 + color.rgb = noise; + #endif - float gridPosition = frac(dot(texcoord, (screenSize / ditherSize)) + (0.5 / ditherSize)); - float ditherShift = (0.75) * (1.0 / (pow(2, ditherBits) - 1.0)); + #elif DitherMethod == 1 //ordered dithering + + float2 ditherSize = float2(1.0 / 16.0, 10.0 / 36.0); + float gridPosition = frac(dot(texcoord, (screenSize * ditherSize)) + 0.25); + float ditherShift = (0.25) * (1.0 / (pow(2.0, ditherBits) - 1.0)); float3 RGBShift = float3(ditherShift, -ditherShift, ditherShift); RGBShift = lerp(2.0 * RGBShift, -2.0 * RGBShift, gridPosition); color.rgb += RGBShift; + + #if ShowMethod == 1 + color.rgb = gridPosition; + #endif + #endif color.a = AvgLuminance(color.rgb); @@ -1688,7 +1993,7 @@ float4 BorderPass(float4 colorInput, float2 tex) float2 border = (_rcpFrame.xy * BorderWidth); float2 within_border = saturate((-tex * tex + tex) - (-border * border + border)); - #if (GLSL == 1) + #if GLSL == 1 // FIXME GLSL any only support bvec so try to mix it with notEqual bvec2 cond = notEqual( within_border, vec2(0.0f) ); colorInput.rgb = all(cond) ? colorInput.rgb : border_color_float; @@ -1704,13 +2009,13 @@ float4 BorderPass(float4 colorInput, float2 tex) [MAIN() & COMBINE PASS CODE SECTION] ------------------------------------------------------------------------------*/ -#if (GLSL == 1) +#if GLSL == 1 void ps_main() #else PS_OUTPUT ps_main(VS_OUTPUT input) #endif { - #if (GLSL == 1) + #if GLSL == 1 float2 texcoord = PSin.t; float4 position = PSin.p; float4 color = texture(TextureSampler, texcoord); @@ -1722,79 +2027,91 @@ PS_OUTPUT ps_main(VS_OUTPUT input) float4 color = sample_tex(TextureSampler, texcoord); #endif - #if (BILINEAR_FILTERING == 1) - color = BiLinearPass(color, texcoord); + #if BILINEAR_FILTERING == 1 + color = BiLinearPass(color, texcoord); #endif - #if (GAUSSIAN_FILTERING == 1) - color = GaussianPass(color, texcoord); + #if GAUSSIAN_FILTERING == 1 + color = GaussianPass(color, texcoord); #endif - #if (BICUBIC_FILTERING == 1) - color = BiCubicPass(color, texcoord); + #if BICUBIC_FILTERING == 1 + color = BiCubicPass(color, texcoord); #endif - #if (BICUBLIC_SCALER == 1) - color = BiCubicScalerPass(color, texcoord); + #if BICUBLIC_SCALER == 1 + color = BiCubicScalerPass(color, texcoord); #endif - #if (LANCZOS_SCALER == 1) - color = LanczosScalerPass(color, texcoord); + #if LANCZOS_SCALER == 1 + color = LanczosScalerPass(color, texcoord); #endif - #if (UHQ_FXAA == 1) - color = FxaaPass(color, texcoord); + #if UHQ_FXAA == 1 + color = FxaaPass(color, texcoord); #endif - #if (GAMMA_CORRECTION == 1) - color = GammaPass(color, texcoord); + #if TEXTURE_SHARPEN == 1 + color = TexSharpenPass(color, texcoord); #endif - #if (TEXTURE_SHARPEN == 1) - color = TexSharpenPass(color, texcoord); + #if PAINT_SHADING == 1 + color = PaintPass(color, texcoord); #endif - #if (CEL_SHADING == 1) - color = CelPass(color, texcoord); + #if CEL_SHADING == 1 + color = CelPass(color, texcoord); #endif - #if (SCANLINES == 1) - color = ScanlinesPass(color, texcoord, position); + #if GAMMA_CORRECTION == 1 + color = GammaPass(color, texcoord); #endif - #if (BLENDED_BLOOM == 1) - color = BloomPass(color, texcoord); + #if PIXEL_VIBRANCE == 1 + color = VibrancePass(color, texcoord); #endif - #if (SCENE_TONEMAPPING == 1) - color = TonemapPass(color, texcoord); + #if COLOR_GRADING == 1 + color = ColorGrading(color, texcoord); #endif - #if (PIXEL_VIBRANCE == 1) - color = VibrancePass(color, texcoord); + #if SCENE_TONEMAPPING == 1 + color = TonemapPass(color, texcoord); #endif - #if (COLOR_GRADING == 1) - color = ColorGrading(color, texcoord); + #if COLOR_CORRECTION == 1 + color = CorrectionPass(color, texcoord); #endif - #if (S_CURVE_CONTRAST == 1) - color = ContrastPass(color, texcoord); + #if CROSS_PROCESSING == 1 + color = CrossPass(color, texcoord); #endif - #if (VIGNETTE == 1) - color = VignettePass(color, texcoord); + #if BLENDED_BLOOM == 1 + color = BloomPass(color, texcoord); #endif - #if (PX_BORDER == 1) - color = BorderPass(color, texcoord); + #if CURVE_CONTRAST == 1 + color = ContrastPass(color, texcoord); + #endif + + #if VIGNETTE == 1 + color = VignettePass(color, texcoord); + #endif + + #if SCANLINES == 1 + color = ScanlinesPass(color, texcoord, position); #endif - #if (DITHERING == 1) - color = DitherPass(color, texcoord); + #if SP_DITHERING == 1 + color = DitherPass(color, texcoord); #endif - #if (GLSL == 1) + #if PX_BORDER == 1 + color = BorderPass(color, texcoord); + #endif + + #if GLSL == 1 SV_Target0 = color; #else output.c = color; From 3a14a63b0f10cc319908daaab695ab8227ce801f Mon Sep 17 00:00:00 2001 From: Kieran Hanrahan Date: Wed, 5 Aug 2015 16:33:51 +0100 Subject: [PATCH 4/5] Update GSdx_FX_Settings.ini Update to 2.3 and resolve OGL. --- bin/shaders/GSdx_FX_Settings.ini | 42 ++++++++++++++++---------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/bin/shaders/GSdx_FX_Settings.ini b/bin/shaders/GSdx_FX_Settings.ini index 2b9b8f476d..b92fdadee9 100644 --- a/bin/shaders/GSdx_FX_Settings.ini +++ b/bin/shaders/GSdx_FX_Settings.ini @@ -14,7 +14,7 @@ || || |#################################################################################| \*===============================================================================*/ -//#NOTICE: This post-processing suite requires Direct3D10(Shader Model 4.0), or higher. +//#NOTICE: GSdx FX is not compatible with GSdx9. Use GSdx OGL or DX10/11. /*------------------------------------------------------------------------------ [DEFINITIONS & ON/OFF OPTIONS] @@ -35,10 +35,10 @@ //#[LIGHTING & COLOUR] [1=ON|0=OFF] #READ: These can all be turned on & off independently of each other. [For High Dynamic Range(HDR) use Bloom & Tonemapping together] #define BLENDED_BLOOM 1 //# High Quality SP Bloom. Soft lighting with blending techniques, for a natural looking bloom. #define SCENE_TONEMAPPING 1 //# HDR Scene Tonemapping. Layered component conversion, and applies scene tone mapping. -#define COLOR_CORRECTION 1 //# Component Color Correction. Colorspace conversion, with correction curves, and multiple palette types. +#define COLOR_CORRECTION 0 //# Component Color Correction. Colorspace conversion, with correction curves, and multiple palette types. #define CROSS_PROCESSING 0 //# Filmic Cross Processing. Alters the tone of the scene, crossing the game's color set, with another. #define GAMMA_CORRECTION 0 //# RGB Gamma Correction. Fixed expansion to variable compression gamma correction curve. -#define PIXEL_VIBRANCE 0 //# Pixel Vibrance. Intelligently adjusts pixel vibrance depending on original color saturation. +#define PIXEL_VIBRANCE 1 //# Pixel Vibrance. Intelligently adjusts pixel vibrance depending on original color saturation. #define COLOR_GRADING 0 //# Post-Complement Colour Grading. Alters individual colour components on a scene, to enhance selected colour tones. #define TEXTURE_SHARPEN 0 //# Bicubic Texture Unsharpen Mask. Looks similar to a negative texture LOD bias. Enhances texture fidelity. #define CURVE_CONTRAST 0 //# S-Curve Scene Contrast Enhancement. Locally adjusts contrast using a four-point cubic bezier spline. @@ -58,7 +58,7 @@ //##[UHQ_FXAA] #define FxaaSubpixMax 0.00 //[0.00 to 1.00] Amount of subpixel aliasing removal. Higher values: softer. Lower values: sharper. 0.00: Edge only. #define FxaaQuality 4 //[1|2|3|4] Overall Fxaa quality preset (pixel coverage). 1: Low, 2: Medium, 3: High, 4: Ultra. -#define FxaaEarlyExit 1 //[0 or 1] Use Fxaa early exit pathing. When enabled: Only luma edge pixels are antialiased. When disabled: the entire scene is antialiased(FSAA). +#define FxaaEarlyExit 1 //[0 or 1] Use Fxaa early exit pathing. When enabled: Only luma edge pixels are antialiased. When disabled: the entire scene is antialiased(FSAA). //##[BILINEAR_FILTERING] #define FilterStrength 1.00 //[0.10 to 1.50] Bilinear filtering strength. Controls the overall strength of the filtering. @@ -79,42 +79,42 @@ #define BlendStrength 1.000 //[0.000 to 1.000] Strength of the blending. This is a modifier based on bloom. 1.0 equates to 100% strength. #define BloomDefocus 2.000 //[1.000 to 4.000] The initial bloom defocus value. Increases the softness of light, bright objects, etc. #define BloomWidth 3.200 //[1.000 to 8.000] Width of the bloom. Adjusts the width of the spread and soft glow. Scales with BloomStrength. -#define BloomReds 0.020 //[0.000 to 1.000] Red channel correction of the bloom. Raising will increase the bloom of reds. -#define BloomGreens 0.010 //[0.000 to 1.000] Green channel correction of the bloom. Raising will increase the bloom of greens. -#define BloomBlues 0.010 //[0.000 to 1.000] Blue channel correction of the bloom. Raising will increase the bloom of blues. +#define BloomReds 0.040 //[0.000 to 1.000] Red channel correction of the bloom. Raising will increase the bloom of reds. +#define BloomGreens 0.030 //[0.000 to 1.000] Green channel correction of the bloom. Raising will increase the bloom of greens. +#define BloomBlues 0.020 //[0.000 to 1.000] Blue channel correction of the bloom. Raising will increase the bloom of blues. //##[SCENE TONEMAPPING] -#define TonemapType 1 //[0|1|2] Type of base tone mapping operator. 0 is LDR, 1 is HDR(original), 2 is HDR Filmic(slight grading). -#define FilmOperator 1 //[0 or 1] Enables the use of Filmic ALU tone mapping operations that can produce a nice cinematic look. -#define FilmStrength 0.25 //[0.000 to 1.000] Strength of the filmic tone mapping. Higher for a stronger effect. This is a dependency of FilmicALU. +#define TonemapType 1 //[0|1|2|3] The base tone mapping operator. 0 is LDR, 1 is HDR(original), 2 & 3 are Filmic HDR(slight grading). +#define TonemapMask 0 //[0 or 1] Enables an ALU tone masking curve. Produces a nice cinematic look. Suits some games more than others. +#define MaskStrength 0.30 //[0.000 to 1.000] Strength of the tone masking. Higher for a stronger effect. This is a dependency of TonemapMask. #define ToneAmount 0.300 //[0.050 to 1.000] Tonemap strength (tone correction). Higher for stronger tone mapping, lower for lighter. -#define BlackLevels 0.050 //[0.000 to 1.000] Black level balance (shadow correction). Increase to deepen blacks, lower to lighten them. +#define BlackLevels 0.060 //[0.000 to 1.000] Black level balance (shadow correction). Increase to deepen blacks, lower to lighten them. #define Exposure 1.000 //[0.100 to 2.000] White correction (brightness). Higher values for more scene exposure, lower for less. -#define Luminance 1.002 //[0.100 to 2.000] Luminance average (luminance correction). Higher values will lower scene luminance average. -#define WhitePoint 1.002 //[0.100 to 2.000] Whitepoint average (wp lum correction). Higher values will lower the maximum scene white point. +#define Luminance 1.000 //[0.100 to 2.000] Luminance average (luminance correction). Higher values will lower scene luminance average. +#define WhitePoint 1.000 //[0.100 to 2.000] Whitepoint average (wp lum correction). Higher values will lower the maximum scene white point. //##[COLOR CORRECTION] #define CorrectionPalette 1 //[1|2|3|4|5] The colorspace palette type. 1: RGB, 2: YXY, 3: XYZ, 4: HSV, 5: YUV. Each one will produce a different combination of shades & hues. -#define ChannelR 2.00 //[0.00 to 8.00] R(1), Y(2), X(3), H(4), Y(5) component channel varies with the colorspace used. Higher values increase correction strength. -#define ChannelG 1.20 //[0.00 to 8.00] G(1), X(2), Y(3), S(4), U(5) component channel varies with the colorspace used. Higher values increase correction strength. -#define ChannelB 1.60 //[0.00 to 8.00] B(1), Y(2), Z(3), V(4), V(5) component channel varies with the colorspace used. Higher values increase correction strength. +#define ChannelR 1.20 //[0.00 to 8.00] R(1), Y(2), X(3), H(4), Y(5) component channel varies with the colorspace used. Higher values increase correction strength. +#define ChannelG 1.60 //[0.00 to 8.00] G(1), X(2), Y(3), S(4), U(5) component channel varies with the colorspace used. Higher values increase correction strength. +#define ChannelB 1.80 //[0.00 to 8.00] B(1), Y(2), Z(3), V(4), V(5) component channel varies with the colorspace used. Higher values increase correction strength. #define PaletteStrength 1.00 //[0.00 to 2.00] The interpolated strength ratio between the base color, and the corrected color. Raise to increase saturation. //##[CROSS PROCESSING] #define FilmicProcess 1 //[1|2|3] The color conversion type for the cross process. 1: cool, 2: warm, 3: dusk. You can achieve different results with each. -#define RedShift 0.55 //[0.10 to 1.00] Red color component shift of the filmic processing. Alters the red balance of the shift. +#define RedShift 0.50 //[0.10 to 1.00] Red color component shift of the filmic processing. Alters the red balance of the shift. #define GreenShift 0.50 //[0.10 to 1.00] Green color component shift of the filmic processing. Alters the green balance of the shift. -#define BlueShift 0.55 //[0.10 to 1.00] Blue color component shift of the filmic processing. Alters the blue balance of the shift. +#define BlueShift 0.50 //[0.10 to 1.00] Blue color component shift of the filmic processing. Alters the blue balance of the shift. #define ShiftRatio 0.50 //[0.10 to 2.00] The blending ratio for the base color and the color shift. Higher for a stronger effect. //##[TEXTURE SHARPEN] #define SharpenStrength 0.75 //[0.10 to 2.00] Strength of the texture sharpening effect. This is the maximum strength that will be used. -#define SharpenClamp 0.012 //[0.005 to 0.500] Reduces the clamping/limiting on the maximum amount of sharpening each pixel recieves. Raise this to reduce the clamping. -#define SharpenBias 1.00 //[1.00 to 4.00] Sharpening edge bias. Lower values for clean subtle sharpen, and higher values for a deeper textured sharpen. +#define SharpenClamp 0.015 //[0.005 to 0.500] Reduces the clamping/limiting on the maximum amount of sharpening each pixel recieves. Raise this to reduce the clamping. +#define SharpenBias 1.20 //[0.50 to 4.00] Sharpening edge bias. Lower values for clean subtle sharpen, and higher values for a deeper textured sharpen. #define DebugSharpen 0 //[0 or 1] Visualize the sharpening effect. Useful for fine-tuning. Best to disable other effects, to see edge detection clearly. //##[PIXEL VIBRANCE] -#define Vibrance 0.15 //[-1.00 to 1.00] Overall vibrance strength. Locally adjusts the vibrance of pixels depending on their original saturation. +#define Vibrance 0.10 //[-1.00 to 1.00] Overall vibrance strength. Locally adjusts the vibrance of pixels depending on their original saturation. #define RedVibrance 1.00 //[-8.00 to 8.00] Red channel coefficient of the vibrance strength. Adjusting the vibrance of the red channel independently. #define GreenVibrance 1.00 //[-8.00 to 8.00] Green channel coefficient of the vibrance strength. Adjusting the vibrance of the green channel independently. #define BlueVibrance 1.00 //[-8.00 to 8.00] Blue channel coefficient of the vibrance strength. Adjusting the vibrance of the blue channel independently. From a1a5b25b915f31cc00a3b21fcda1f35e3a1d6142 Mon Sep 17 00:00:00 2001 From: Kieran Hanrahan Date: Wed, 5 Aug 2015 16:34:40 +0100 Subject: [PATCH 5/5] Update GSdx.fx Update to 2.3 & resolve OGL. --- bin/shaders/GSdx.fx | 189 ++++++++++++++++++++++++++------------------ 1 file changed, 111 insertions(+), 78 deletions(-) diff --git a/bin/shaders/GSdx.fx b/bin/shaders/GSdx.fx index a1b3c920ca..73ef7bd738 100644 --- a/bin/shaders/GSdx.fx +++ b/bin/shaders/GSdx.fx @@ -23,7 +23,7 @@ #endif #if defined(SHADER_MODEL) && (SHADER_MODEL <= 0x300) -#error GSdx FX requires shader model 4.0(Direct3D10) or higher. Use GSdx DX10/11. +#error GSdx FX is not compatible with GSdx9. Use GSdx OGL or DX10/11. #endif #ifdef SHADER_MODEL @@ -34,7 +34,6 @@ [GLOBALS|FUNCTIONS] ------------------------------------------------------------------------------*/ #if GLSL == 1 - #define int2 ivec2 #define float2 vec2 #define float3 vec3 @@ -606,7 +605,6 @@ float4 FxaaPixelShader(float2 pos, FxaaTex tex, float2 fxaaRcpFrame, float fxaaS float4 FxaaPass(float4 FxaaColor, float2 texcoord) { #if GLSL == 1 - tex = TextureSampler; FxaaColor = FxaaPixelShader(texcoord, TextureSampler, pixelSize.xy, FxaaSubpixMax, FxaaEdgeThreshold, FxaaEdgeThresholdMin); #else FxaaTex tex; @@ -1134,18 +1132,18 @@ float3 BlendScreen(float3 bloom, float3 blend) return (bloom + blend) - (bloom * blend); } -float3 BlendAddGlow(float3 bloom, float3 blend) +float3 BlendGlow(float3 bloom, float3 blend) { - float glow = smootherstep(0.0, 1.0, AvgLuminance(bloom)); - return lerp(saturate(bloom + blend), + float glow = AvgLuminance(bloom); + return lerp((bloom + blend) - (bloom * blend), (blend + blend) - (blend * blend), glow); } -float3 BlendGlow(float3 bloom, float3 blend) +float3 BlendAddGlow(float3 bloom, float3 blend) { - float glow = smootherstep(0.0, 1.0, AvgLuminance(bloom)); - return lerp((bloom + blend) - (bloom * blend), - (blend + blend) - (blend * blend), glow); + float addglow = smootherstep(0.0, 1.0, AvgLuminance(bloom)); + return lerp(saturate(bloom + blend), + (blend + blend) - (blend * blend), addglow); } float3 BlendLuma(float3 bloom, float3 blend) @@ -1162,16 +1160,6 @@ float3 BlendOverlay(float3 bloom, float3 blend) (1.0 - bloom) * (1.0 - blend))), overlay); } -float4 PyramidFilter(sampler tex, float2 texcoord, float2 width) -{ - float4 X = sample_tex(tex, texcoord + float2(0.5, 0.5) * width); - float4 Y = sample_tex(tex, texcoord + float2(-0.5, 0.5) * width); - float4 Z = sample_tex(tex, texcoord + float2(0.5, -0.5) * width); - float4 W = sample_tex(tex, texcoord + float2(-0.5, -0.5) * width); - - return (X + Y + Z + W) / 4.0; -} - float3 BloomCorrection(float3 color) { float3 bloom = color; @@ -1184,23 +1172,41 @@ float3 BloomCorrection(float3 color) bloom.g = saturate(color.g + float(BloomGreens) * bloom.g); bloom.b = saturate(color.b + float(BloomBlues) * bloom.b); - color = saturate(bloom); + color = bloom; return color; } +float4 DefocusFilter(SamplerState tex, float2 texcoord, float2 defocus) +{ + float2 texel = pixelSize * defocus; + + float4 sampleA = sample_tex(tex, texcoord + float2(0.5, 0.5) * texel); + float4 sampleB = sample_tex(tex, texcoord + float2(-0.5, 0.5) * texel); + float4 sampleC = sample_tex(tex, texcoord + float2(0.5, -0.5) * texel); + float4 sampleD = sample_tex(tex, texcoord + float2(-0.5, -0.5) * texel); + + float fx = frac(texcoord.x * screenSize.x); + float fy = frac(texcoord.y * screenSize.y); + + float4 interpolateA = lerp(sampleA, sampleB, fx); + float4 interpolateB = lerp(sampleC, sampleD, fx); + + return lerp(interpolateA, interpolateB, fy); +} + float4 BloomPass(float4 color, float2 texcoord) { float anflare = 4.0; float2 defocus = float2(BloomDefocus, BloomDefocus); - float4 bloom = PyramidFilter(TextureSampler, texcoord, pixelSize * defocus); + float4 bloom = DefocusFilter(TextureSampler, texcoord, defocus); float2 dx = float2(pixelSize.x * float(BloomWidth), 0.0); float2 dy = float2(0.0, pixelSize.y * float(BloomWidth)); - float2 mdx = mul(dx, 2.0); - float2 mdy = mul(dy, 2.0); + float2 mdx = float2(dx.x * defocus.x, 0.0); + float2 mdy = float2(0.0, dy.y * defocus.y); float4 blend = bloom * 0.22520613262190495; @@ -1237,9 +1243,9 @@ float4 BloomPass(float4 color, float2 texcoord) bloom.xyz = BloomType(bloom.xyz, blend.xyz); bloom.xyz = BloomCorrection(bloom.xyz); - color.a = AvgLuminance(color.xyz); - bloom.a = AvgLuminance(bloom.xyz); - bloom.a *= anflare; + color.w = AvgLuminance(color.xyz); + bloom.w = AvgLuminance(bloom.xyz); + bloom.w *= anflare; color = lerp(color, bloom, float(BloomStrength)); @@ -1252,68 +1258,96 @@ float4 BloomPass(float4 color, float2 texcoord) ------------------------------------------------------------------------------*/ #if SCENE_TONEMAPPING == 1 -float3 FilmicCurve(float3 color) +float3 ScaleLuminance(float3 x) +{ + float W = 1.02; + float L = 0.06; + float C = 1.02; + + float N = clamp(0.76 + ToneAmount, 1.0, 2.0); + float K = (N - L * C) / C; + + float3 tone = L * C + (1.0 - L * C) * (1.0 + K * (x - L) / + ((W - L) * (W - L))) * (x - L) / (x - L + K); + + return tone; +} + +float3 TmMask(float3 color) +{ + float3 tone = color; + + float highTone = 6.2; float greyTone = 0.4; + float midTone = 1.620; float lowTone = 0.06; + + tone.r = (tone.r * (highTone * tone.r + greyTone))/( + tone.r * (highTone * tone.r + midTone) + lowTone); + tone.g = (tone.g * (highTone * tone.g + greyTone))/( + tone.g * (highTone * tone.g + midTone) + lowTone); + tone.b = (tone.b * (highTone * tone.b + greyTone))/( + tone.b * (highTone * tone.b + midTone) + lowTone); + + static const float gamma = 2.42; + tone = EncodeGamma(tone, gamma); + + color = lerp(color, tone, float(MaskStrength)); + + return color; +} + +float3 TmCurve(float3 color) { float3 T = color; - float tnamn = ToneAmount; - float A = 0.100; - float B = 0.300; - float C = 0.100; - float D = tnamn; - float E = 0.020; - float F = 0.300; - float W = 1.012; + float tnamn = ToneAmount; + float blevel = length(T); + float bmask = pow(blevel, 0.02); + + float A = 0.100; float B = 0.300; + float C = 0.100; float D = tnamn; + float E = 0.020; float F = 0.300; + + float W = 1.000; T.r = ((T.r*(A*T.r + C*B) + D*E) / (T.r*(A*T.r + B) + D*F)) - E / F; T.g = ((T.g*(A*T.g + C*B) + D*E) / (T.g*(A*T.g + B) + D*F)) - E / F; T.b = ((T.b*(A*T.b + C*B) + D*E) / (T.b*(A*T.b + B) + D*F)) - E / F; float denom = ((W*(A*W + C*B) + D*E) / (W*(A*W + B) + D*F)) - E / F; + + float3 black = float3(bmask, bmask, bmask); float3 white = float3(denom, denom, denom); T = T / white; + T = T * black; + color = saturate(T); return color; } -float3 FilmicTonemap(float3 color) -{ - float3 tone = color; - - float3 black = float3(0.0, 0.0, 0.0); - tone = max(black, tone); - - tone.r = (tone.r * (6.2 * tone.r + 0.5)) / (tone.r * (6.2 * tone.r + 1.66) + 0.066); - tone.g = (tone.g * (6.2 * tone.g + 0.5)) / (tone.g * (6.2 * tone.g + 1.66) + 0.066); - tone.b = (tone.b * (6.2 * tone.b + 0.5)) / (tone.b * (6.2 * tone.b + 1.66) + 0.066); - - static const float gamma = 2.42; - tone = EncodeGamma(tone, gamma); - - color = lerp(color, tone, float(FilmStrength)); - - return color; -} - float4 TonemapPass(float4 color, float2 texcoord) { - float luminanceAverage = AvgLuminance(Luminance); - float bmax = max(color.r, max(color.g, color.b)); + float3 tonemap = color.rgb; - float blevel = pow(saturate(bmax), float(BlackLevels)); - color.rgb = color.rgb * blevel; + float blackLevel = length(tonemap); + tonemap = ScaleLuminance(tonemap); - if (FilmOperator == 1) { color.rgb = FilmicTonemap(color.rgb); } - if (TonemapType == 1) { color.rgb = FilmicCurve(color.rgb); } + #if GLSL == 1 + float luminanceAverage = AvgLuminance(float3(Luminance)); + #else + float luminanceAverage = AvgLuminance(Luminance); + #endif + + if (TonemapMask == 1) { tonemap = TmMask(tonemap); } + if (TonemapType == 1) { tonemap = TmCurve(tonemap); } // RGB -> XYZ conversion const float3x3 RGB2XYZ = float3x3(0.4124564, 0.3575761, 0.1804375, 0.2126729, 0.7151522, 0.0721750, 0.0193339, 0.1191920, 0.9503041); - float3 XYZ = mul(RGB2XYZ, color.rgb); + float3 XYZ = mul(RGB2XYZ, tonemap); // XYZ -> Yxy conversion float3 Yxy; @@ -1325,7 +1359,7 @@ float4 TonemapPass(float4 color, float2 texcoord) // (Wt) Tone mapped scaling of the initial wp before input modifiers float Wt = saturate(Yxy.r / AvgLuminance(XYZ)); - if (TonemapType == 2) { Yxy.r = FilmicCurve(Yxy).r; } + if (TonemapType == 2) { Yxy.r = TmCurve(Yxy).r; } // (Lp) Map average luminance to the middlegrey zone by scaling pixel luminance float Lp = Yxy.r * float(Exposure) / (luminanceAverage + Epsilon); @@ -1341,12 +1375,19 @@ float4 TonemapPass(float4 color, float2 texcoord) XYZ.g = Yxy.r; // copy luminance Y XYZ.b = Yxy.r * (1.0 - Yxy.g - Yxy.b) / Yxy.b; // Z = Y * (1-x-y) / y + if (TonemapType == 3) { XYZ = TmCurve(XYZ); } + // XYZ -> RGB conversion const float3x3 XYZ2RGB = float3x3(3.2404542,-1.5371385,-0.4985314, -0.9692660, 1.8760108, 0.0415560, 0.0556434,-0.2040259, 1.0572252); - color.rgb = mul(XYZ2RGB, XYZ); + tonemap = mul(XYZ2RGB, XYZ); + + float shadowmask = pow(saturate(blackLevel), float(BlackLevels)); + tonemap = tonemap * float3(shadowmask, shadowmask, shadowmask); + + color.rgb = tonemap; color.a = AvgLuminance(color.rgb); return color; @@ -1358,14 +1399,6 @@ float4 TonemapPass(float4 color, float2 texcoord) ------------------------------------------------------------------------------*/ #if CROSS_PROCESSING == 1 -float MidLuminance(float3 color) -{ - return sqrt( - (color.x * color.x * 0.3333) + - (color.y * color.y * 0.3333) + - (color.z * color.z * 0.3333)); -} - float3 CrossShift(float3 color) { float3 cross; @@ -1379,7 +1412,7 @@ float3 CrossShift(float3 color) cross.y = float(GreenShift) * CrossMatrix[1].x + CrossMatrix[1].y; cross.z = float(BlueShift) * CrossMatrix[2].x + CrossMatrix[2].y; - float lum = MidLuminance(color); + float lum = AvgLuminance(color); float3 black = float3(0.0, 0.0, 0.0); float3 white = float3(1.0, 1.0, 1.0); @@ -1573,7 +1606,7 @@ float4 ContrastPass(float4 color, float2 texcoord) //S-Curve - Cubic Bezier spline float3 a = float3(0.00, 0.00, 0.00); //start point float3 b = float3(0.25, 0.25, 0.25); //control point 1 - float3 c = float3(0.80, 0.80, 0.80); //control point 2 + float3 c = float3(0.85, 0.85, 0.85); //control point 2 float3 d = float3(1.00, 1.00, 1.00); //endpoint float3 ab = lerp(a, b, x); //point between a and b (green) @@ -2075,10 +2108,6 @@ PS_OUTPUT ps_main(VS_OUTPUT input) color = ColorGrading(color, texcoord); #endif - #if SCENE_TONEMAPPING == 1 - color = TonemapPass(color, texcoord); - #endif - #if COLOR_CORRECTION == 1 color = CorrectionPass(color, texcoord); #endif @@ -2087,6 +2116,10 @@ PS_OUTPUT ps_main(VS_OUTPUT input) color = CrossPass(color, texcoord); #endif + #if SCENE_TONEMAPPING == 1 + color = TonemapPass(color, texcoord); + #endif + #if BLENDED_BLOOM == 1 color = BloomPass(color, texcoord); #endif