Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*===============================================================================*\
- |####################### [PsxFX Shader Suite v2.00] ########################|
- |######################### By Asmodean ##########################|
- || ||
- || This program is free software; you can redistribute it and/or ||
- || modify it under the terms of the GNU General Public License ||
- || as published by the Free Software Foundation; either version 2 ||
- || of the License, or (at your option) any later version. ||
- || ||
- || 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)2016 ||
- || ||
- |#################################################################################|
- \*===============================================================================*/
- #version 150 compatibility
- #extension GL_NV_gpu_shader5 : enable
- #extension GL_ARB_gpu_shader5 : enable
- #extension GL_ARB_shader_precision : enable
- #extension GL_ARB_sample_shading : enable
- #extension GL_ARB_texture_rectangle : enable
- #extension GL_ARB_shader_storage_buffer_object : enable
- #extension GL_ARB_shader_image_load_store : enable
- #extension GL_ARB_bindless_texture : enable
- #extension GL_ARB_shading_language_420pack : enable
- /*------------------------------------------------------------------------------
- [DEFINITIONS & ON/OFF OPTIONS]
- ------------------------------------------------------------------------------*/
- //--------------------------#[CHOOSE EFFECTS]#--------------------------------\\
- //#[ANTIALIASING TECHNIQUES] [1=ON|0=OFF] #NOTE: For best results: use an antialiasing OR filtering technique. Not both together.
- #define FXAA 1 //# High Quality Fast Approximate Anti-Aliasing. With optional xBR, & Bilateral sampling. Providing the benefits of 3 in 1.
- #define DLAA 0 //# Directionally Localized Anti-Aliasing. A soft type of Morphological Anti-Aliasing with good coverage.
- #define SSAA 0 //# Shader-Based Pseudo SuperSampling. A light AA that scales well with high resolutions. (2D & 3D).
- #define XBRV 0 //# Hyllian's xBR-lv2-3D Shader. xBR interpolation scaling. This must be enabled in the vertex shader (slv) also, for it to work.
- #define SFAA 0 //# Guest's Soft Filter Anti-Aliasing. This must be enabled in the vertex shader (slv) also, for it to work. (2D & 3D).
- //#[FS SCALING TECHNIQUES] [1=ON|0=OFF] #NOTE: 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 BILATERAL_FILTERING 0 //# Bilateral Fullscreen Texture Filtering. Smoothes color gradient transitions and reduces dithering artifacts.[2D]
- #define DDTI_FILTERING 0 //# Data Dependent Triangulation Interpolation. This must be enabled in the vertex shader (slv) also, for it to work.[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] #NOTE: These can all be turned on & off independently of each other. [For High Dynamic Range(HDR) use Bloom & Tonemapping together]
- #define PHONG_SHADING 1 //# Per-Pixel Phong Shading. Simulates lighting calculations on a per-pixel basis, with attenuation (lighting enhancement).
- #define BLENDED_BLOOM 0 //# High Quality SP Bloom. Soft lighting with blending techniques, for a natural looking bloom.
- #define SCENE_TONEMAPPING 0 //# 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 NTSC_TV_EMULATION 0 //# SimoneT's TV Colors Emulation Shader. Use to emulate the original PSX color space tone, and vibrancy.
- #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 manip selected colour tones.
- #define TEXTURE_SHARPEN 0 //# Bicubic Texture Unsharp 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. A pixel-based cel shader, with a luminance edge filter for avoiding edge effects on menus & text.
- #define PAINT_SHADING 0 //# Paint Shading. Creates the effect of a painted scene. Cel shaded edges can also be enabled for a story book effect.
- //#[TV EMU TECHNIQUES] [1=ON|0=OFF] #NOTE: These can all be turned on & off independently of each other. These effects are typically used to simulated older TVs/utility, etc.
- #define LOTTES_CRT 0 //# Timothy Lottes CRT emulation effect. Similar to scanlines, but with more control options. Ported by request.
- #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 DEBANDING 0 //# Applies a debanding effect. This effect can help to minimize banding artifacts. Mileage will vary per game.
- #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, or flickering edges that can occur on some games. (Ported by request from SFX).
- /*------------------------------------------------------------------------------
- [EFFECT CONFIG OPTIONS]
- ------------------------------------------------------------------------------*/
- //##[FXAA]
- #define FxaaSubpixMax 8.00 //[1.00 to 8.00] Amount of subpixel anti-aliasing. Higher values for a stronger effect, & edge coverage.
- #define FxaaQuality 4 //[1|2|3|4] Overall Fxaa quality preset (pixel coverage). 1: Low, 2: Medium, 3: High, 4: Ultra.
- #define BilateralSampling 0 //[0 or 1] Use Bilateral filtering within the FXAA coverage. High performance cost if BilateralRadius is set too high. (use bilateral settings)
- #define xBRlv2Sampling 0 //[0 or 1] Use xBR-lv2-3D within the FXAA coverage. Enables the 2D interpolation of xBR, with the 3D antialiasing of FXAA. (use xBR settings & enable in .slv)
- #define xBRThreshold 0.020 //[0.00 to 0.05] The detection threshold for applying xBR to 2D, and FXAA to 3D. (3D -> 0.0....0.05 -> 2D)
- //##[SSAA]
- #define FilterWidth 1.35 //[0.50 to 2.00] Width of the SSAA filter. Raising this will increase the width of the edge filter.
- //##[XBRV]
- #define DetectionType 3 //[1|2|3|4] The pixel corner detection method used. 1: Corner A, 2: Corner B, 3: Corner C, 4: Corner D.
- #define SampleScale 2.0 //[1.0 to 4.0] The xBR resolution scale of the samples. Changes the scale mod for the base res.
- #define ScaleFactor 3.0 //[1.0 to 5.0] The xBR scaling factor. Use to increase or decrease the scale of the xBR.
- //##[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_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_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.
- //##[BILATERAL_FILTERING]
- #define BilateralRadius 2.00 //[1.00 to 8.00] Radius of the filter. Increasing the radius leads to more pixel lookups, so higher values require more performance.
- #define BilateralWeight 0.20 //[0.10 to 1.00] Central weight of the filter. Raising this increases the overall filter width, along with the strength.
- //##[DDTI_FILTERING]
- #define PixelShift 0.25 //[0.10 to 1.00] Pixel offset amount. If you want to use an st offset, 0.25 is generally recommended. 0.0 is off.
- //##[BLENDED_BLOOM]
- #define BloomType BlendGlow //[BlendGlow, BlendAddGlow, BlendAddLight, BlendScreen, BlendLuma, BlendOverlay] The type of blended bloom. Light<->Dark.
- #define BloomStrength 0.200 //[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.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|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.10 //[0.000 to 1.000] Strength of the tone masking. Higher for a stronger effect. This is a dependency of TonemapMask.
- #define ToneAmount 0.320 //[0.050 to 1.000] Tonemap strength (tone correction). Higher for stronger tone mapping, lower for lighter.
- #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.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 1.40 //[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 2.00 //[0.00 to 4.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.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.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.80 //[0.10 to 2.00] Strength of the texture sharpening effect. This is the maximum strength that will be used.
- #define SharpenClamp 0.080 //[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.40 //[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.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.
- //##[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.
- //##[CEL_SHADING]
- #define CelStrength 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 1.00 //[0.10 to 2.00] Filters out fainter cel edges. Use it for balancing the cel edge density. Lower values for more of a dense cel detection.
- #define EdgeScale 1.50 //[1.00 to 4.00] Thickness of the cel edges. Basically a scale modifier for the resolution. Set higher when using low/native res for games.
- #define ColorRange 7.00 //[5.00 to 15.0] This alters the color highlight range of the cel shading. Lower values reduce the range, and higher increases it.
- #define Saturation 1.20 //[0.10 to 2.00] Highlighted saturation of the shaded color. Where 1.0 is base saturation. Higher for more.
- #define ShadedStrength 0.60 //[0.00 to 1.00] The interpolated strength value of the 'tooning' shading color conversions. Where 1.00 is 100% strength.
- #define UseYuvLuma 0 //[0 or 1] Uses YUV luma calculations, or base color luma calculations. Yuv luma can produce a better shaded look.
- #define ColorRounding 0 //[0 or 1] Uses rounding methods on colors. This can emphasise shaded toon colors. Looks good in some games, and odd in others.
- #define RoundingLevels 9.0 //[2.0 to 18.0] Alters the rounding levels for the shaded RGB color. Different values will produce different roundin results.
- //##[PAINT_SHADING]
- #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.
- #define ResScale 1.00 //[1.00 to 4.00] Scale modifier for the effect resolution. Set higher to clean up the effect when using on low/native res for games.
- #define UseCelEdges 1 //[0 or 1] Enables cel edges for the paint shading. This can produce a nice story book / painted cel shader effect. (use cel options)
- //##[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.
- //##[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)
- //##[LOTTES_CRT]
- #define UseShadowMask 1 //[0 or 1] Enables, or disables the use of the CRT shadow mask. 0 is disabled, 1 is enabled.
- #define MaskingType 1 //[1|2|3|4] The type of CRT shadow masking used. 1: compressed TV style, 2: Aperture-grille, 3: Stretched VGA style, 4: VGA style.
- #define CRTSizeX 1024 //[128 to 2048] A workaround for arbitrary render target scaling. Either set it to a fixed width, or set it to screenSize.x
- #define CRTSizeY 240 //[128 to 2048] A workaround for arbitrary render target scaling. Either set it to a fixed height, or set it to screenSize.y
- #define ScanBrightness -6.00 //[-16.0 to 1.0] The overall brightness of the scanline effect. Lower for darker, higher for brighter.
- #define FilterCRTAmount -4.00 //[-4.0 to 1.0] The amount of filtering used, to replicate the TV CRT look. Lower for less, higher for more.
- #define HorizontalWarp 0.00 //[0.0 to 0.1] The distortion warping effect for the horizontal (x) axis of the screen. Use small increments.
- #define VerticalWarp 0.00 //[0.0 to 0.1] The distortion warping effect for the verticle (y) axis of the screen. Use small increments.
- #define MaskAmountDark 1.00 //[0.0 to 1.0] The value of the dark masking line effect used. Lower for darker lower end masking, higher for brighter.
- #define MaskAmountLight 1.50 //[0.0 to 2.0] The value of the light masking line effect used. Lower for darker higher end masking, higher for brighter.
- #define ResolutionScale 4.00 //[0.1 to 4.0] The scale of the image resolution. Lowering this can give off a nice retro TV look. Raising it can clear up the image.
- #define MaskResolutionScale 2.30 //[0.1 to 2.0] The scale of the CRT mask resolution. Use this for balancing the scanline mask scale for difference resolution scaling.
- //##[SCANLINES]
- #define ScanlineType 2 //[0|1|2] The type & orientation of the scanlines. 0 is x(horizontal), 1 is y(vertical), 2 is both(xy)
- #define ScanlineScale 0.30 //[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 2.00 //[0.50 to 2.00] The brightness of the scanlines. Defaults: 2.00 for ScanlineType 0|1|2, 1.50 for ScanlineType 3.
- //##[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.
- //##[DEBANDING]
- #define DebandRadius 256.0 //[0.0 to 1024.0] Sampling radius, higher values will reduce further banding but might also reduce details.
- #define DebandThreshold 0.017 //[0.000 to 0.100] Threshold, higher values will reduce further banding but might also reduce details and increase noise.
- #define DebandSampleCount 8 //[1 to 8] Sample count, higher values are better. But also have a higher performance cost.
- #define DebandOffsetMode 3 //[1|2|3] 1 = cross (axis aligned, fast), 2 = diagonal (45 degrees, slower), 3 = box (fully random, slower).
- #define DebandDithering 3 //[0|1|2|3] Additional dithering options to smoothen the output. 0 = No dithering 1 = Ordered dithering, 2 = Random dithering, 3 = Iestyn's RGB dither (Valve).
- //##[SUBPIXEL_DITHERING]
- #define DitherMethod 2 //[1 or 2] The type of dithering to use. 1: Ordered grid dithering(faster), 2: random dithering(higher quality).
- #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(0, 0) //[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]
- /*------------------------------------------------------------------------------
- [GLOBALS|FUNCTIONS]
- ------------------------------------------------------------------------------*/
- // HLSL --> GLSL
- #define float2 vec2
- #define float3 vec3
- #define float4 vec4
- #define uint2 uvec2
- #define uint3 uvec3
- #define uint4 uvec4
- #define int2 ivec2
- #define int3 ivec3
- #define int4 ivec4
- #define float1x1 mat1
- #define float2x2 mat2
- #define float3x3 mat3
- #define float4x4 mat4
- #define float4x3 mat4x3
- #define float3x4 mat3x4
- #define frac fract
- #define lerp mix
- #define fmod mod
- #define saturate(x) clamp(x, 0.0, 1.0)
- #define mul(x, y) (y * x)
- #define ddx dFdx
- #define ddy dFdy
- #define rsqrt inversesqrt
- #define SamplerState sampler2D
- //OGL2 Uniforms
- uniform vec4 OGL2Param;
- uniform vec4 OGL2Size;
- uniform vec4 OGL2InvSize;
- uniform sampler2D OGL2Texture;
- //VS --> PS
- in vec4 TexCoord;
- in vec4 Vertex;
- in vec3 eyeVect;
- in vec3 Normal;
- in vec4 rcpPos;
- in vec4 Position;
- in vec3 lightPos;
- in vec3 lightVect;
- in float Distance;
- //PS --> Output
- out vec4 FragColor;
- //Static vars
- float Epsilon = 1e-10;
- float2 screenSize = OGL2Size.xy;
- float2 pixelSize = OGL2InvSize.xy;
- float4 rcpFrame = float4(-0.50/OGL2Size.x, -0.50/OGL2Size.y, 0.50/OGL2Size.x, 0.50/OGL2Size.y);
- float4 rcpByTwo = float4(-2.00/OGL2Size.x, -2.00/OGL2Size.y, 2.00/OGL2Size.x, 2.00/OGL2Size.y);
- //Conversion matrices
- float3 RGBtoXYZ(float3 RGB)
- {
- const float3x3 m = float3x3(
- 0.6068909, 0.1735011, 0.2003480,
- 0.2989164, 0.5865990, 0.1144845,
- 0.0000000, 0.0660957, 1.1162243);
- return mul(m, RGB);
- }
- float3 XYZtoRGB(float3 XYZ)
- {
- const float3x3 m = float3x3(
- 1.9099961, -0.5324542, -0.2882091,
- -0.9846663, 1.9991710, -0.0283082,
- 0.0583056, -0.1183781, 0.8975535);
- return mul(m, XYZ);
- }
- float3 XYZtoSRGB(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);
- }
- 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;
- }
- 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 (HSP Color Model)
- //sqrt(0.299 * R^2 + 0.587 * G^2 + 0.114 * B^2)
- const float3 lumCoeff = float3(0.2126729, 0.7151522, 0.0721750);
- float AvgLuminance(float3 color)
- {
- return sqrt(dot(color * color, lumCoeff));
- }
- //Smoothstep alt
- float smootherstep(float a, float b, float x)
- {
- x = saturate((x - a) / (b - a));
- return x*x*x*(x*(x * 6 - 15) + 10);
- }
- //Check for OOB rgb clipping
- 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;
- }
- /*------------------------------------------------------------------------------
- [DLAA CODE SECTION]
- ------------------------------------------------------------------------------*/
- #if DLAA == 1
- vec4 sampleOffset(sampler2D tex, vec2 texcoord, vec2 pixelOffset)
- {
- return texture(tex, texcoord + pixelOffset * pixelSize);
- }
- vec3 DLAAPixelShader(vec4 color, vec2 texcoord)
- {
- vec4 SC = sampleOffset(OGL2Texture, texcoord.xy, vec2( 0.0, 0.0));
- vec4 HN = sampleOffset(OGL2Texture, texcoord.xy, vec2(-1.5, 0.0));
- vec4 HP = sampleOffset(OGL2Texture, texcoord.xy, vec2( 1.5, 0.0));
- vec4 VN = sampleOffset(OGL2Texture, texcoord.xy, vec2( 0.0, -1.5));
- vec4 VP = sampleOffset(OGL2Texture, texcoord.xy, vec2( 0.0, 1.5));
- vec4 sumH = HN + HP, sumV = VN + VP;
- vec4 diffH = abs(sumH - (2.0 * SC)) / 2.0, diffV = abs(sumH - (2.0 * SC)) / 2.0;
- float edgeH = AvgLuminance(diffH.xyz);
- float edgeV = AvgLuminance(diffV.xyz);
- float detectH = clamp((3.0 * edgeH) - 0.1, 0.0, 1.0);
- float detectV = clamp((3.0 * edgeV) - 0.1, 0.0, 1.0);
- vec4 averageH = (sumH + SC) / 3.0, averageV = (sumV + SC) / 3.0;
- float valueH = AvgLuminance(averageH.xyz);
- float valueV = AvgLuminance(averageV.xyz );
- float blurAmountHoriz = clamp(detectH / valueH , 0.0, 1.0);
- float blurAmountVert = clamp(detectV / valueV , 0.0, 1.0);
- vec4 result = mix(SC, averageH, blurAmountHoriz);
- result = mix(result, averageV, blurAmountVert);
- vec4 VNA = sampleOffset(OGL2Texture, texcoord.xy, vec2(0.0, -3.5));
- vec4 VNB = sampleOffset(OGL2Texture, texcoord.xy, vec2(0.0, -7.5));
- vec4 VPA = sampleOffset(OGL2Texture, texcoord.xy, vec2(0.0, 3.5));
- vec4 VPB = sampleOffset(OGL2Texture, texcoord.xy, vec2(0.0, 7.5));
- vec4 HNA = sampleOffset(OGL2Texture, texcoord.xy, vec2(-3.5, 0.0));
- vec4 HNB = sampleOffset(OGL2Texture, texcoord.xy, vec2(-7.5, 0.0));
- vec4 HPA = sampleOffset(OGL2Texture, texcoord.xy, vec2( 3.5, 0.0));
- vec4 HPB = sampleOffset(OGL2Texture, texcoord.xy, vec2( 7.5, 0.0));
- float passH = (HNB.a + HNA.a + SC.a + HPA.a + HPB.a) / 5.0;
- float passV = (VNB.a + VNA.a + SC.a + VPA.a + VPB.a ) / 5.0;
- passH = clamp(passH * 2.0 - 1.0 , 0.0, 1.0), passV = clamp(passV * 2.0 - 1.0 , 0.0, 1.0);
- float longEdge = max(passH, passV);
- if (longEdge > 1.0)
- {
- vec4 avgHorizLong = (HNB + HNA + SC + HPA + HPB) / 5.0;
- vec4 avgVertLong = (VNB + VNA + SC + VPA + VPB) / 5.0;
- float valueHorizLong = AvgLuminance(avgHorizLong.xyz);
- float valueVertLong = AvgLuminance(avgVertLong.xyz);
- vec4 SL = sampleOffset(OGL2Texture, texcoord.xy, vec2(-1.0, 0.0) );
- vec4 SR = sampleOffset(OGL2Texture, texcoord.xy, vec2( 1.0, 0.0) );
- vec4 SU = sampleOffset(OGL2Texture, texcoord.xy, vec2( 0.0, -1.0) );
- vec4 SD = sampleOffset(OGL2Texture, texcoord.xy, vec2( 0.0, 1.0) );
- float VC = AvgLuminance(SC.xyz);
- float VL = AvgLuminance(SL.xyz);
- float VR = AvgLuminance(SR.xyz);
- float VT = AvgLuminance(SU.xyz);
- float VB = AvgLuminance(SD.xyz);
- vec4 diffC = VC - vec4(VL, VT, VR, VB);
- float BL = clamp(0.0 + (valueVertLong - VL) / diffC.x , 0.0, 1.0);
- float BU = clamp(0.0 + (valueHorizLong - VT) / diffC.y , 0.0, 1.0);
- float BR = clamp(1.0 + (valueVertLong - VC) / diffC.z , 0.0, 1.0);
- float BD = clamp(1.0 + (valueHorizLong - VC) / diffC.w , 0.0, 1.0);
- vec4 blurAmounts = vec4(BL, BR, BU, BD);
- blurAmounts = (blurAmounts == vec4(0.0, 0.0, 0.0, 0.0)) ? vec4(1.0, 1.0, 1.0, 1.0) : blurAmounts;
- vec4 longBlurHoriz = mix(SL, SC, blurAmounts.x);
- longBlurHoriz = mix(SR, longBlurHoriz, blurAmounts.y);
- vec4 longBlurVert = mix(SU, SC, blurAmounts.z);
- longBlurVert = mix(SD, longBlurVert, blurAmounts.w);
- result = mix(result, longBlurHoriz, passV);
- result = mix(result, longBlurVert, passH);
- }
- color.rgb = result.rgb;
- return color.rgb;
- }
- vec4 DLAAPass(float4 color, float2 texcoord)
- {
- color.rgb = DLAAPixelShader(color, texcoord);
- color.a = AvgLuminance(color.rgb);
- return color;
- }
- #endif
- /*------------------------------------------------------------------------------
- [SSAA CODE SECTION]
- ------------------------------------------------------------------------------*/
- #if SSAA == 1
- vec4 SSAAPass(vec4 color, vec2 texcoord)
- {
- float t, l, r, b;
- vec2 w = vec2(FilterWidth) * pixelSize;
- t = AvgLuminance(texture(OGL2Texture, texcoord + vec2(0.0,-1.0) * w, 0.0).xyz),
- l = AvgLuminance(texture(OGL2Texture, texcoord + vec2(-1.0,0.0) * w, 0.0).xyz),
- r = AvgLuminance(texture(OGL2Texture, texcoord + vec2(1.0, 0.0) * w, 0.0).xyz),
- b = AvgLuminance(texture(OGL2Texture, texcoord + vec2(0.0, 1.0) * w, 0.0).xyz);
- vec2 n = vec2(-(t - b), r - l);
- float nl = length(n);
- if (nl < (1.0 / 16.0))
- return texture(OGL2Texture, texcoord, 0.0);
- else
- {
- n *= pixelSize / nl;
- vec4 o = texture(OGL2Texture, texcoord, 0.0),
- t0 = texture(OGL2Texture, texcoord + n * 0.5, 0.0) * 0.9,
- t1 = texture(OGL2Texture, texcoord - n * 0.5, 0.0) * 0.9,
- t2 = texture(OGL2Texture, texcoord + n, 0.0) * 0.75,
- t3 = texture(OGL2Texture, texcoord - n, 0.0) * 0.75;
- color = (o + t0 + t1 + t2 + t3) / 4.3;
- return color;
- }
- }
- #endif
- /*------------------------------------------------------------------------------
- [SFAA AA CODE SECTION]
- ------------------------------------------------------------------------------*/
- #if SFAA == 1
- // Ported from AA 1.5 by guest(r)
- vec3 SFAAFilter(sampler2D colorSampler, vec2 texcoord)
- {
- vec3 c11 = texture(colorSampler, gl_TexCoord[0].xy).xyz;
- vec3 s00 = texture(colorSampler, gl_TexCoord[1].xy).xyz;
- vec3 s20 = texture(colorSampler, gl_TexCoord[2].xy).xyz;
- vec3 s22 = texture(colorSampler, gl_TexCoord[3].xy).xyz;
- vec3 s02 = texture(colorSampler, gl_TexCoord[4].xy).xyz;
- vec3 c00 = texture(colorSampler, gl_TexCoord[5].xy).xyz;
- vec3 c22 = texture(colorSampler, gl_TexCoord[6].xy).xyz;
- vec3 c20 = texture(colorSampler, gl_TexCoord[5].zw).xyz;
- vec3 c02 = texture(colorSampler, gl_TexCoord[6].zw).xyz;
- vec3 c10 = texture(colorSampler, gl_TexCoord[1].zw).xyz;
- vec3 c21 = texture(colorSampler, gl_TexCoord[2].zw).xyz;
- vec3 c12 = texture(colorSampler, gl_TexCoord[3].zw).xyz;
- vec3 c01 = texture(colorSampler, gl_TexCoord[4].zw).xyz;
- vec3 dt = vec3(1.0, 1.0, 1.0);
- float d1 = dot(abs(c00-c22),dt) +0.001;
- float d2 = dot(abs(c20-c02),dt) +0.001;
- float hl = dot(abs(c01-c21),dt) +0.001;
- float vl = dot(abs(c10-c12),dt) +0.001;
- float m1 = dot(abs(s00-s22),dt) +0.001;
- float m2 = dot(abs(s02-s20),dt) +0.001;
- c11 = 0.5 * (m2*(s00+s22)+m1*(s02+s20))/(m1+m2);
- float k1 = hl+vl, k2 = d1+d2;
- vec3 t1 = (hl*(c10+c12)+vl*(c01+c21)+k1*c11)/(3.0*(hl+vl));
- vec3 t2 = (d1*(c20+c02)+d2*(c00+c22)+k2*c11)/(3.0*(d1+d2));
- k1 = dot(abs(t1-c11),dt) +0.001;
- k2 = dot(abs(t2-c11),dt) +0.001;
- c11 = (k1*t2 + k2*t1)/(k1+k2);
- vec3 mn1 = min(min(c00,c01),c02);
- vec3 mn2 = min(min(c10,c11),c12);
- vec3 mn3 = min(min(c20,c21),c22);
- vec3 mx1 = max(max(c00,c01),c02);
- vec3 mx2 = max(max(c10,c11),c12);
- vec3 mx3 = max(max(c20,c21),c22);
- mn1 = min(min(mn1,mn2),mn3);
- mx1 = max(max(mx1,mx2),mx3);
- vec3 dif1 = abs(c11-mn1) + 0.01 * dt; dif1*=dif1; k1=dot(dif1,dt);
- vec3 dif2 = abs(c11-mx1) + 0.01 * dt; dif2*=dif2; k2=dot(dif2,dt);
- return (k1*mx1+k2*mn1)/(k1+k2);
- }
- float4 SFAAPass(float4 color, float2 texcoord)
- {
- color.rgb = SFAAFilter(OGL2Texture, texcoord);
- color.a = AvgLuminance(color.rgb);
- return color;
- }
- #endif
- /*------------------------------------------------------------------------------
- [TEXTURE FILTERING FUNCTIONS]
- ------------------------------------------------------------------------------*/
- float BSpline(float x)
- {
- float f = x;
- if (f < 0.0)
- {
- f = -f;
- }
- if (f >= 0.0 && f <= 1.0)
- {
- return (2.0 / 3.0) + (0.5) * (f* f * f) - (f*f);
- }
- else if (f > 1.0 && f <= 2.0)
- {
- return 1.0 / 6.0 * pow((2.0 - f), 3.0);
- }
- return 1.0;
- }
- float CatMullRom(float x)
- {
- float b = 0.0;
- float c = 0.5;
- float f = x;
- if (f < 0.0)
- {
- f = -f;
- }
- if (f < 1.0)
- {
- return ((12.0 - 9.0 * b - 6.0 * c) *
- (f * f * f) + (-18.0 + 12.0 * b + 6.0 * c) *
- (f * f) + (6.0 - 2.0 * b)) / 6.0;
- }
- else if (f >= 1.0 && f < 2.0)
- {
- return ((-b - 6.0 * c) * (f * f * f) +
- (6.0 * b + 30.0 * c) *(f *f) +
- (-(12.0 * b) - 48.0 * c) * f +
- 8.0 * b + 24.0 * c) / 6.0;
- }
- else
- {
- return 0.0;
- }
- }
- float Bell(float x)
- {
- float f = (x / 2.0) * 1.5;
- if (f > -1.5 && f < -0.5)
- {
- return(0.5 * pow(f + 1.5, 2.0));
- }
- else if (f > -0.5 && f < 0.5)
- {
- return 3.0 / 4.0 - (f * f);
- }
- else if ((f > 0.5 && f < 1.5))
- {
- return(0.5 * pow(f - 1.5, 2.0));
- }
- return 0.0;
- }
- float Triangular(float x)
- {
- x = x / 2.0;
- if (x < 0.0)
- {
- return (x + 1.0);
- }
- else
- {
- return (1.0 - x);
- }
- return 0.0;
- }
- float Cubic(float coeff)
- {
- float4 n = float4(1.0, 2.0, 3.0, 4.0) - coeff;
- float4 s = n * n * n;
- float x = s.x;
- float y = s.y - 4.0 * s.x;
- float z = s.z - 4.0 * s.y + 6.0 * s.x;
- float w = 6.0 - x - y - z;
- return (x + y + z + w) / 4.0;
- }
- /*------------------------------------------------------------------------------
- [BILINEAR FILTERING CODE SECTION]
- ------------------------------------------------------------------------------*/
- #if BILINEAR_FILTERING == 1
- float4 SampleBiLinear(sampler2D texSample, float2 texcoord)
- {
- float texelSizeX = pixelSize.x;
- float texelSizeY = pixelSize.y;
- int nX = int(texcoord.x * screenSize.x);
- int nY = int(texcoord.y * screenSize.y);
- float2 uvCoord = float2((float(nX) + OffsetAmount) / screenSize.x, (float(nY) + OffsetAmount) / screenSize.y);
- // Take nearest two data in current row.
- float4 SampleA = texture(texSample, uvCoord);
- float4 SampleB = texture(texSample, uvCoord + float2(texelSizeX, 0.0));
- // Take nearest two data in bottom row.
- float4 SampleC = texture(texSample, uvCoord + float2(0.0, texelSizeY));
- float4 SampleD = texture(texSample, uvCoord + float2(texelSizeX, texelSizeY));
- float LX = frac(texcoord.x * screenSize.x); //Get Interpolation factor for X direction.
- // Interpolate in X direction.
- float4 InterpolateA = lerp(SampleA, SampleB, LX); //Top row in X direction.
- float4 InterpolateB = lerp(SampleC, SampleD, LX); //Bottom row in X direction.
- float LY = frac(texcoord.y * screenSize.y); //Get Interpolation factor for Y direction.
- return lerp(InterpolateA, InterpolateB, LY); //Interpolate in Y direction.
- }
- float4 BiLinearPass(float4 color, float2 texcoord)
- {
- float4 bilinear = SampleBiLinear(OGL2Texture, texcoord);
- color = lerp(color, bilinear, FilterStrength);
- return color;
- }
- #endif
- /*------------------------------------------------------------------------------
- [BICUBIC FILTERING CODE SECTION]
- ------------------------------------------------------------------------------*/
- #if BICUBIC_FILTERING == 1
- float4 BicubicFilter(sampler2D texSample, float2 texcoord)
- {
- float texelSizeX = pixelSize.x;
- float texelSizeY = pixelSize.y;
- float4 nSum = float4(0.0, 0.0, 0.0, 0.0);
- float4 nDenom = float4(0.0, 0.0, 0.0, 0.0);
- float a = frac(texcoord.x * screenSize.x);
- float b = frac(texcoord.y * screenSize.y);
- int nX = int(texcoord.x * screenSize.x);
- int nY = int(texcoord.y * screenSize.y);
- 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 = texture(texSample, uvCoord +
- float2(texelSizeX * float(m), texelSizeY * float(n)));
- float vc1 = Interpolation(float(m) - a);
- float4 vecCoeff1 = float4(vc1, vc1, vc1, vc1);
- 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;
- }
- float4 BiCubicPass(float4 color, float2 texcoord)
- {
- float4 bicubic = BicubicFilter(OGL2Texture, texcoord);
- color = lerp(color, bicubic, BicubicStrength);
- return color;
- }
- #endif
- /*------------------------------------------------------------------------------
- [DDT FILTERING CODE SECTION]
- ------------------------------------------------------------------------------*/
- #if DDTI_FILTERING == 1
- float3 Bilinear(float p, float q, float3 A, float3 B, float3 C, float3 D)
- {
- return ((1-p)*(1-q)*A + p*(1-q)*B + (1-p)*q*C + p*q*D);
- }
- float3 DDTFilter(sampler2D decal, float2 texcoord)
- {
- float2 ofx = float2(PixelShift, PixelShift);
- float2 pos = frac(gl_TexCoord[2].xy) - ofx;
- float2 dir = sign(pos); // dir = pixel direction
- float2 g1 = dir * gl_TexCoord[1].xy;
- float2 g2 = dir * gl_TexCoord[1].zw;
- float3 A = texture(decal, texcoord).xyz;
- float3 B = texture(decal, texcoord +g1).xyz;
- float3 C = texture(decal, texcoord +g2).xyz;
- float3 D = texture(decal, texcoord +g1+g2).xyz;
- float a = AvgLuminance(A);
- float b = AvgLuminance(B);
- float c = AvgLuminance(C);
- float d = AvgLuminance(D);
- float p = abs(pos.x), q = abs(pos.y);
- float k = distance(pos,g1), l = distance(pos,g2);
- float wd1 = abs(a-d), wd2 = abs(b-c);
- if (wd1 < wd2)
- {
- if (k < l)
- {
- C = A + D - B;
- }
- else
- {
- B = A + D - C;
- }
- }
- else if (wd1 > wd2)
- {
- D = B + C - A;
- }
- float3 color = Bilinear(p, q, A, B, C, D);
- return color;
- }
- float4 DDTPass(float4 color, float2 texcoord)
- {
- color.rgb = DDTFilter(OGL2Texture, texcoord);
- color.a = AvgLuminance(color.rgb);
- return color;
- }
- #endif
- /*------------------------------------------------------------------------------
- [GAUSSIAN FILTERING CODE SECTION]
- ------------------------------------------------------------------------------*/
- #if GAUSSIAN_FILTERING == 1
- float4 GaussianPass(float4 color, float2 texcoord)
- {
- if (screenSize.x < 1024 || screenSize.y < 1024)
- {
- pixelSize.x /= 2.0;
- pixelSize.y /= 2.0;
- }
- float2 dx = float2(pixelSize.x * GaussianSpread, 0.0);
- float2 dy = float2(0.0, pixelSize.y * GaussianSpread);
- float2 dx2 = 2.0 * dx;
- float2 dy2 = 2.0 * dy;
- float4 gaussian = texture(OGL2Texture, texcoord);
- gaussian += texture(OGL2Texture, texcoord - dx2 + dy2);
- gaussian += texture(OGL2Texture, texcoord - dx + dy2);
- gaussian += texture(OGL2Texture, texcoord + dy2);
- gaussian += texture(OGL2Texture, texcoord + dx + dy2);
- gaussian += texture(OGL2Texture, texcoord + dx2 + dy2);
- gaussian += texture(OGL2Texture, texcoord - dx2 + dy);
- gaussian += texture(OGL2Texture, texcoord - dx + dy);
- gaussian += texture(OGL2Texture, texcoord + dy);
- gaussian += texture(OGL2Texture, texcoord + dx + dy);
- gaussian += texture(OGL2Texture, texcoord + dx2 + dy);
- gaussian += texture(OGL2Texture, texcoord - dx2);
- gaussian += texture(OGL2Texture, texcoord - dx);
- gaussian += texture(OGL2Texture, texcoord + dx);
- gaussian += texture(OGL2Texture, texcoord + dx2);
- gaussian += texture(OGL2Texture, texcoord - dx2 - dy);
- gaussian += texture(OGL2Texture, texcoord - dx - dy);
- gaussian += texture(OGL2Texture, texcoord - dy);
- gaussian += texture(OGL2Texture, texcoord + dx - dy);
- gaussian += texture(OGL2Texture, texcoord + dx2 - dy);
- gaussian += texture(OGL2Texture, texcoord - dx2 - dy2);
- gaussian += texture(OGL2Texture, texcoord - dx - dy2);
- gaussian += texture(OGL2Texture, texcoord - dy2);
- gaussian += texture(OGL2Texture, texcoord + dx - dy2);
- gaussian += texture(OGL2Texture, texcoord + dx2 - dy2);
- gaussian /= 25.0;
- color = lerp(color, gaussian, FilterAmount);
- return color;
- }
- #endif
- /*------------------------------------------------------------------------------
- [BILATERAL FILTERING CODE SECTION]
- ------------------------------------------------------------------------------*/
- #if BILATERAL_FILTERING || BilateralSampling == 1
- // Adapated from LibRetro (Bilateral v1.0 by Sp00kyFox)
- #define CWGHT 0.25 // color weight threshold
- #define TEX(dx, dy) texture(bTex, texcoord + float2(dx, dy) * pixelSize)
- float Dist(float3 pt1, float3 pt2)
- {
- float3 v = pt1 - pt2;
- return dot(v,v);
- }
- float sigma = BilateralRadius * BilateralRadius / 2.0;
- float cwght = 1.0 + CWGHT * max(1.0, 2.87029746 * sigma + 0.43165242 * BilateralRadius - 0.25219746);
- float4 Weight(int i, int j, float3 org, float4x3 A)
- {
- float clr = -BilateralWeight * BilateralWeight;
- float domain[13] = float[](1.0,
- exp( -1.0/sigma), exp( -4.0/sigma), exp( -9.0/sigma), exp( -16.0/sigma), exp( -25.0/sigma), exp( -36.0/sigma),
- exp(-49.0/sigma), exp(-64.0/sigma), exp(-81.0/sigma), exp(-100.0/sigma), exp(-121.0/sigma), exp(-144.0/sigma));
- float4 weight = domain[i] * domain[j] * exp(
- float4(Dist(org, A[0]), Dist(org, A[1]), Dist(org, A[2]), Dist(org, A[3])) / clr);
- return weight;
- }
- float3 BilateralFilter(sampler2D bTex, float2 texcoord)
- {
- float4x3 A, B;
- float norm = cwght;
- float4 WX, WY, V4 = float4(1.0, 1.0, 1.0, 1.0);
- float3 org = TEX(0.0, 0.0).rgb, result = cwght * org;
- float steps = ceil(BilateralRadius);
- for(int x = 1; x <= steps; x++)
- {
- A = float4x3(TEX( x, 0).rgb, TEX(-x, 0).rgb, TEX( 0, x).rgb, TEX( 0,-x).rgb);
- B = float4x3(TEX( x, x).rgb, TEX( x,-x).rgb, TEX(-x, x).rgb, TEX(-x,-x).rgb);
- WX = Weight(x, 0, org, A); WY = Weight(x, x, org, B);
- result += mul(WX, A) + mul(WY, B);
- norm += dot(WX, V4) + dot(WY, V4);
- for(int y = 1; y < x; y++)
- {
- A = float4x3(TEX( x, y).rgb, TEX( x,-y).rgb, TEX(-x, y).rgb, TEX(-x,-y).rgb);
- B = float4x3(TEX( y, x).rgb, TEX( y,-x).rgb, TEX(-y, x).rgb, TEX(-y,-x).rgb);
- WX = Weight(x, y, org, A); WY = Weight(y, x, org, B);
- result += mul(WX, A) + mul(WY, B);
- norm += dot(WX, V4) + dot(WY, V4);
- }
- }
- return result/norm;
- }
- float4 BilateralPass(float4 color, float2 texcoord)
- {
- color.rgb = BilateralFilter(OGL2Texture, texcoord);
- color.a = AvgLuminance(color.rgb);
- return color;
- }
- #endif
- /*------------------------------------------------------------------------------
- [xBR LV2 3D CODE SECTION]
- ------------------------------------------------------------------------------*/
- #if XBRV == 1 || xBRlv2Sampling == 1
- #define XBR_RES SampleScale
- #define TEX_SIZEX (1024.0 * XBR_RES)
- #define TEX_SIZEY (512.0 * XBR_RES)
- #if DetectionType == 1
- #define CORNER_A
- #elif DetectionType == 2
- #define CORNER_B
- #elif DetectionType == 3
- #define CORNER_C
- #else
- #define CORNER_D
- #endif
- #ifndef CORNER_A
- #define SMOOTH_TIPS
- #endif
- #define XBR_SCALE ScaleFactor
- #define XBR_EQ_THRESHOLD 15.0
- #define lv2_cf 4.0
- const vec3 rgbw = vec3(14.352, 28.176, 5.472);
- const vec4 delta = vec4(1.0/XBR_SCALE, 1.0/XBR_SCALE, 1.0/XBR_SCALE, 1.0/XBR_SCALE);
- const vec4 delta_l = vec4(0.5/XBR_SCALE, 1.0/XBR_SCALE, 0.5/XBR_SCALE, 1.0/XBR_SCALE);
- const vec4 delta_u = delta_l.yxwz;
- const vec2 OGLSize = vec2(1024.0, 512.0);
- const vec2 OGLInvSize = 1.0/OGLSize;
- const vec2 dx = vec2( XBR_RES/TEX_SIZEX, 0.0);
- const vec2 dy = vec2( 0.0, XBR_RES/TEX_SIZEY);
- const vec4 Ao = vec4( 1.0, -1.0, -1.0, 1.0 );
- const vec4 Bo = vec4( 1.0, 1.0, -1.0,-1.0 );
- const vec4 Co = vec4( 1.5, 0.5, -0.5, 0.5 );
- const vec4 Ax = vec4( 1.0, -1.0, -1.0, 1.0 );
- const vec4 Bx = vec4( 0.5, 2.0, -0.5,-2.0 );
- const vec4 Cx = vec4( 1.0, 1.0, -0.5, 0.0 );
- const vec4 Ay = vec4( 1.0, -1.0, -1.0, 1.0 );
- const vec4 By = vec4( 2.0, 0.5, -2.0,-0.5 );
- const vec4 Cy = vec4( 2.0, 0.0, -1.0, 0.5 );
- const vec4 Ci = vec4(0.25, 0.25, 0.25, 0.25);
- // Difference between vector components.
- vec4 df(vec4 A, vec4 B)
- {
- return vec4(abs(A-B));
- }
- // Compare two vectors and return their components are different.
- vec4 diff(vec4 A, vec4 B)
- {
- return vec4(notEqual(A, B));
- }
- // Determine if two vector components are equal based on a threshold.
- vec4 eq(vec4 A, vec4 B)
- {
- return (step(df(A, B), vec4(XBR_EQ_THRESHOLD)));
- }
- // Determine if two vector components are NOT equal based on a threshold.
- vec4 neq(vec4 A, vec4 B)
- {
- return (vec4(1.0, 1.0, 1.0, 1.0) - eq(A, B));
- }
- // Weighted distance.
- vec4 wd(vec4 a, vec4 b, vec4 c, vec4 d, vec4 e, vec4 f, vec4 g, vec4 h)
- {
- return (df(a,b) + df(a,c) + df(d,e) + df(d,f) + 4.0*df(g,h));
- }
- float c_df(vec3 c1, vec3 c2)
- {
- vec3 df = abs(c1 - c2);
- return df.r + df.g + df.b;
- }
- vec3 xBRvFilter(sampler2D tex, vec2 texcoord)
- {
- vec4 edri, edr, edr_l, edr_u, px; // px = pixel, edr = edge detection rule
- vec4 irlv0, irlv1, irlv2l, irlv2u, block_3d;
- vec4 fx, fx_l, fx_u; // inequations of straight lines.
- vec2 fp = fract(texcoord * OGLSize);
- vec2 uv = (floor(texcoord * OGLSize) + vec2(0.5, 0.5))/OGLSize;
- vec3 A1 = texture(tex, gl_TexCoord[1].xw ).xyz;
- vec3 B1 = texture(tex, gl_TexCoord[1].yw ).xyz;
- vec3 C1 = texture(tex, gl_TexCoord[1].zw ).xyz;
- vec3 A = texture(tex, gl_TexCoord[2].xw ).xyz;
- vec3 B = texture(tex, gl_TexCoord[2].yw ).xyz;
- vec3 C = texture(tex, gl_TexCoord[2].zw ).xyz;
- vec3 D = texture(tex, gl_TexCoord[3].xw ).xyz;
- vec3 E = texture(tex, gl_TexCoord[3].yw ).xyz;
- vec3 F = texture(tex, gl_TexCoord[3].zw ).xyz;
- vec3 G = texture(tex, gl_TexCoord[4].xw ).xyz;
- vec3 H = texture(tex, gl_TexCoord[4].yw ).xyz;
- vec3 I = texture(tex, gl_TexCoord[4].zw ).xyz;
- vec3 G5 = texture(tex, gl_TexCoord[5].xw ).xyz;
- vec3 H5 = texture(tex, gl_TexCoord[5].yw ).xyz;
- vec3 I5 = texture(tex, gl_TexCoord[5].zw ).xyz;
- vec3 A0 = texture(tex, gl_TexCoord[6].xy ).xyz;
- vec3 D0 = texture(tex, gl_TexCoord[6].xz ).xyz;
- vec3 G0 = texture(tex, gl_TexCoord[6].xw ).xyz;
- vec3 C4 = texture(tex, gl_TexCoord[7].xy ).xyz;
- vec3 F4 = texture(tex, gl_TexCoord[7].xz ).xyz;
- vec3 I4 = texture(tex, gl_TexCoord[7].xw ).xyz;
- vec3 E6 = texture(tex, uv +0.25*dx +0.25*dy).xyz;
- vec3 E7 = texture(tex, uv +0.25*dx -0.25*dy).xyz;
- vec3 E8 = texture(tex, uv -0.25*dx -0.25*dy).xyz;
- vec3 E9 = texture(tex, uv -0.25*dx +0.25*dy).xyz;
- vec3 F6 = texture(tex, uv +dx+0.25*dx +0.25*dy).xyz;
- vec3 F7 = texture(tex, uv +dx+0.25*dx -0.25*dy).xyz;
- vec3 F8 = texture(tex, uv +dx-0.25*dx -0.25*dy).xyz;
- vec3 F9 = texture(tex, uv +dx-0.25*dx +0.25*dy).xyz;
- vec3 B6 = texture(tex, uv +0.25*dx +0.25*dy-dy).xyz;
- vec3 B7 = texture(tex, uv +0.25*dx -0.25*dy-dy).xyz;
- vec3 B8 = texture(tex, uv -0.25*dx -0.25*dy-dy).xyz;
- vec3 B9 = texture(tex, uv -0.25*dx +0.25*dy-dy).xyz;
- vec3 D6 = texture(tex, uv -dx+0.25*dx +0.25*dy).xyz;
- vec3 D7 = texture(tex, uv -dx+0.25*dx -0.25*dy).xyz;
- vec3 D8 = texture(tex, uv -dx-0.25*dx -0.25*dy).xyz;
- vec3 D9 = texture(tex, uv -dx-0.25*dx +0.25*dy).xyz;
- vec3 H6 = texture(tex, uv +0.25*dx +0.25*dy+dy).xyz;
- vec3 H7 = texture(tex, uv +0.25*dx -0.25*dy+dy).xyz;
- vec3 H8 = texture(tex, uv -0.25*dx -0.25*dy+dy).xyz;
- vec3 H9 = texture(tex, uv -0.25*dx +0.25*dy+dy).xyz;
- vec4 b = vec4(dot(B ,rgbw), dot(D ,rgbw), dot(H ,rgbw), dot(F ,rgbw));
- vec4 c = vec4(dot(C ,rgbw), dot(A ,rgbw), dot(G ,rgbw), dot(I ,rgbw));
- vec4 d = b.yzwx;
- vec4 e = vec4(dot(E,rgbw));
- vec4 f = b.wxyz;
- vec4 g = c.zwxy;
- vec4 h = b.zwxy;
- vec4 i = c.wxyz;
- vec4 i4 = vec4(dot(I4,rgbw), dot(C1,rgbw), dot(A0,rgbw), dot(G5,rgbw));
- vec4 i5 = vec4(dot(I5,rgbw), dot(C4,rgbw), dot(A1,rgbw), dot(G0,rgbw));
- vec4 h5 = vec4(dot(H5,rgbw), dot(F4,rgbw), dot(B1,rgbw), dot(D0,rgbw));
- vec4 f4 = h5.yzwx;
- vec4 f0 = vec4(dot(F6,rgbw), dot(B6,rgbw), dot(D6,rgbw), dot(H6,rgbw));
- vec4 f1 = vec4(dot(F7,rgbw), dot(B7,rgbw), dot(D7,rgbw), dot(H7,rgbw));
- vec4 f2 = vec4(dot(F8,rgbw), dot(B8,rgbw), dot(D8,rgbw), dot(H8,rgbw));
- vec4 f3 = vec4(dot(F9,rgbw), dot(B9,rgbw), dot(D9,rgbw), dot(H9,rgbw));
- vec4 h0 = f0.wxyz;
- vec4 h1 = f1.wxyz;
- vec4 h2 = f2.wxyz;
- vec4 h3 = f3.wxyz;
- vec4 e0 = vec4(dot(E6,rgbw), dot(E7,rgbw), dot(E8,rgbw), dot(E9,rgbw));
- // These inequations define the line below which interpolation occurs.
- fx = (Ao*fp.y+Bo*fp.x);
- fx_l = (Ax*fp.y+Bx*fp.x);
- fx_u = (Ay*fp.y+By*fp.x);
- block_3d = vec4(equal(f0,f1))*vec4(equal(f1,f2))*vec4(equal(f2,f3))*
- vec4(equal(h0,h1))*vec4(equal(h1,h2))*vec4(equal(h2,h3));
- irlv1 = irlv0 = block_3d * diff(e,f) * diff(e,h);
- #ifdef CORNER_B
- irlv1 = (irlv0 * (neq(f,b) * neq(h,d) + eq(e,i) * neq(f,i4) * neq(h,i5) + eq(e,g) + eq(e,c)));
- #endif
- #ifdef CORNER_D
- vec4 c1 = i4.yzwx;
- vec4 g0 = i5.wxyz;
- irlv1 = (irlv0 * (neq(f,b) * neq(h,d) + eq(e,i) * neq(f,i4) * neq(h,i5) + eq(e,g) + eq(e,c) ) * (
- diff(f,f4) * diff(f,i) + diff(h,h5) * diff(h,i) + diff(h,g) + diff(f,c) + eq(b,c1) * eq(d,g0)));
- #endif
- #ifdef CORNER_C
- irlv1 = (irlv0 * ( neq(f,b) * neq(f,c) + neq(h,d) * neq(h,g) + eq(e,i) * (
- neq(f,f4) * neq(f,i4) + neq(h,h5) * neq(h,i5)) + eq(e,g) + eq(e,c)));
- #endif
- irlv2l = diff(e,g) * diff(d,g);
- irlv2u = diff(e,c) * diff(b,c);
- vec4 fx45i = clamp((fx + delta -Co - Ci)/(2*delta ), 0.0, 1.0);
- vec4 fx45 = clamp((fx + delta -Co )/(2*delta ), 0.0, 1.0);
- vec4 fx30 = clamp((fx_l + delta_l -Cx )/(2*delta_l), 0.0, 1.0);
- vec4 fx60 = clamp((fx_u + delta_u -Cy )/(2*delta_u), 0.0, 1.0);
- vec4 wd1 = wd( e, c, g, i, h5, f4, h, f);
- vec4 wd2 = wd( h, d, i5, f, i4, b, e, i);
- edri = step(wd1, wd2) * irlv0;
- edr = step(wd1 + vec4(0.1, 0.1, 0.1, 0.1), wd2) * step(vec4(0.5, 0.5, 0.5, 0.5), irlv1);
- edr_l = step(lv2_cf*df(f,g), df(h,c) ) * irlv2l * edr;
- edr_u = step(lv2_cf*df(h,c), df(f,g) ) * irlv2u * edr;
- fx45 = edr * fx45;
- fx30 = edr_l * fx30;
- fx60 = edr_u * fx60;
- fx45i = edri * fx45i;
- px = step(df(e,f), df(e,h));
- #ifdef SMOOTH_TIPS
- vec4 maximos = max(max(fx30, fx60), max(fx45, fx45i));
- #endif
- #ifndef SMOOTH_TIPS
- vec4 maximos = max(max(fx30, fx60), fx45);
- #endif
- vec3 res1 = E;
- res1 = mix(res1, mix(H, F, px.x), maximos.x);
- res1 = mix(res1, mix(B, D, px.z), maximos.z);
- vec3 res2 = E;
- res2 = mix(res2, mix(F, B, px.y), maximos.y);
- res2 = mix(res2, mix(D, H, px.w), maximos.w);
- vec3 res = mix(res1, res2, step(c_df(E, res1), c_df(E, res2)));
- return res;
- }
- float4 xBRPass(float4 color, float2 texcoord)
- {
- color.rgb = xBRvFilter(OGL2Texture, texcoord);
- color.a = AvgLuminance(color.rgb);
- return color;
- }
- #endif
- /*------------------------------------------------------------------------------
- [FXAA CODE SECTION]
- ------------------------------------------------------------------------------*/
- #if FXAA == 1
- #if FxaaQuality == 4
- #define FxaaEdgeThreshold 0.063
- #define FxaaEdgeThresholdMin 0.000
- #elif FxaaQuality == 3
- #define FxaaEdgeThreshold 0.125
- #define FxaaEdgeThresholdMin 0.0312
- #elif FxaaQuality == 2
- #define FxaaEdgeThreshold 0.166
- #define FxaaEdgeThresholdMin 0.0625
- #elif FxaaQuality == 1
- #define FxaaEdgeThreshold 0.250
- #define FxaaEdgeThresholdMin 0.0833
- #endif
- uniform float maxSpan = FxaaSubpixMax;
- uniform float mulReduce = FxaaEdgeThreshold;
- uniform float minReduce = FxaaEdgeThresholdMin;
- vec3 FxaaPixelShader(vec2 texcoord, vec4 pos, vec2 texelStep)
- {
- vec3 rgbM = texture(OGL2Texture, texcoord).rgb;
- // Sampling neighbour texels. Offsets are adapted to OpenGL texture coordinates.
- vec3 rgbNW = textureOffset(OGL2Texture, pos.zw, ivec2(0, 0)).rgb;
- vec3 rgbNE = textureOffset(OGL2Texture, pos.zw, ivec2(1, 0)).rgb;
- vec3 rgbSW = textureOffset(OGL2Texture, pos.zw, ivec2(0, 1)).rgb;
- vec3 rgbSE = textureOffset(OGL2Texture, pos.zw, ivec2(1, 1)).rgb;
- // Convert from RGB to luma.
- float lumaNW = AvgLuminance(rgbNW);
- float lumaNE = AvgLuminance(rgbNE);
- float lumaSW = AvgLuminance(rgbSW);
- float lumaSE = AvgLuminance(rgbSE);
- float lumaM = AvgLuminance(rgbM);
- // Gather minimum and maximum luma.
- float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
- float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
- // Sampling is done along the gradient.
- vec2 direction;
- direction.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
- direction.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
- // Sampling step distance depends on the luma: brighter areas are sharper than dark areas.
- float samplingDirectionReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * 0.25 * mulReduce, minReduce);
- // Factor for norming the sampling direction plus adding the brightness influence.
- float minSamplingDirectionFactor = 1.0 / (min(abs(direction.x), abs(direction.y)) + samplingDirectionReduce);
- // Calculate final sampling direction vector by reducing, clamping to a range and finally adapting to the texture size.
- direction = clamp(direction * minSamplingDirectionFactor, vec2(-maxSpan, -maxSpan), vec2(maxSpan, maxSpan)) * texelStep;
- // Inner samples.
- #if BilateralSampling == 1
- vec3 rgbSampleNeg = BilateralFilter(OGL2Texture, texcoord + direction * (1.0/3.0 - 0.5)).rgb;
- vec3 rgbSamplePos = BilateralFilter(OGL2Texture, texcoord + direction * (2.0/3.0 - 0.5)).rgb;
- #else
- vec3 rgbSampleNeg = texture(OGL2Texture, texcoord + direction * (1.0/3.0 - 0.5)).rgb;
- vec3 rgbSamplePos = texture(OGL2Texture, texcoord + direction * (2.0/3.0 - 0.5)).rgb;
- #endif
- vec3 rgbTwoTab = (rgbSamplePos + rgbSampleNeg) * 0.5;
- // Outer samples.
- vec3 rgbSampleNegOuter = texture(OGL2Texture, texcoord + direction * (0.0/3.0 - 0.5)).rgb;
- vec3 rgbSamplePosOuter = texture(OGL2Texture, texcoord + direction * (3.0/3.0 - 0.5)).rgb;
- vec3 rgbFourTab = (rgbSamplePosOuter + rgbSampleNegOuter) * 0.25 + rgbTwoTab * 0.5;
- // Calculate luma for checking against the minimum and maximum value.
- float lumaFourTab = AvgLuminance(rgbFourTab);
- // Are outer samples of the tab beyond the edge ...
- if (lumaFourTab < lumaMin || lumaFourTab > lumaMax) return rgbTwoTab; // two samples.
- else return rgbFourTab; // four samples.
- }
- #if xBRlv2Sampling == 1
- float diff2D(vec2 coord)
- {
- const vec3 dt = vec3(1.0, 1.0, 1.0);
- vec3 c00 = texture(OGL2Texture, coord + 0.25 * (-dx-dy)).xyz;
- vec3 c20 = texture(OGL2Texture, coord + 0.25 * ( dx-dy)).xyz;
- vec3 c02 = texture(OGL2Texture, coord + 0.25 * (-dx+dy)).xyz;
- vec3 c22 = texture(OGL2Texture, coord + 0.25 * ( dx+dy)).xyz;
- vec3 mn = min(min(c00, c20), min(c02, c22));
- vec3 mx = max(max(c00, c20), max(c02, c22));
- return dot(mx-mn, dt);
- }
- vec3 MergeXBR(vec3 color, vec2 texcoord)
- {
- const float xbrthreshold = xBRThreshold;
- vec2 fp = fract(texcoord * OGLSize);
- vec2 tex = texcoord - fp * OGLInvSize + 0.5 * OGLInvSize;
- vec2 locator = sign(fp - vec2(0.5000000001, 0.5000000001)); //fractional driver bug workaround?
- float maxdiff = max(max(diff2D(tex+locator*dx), diff2D(tex+locator*dy)), diff2D(tex));
- if (maxdiff <= xbrthreshold) { color = xBRvFilter(OGL2Texture, texcoord);}
- else { color = FxaaPixelShader(texcoord, rcpPos, pixelSize); }
- return color;
- }
- #endif
- vec4 FXAAPass(float4 Fxaa, vec2 texcoord)
- {
- #if xBRlv2Sampling == 1
- Fxaa.rgb = MergeXBR(Fxaa.rgb, texcoord);
- #else
- Fxaa.rgb = FxaaPixelShader(texcoord, rcpPos, pixelSize);
- #endif
- Fxaa.a = AvgLuminance(Fxaa.rgb);
- return Fxaa;
- }
- #endif
- /*------------------------------------------------------------------------------
- [BICUBIC SCALER CODE SECTION]
- ------------------------------------------------------------------------------*/
- #if BICUBLIC_SCALER == 1
- float4 BicubicScaler(sampler2D tex, float2 uv, float2 texSize)
- {
- float2 inputSize = float2(1.0/texSize.x, 1.0/texSize.y);
- float2 coord_hg = uv * texSize - 0.5;
- float2 index = floor(coord_hg);
- float2 f = coord_hg - index;
- 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 );
- M /= 6.0;
- float4 wx = mul(float4(f.x*f.x*f.x, f.x*f.x, f.x, 1.0), M);
- float4 wy = mul(float4(f.y*f.y*f.y, f.y*f.y, f.y, 1.0), M);
- float2 w0 = float2(wx.x, wy.x);
- float2 w1 = float2(wx.y, wy.y);
- float2 w2 = float2(wx.z, wy.z);
- float2 w3 = float2(wx.w, wy.w);
- float2 g0 = w0 + w1;
- float2 g1 = w2 + w3;
- float2 h0 = w1 / g0 - 1.0;
- float2 h1 = w3 / g1 + 1.0;
- float2 coord00 = index + h0;
- float2 coord10 = index + float2(h1.x, h0.y);
- float2 coord01 = index + float2(h0.x, h1.y);
- float2 coord11 = index + h1;
- coord00 = (coord00 + 0.5) * inputSize;
- coord10 = (coord10 + 0.5) * inputSize;
- coord01 = (coord01 + 0.5) * inputSize;
- coord11 = (coord11 + 0.5) * inputSize;
- float4 tex00 = texture(tex, coord00);
- float4 tex10 = texture(tex, coord10);
- float4 tex01 = texture(tex, coord01);
- float4 tex11 = texture(tex, coord11);
- tex00 = lerp(tex01, tex00, float4(g0.y, g0.y, g0.y, g0.y));
- tex10 = lerp(tex11, tex10, float4(g0.y, g0.y, g0.y, g0.y));
- float4 res = lerp(tex10, tex00, float4(g0.x, g0.x, g0.x, g0.x));
- return res;
- }
- float4 BiCubicScalerPass(float4 color, float2 texcoord)
- {
- color = BicubicScaler(OGL2Texture, texcoord, screenSize);
- return color;
- }
- #endif
- /*------------------------------------------------------------------------------
- [LANCZOS SCALER CODE SECTION]
- ------------------------------------------------------------------------------*/
- #if LANCZOS_SCALER == 1
- float3 PixelPos(float xpos, float ypos)
- {
- return texture(OGL2Texture, float2(xpos, ypos)).rgb;
- }
- float4 WeightQuad(float x)
- {
- #define FIX(c) max(abs(c), 1e-5);
- const float PI = 3.1415926535897932384626433832795;
- float4 weight = FIX(PI * float4(1.0 + x, x, 1.0 - x, 2.0 - x));
- float4 ret = sin(weight) * sin(weight / 2.0) / (weight * weight);
- return ret / dot(ret, float4(1.0, 1.0, 1.0, 1.0));
- }
- float3 LineRun(float ypos, float4 xpos, float4 linetaps)
- {
- return mul(linetaps, float4x3(
- PixelPos(xpos.x, ypos),
- PixelPos(xpos.y, ypos),
- PixelPos(xpos.z, ypos),
- PixelPos(xpos.w, ypos)));
- }
- float4 LanczosScaler(float2 texcoord, float2 inputSize)
- {
- float2 stepxy = float2(1.0/inputSize.x, 1.0/inputSize.y);
- float2 pos = texcoord + stepxy;
- float2 f = frac(pos / stepxy);
- float2 xystart = (-2.0 - f) * stepxy + pos;
- float4 xpos = float4(xystart.x,
- xystart.x + stepxy.x,
- xystart.x + stepxy.x * 2.0,
- xystart.x + stepxy.x * 3.0);
- float4 linetaps = WeightQuad(f.x);
- float4 columntaps = WeightQuad(f.y);
- // final sum and weight normalization
- return float4(mul(columntaps, float4x3(
- LineRun(xystart.y, xpos, linetaps),
- LineRun(xystart.y + stepxy.y, xpos, linetaps),
- LineRun(xystart.y + stepxy.y * 2.0, xpos, linetaps),
- LineRun(xystart.y + stepxy.y * 3.0, xpos, linetaps))), 1.0);
- }
- float4 LanczosScalerPass(float4 color, float2 texcoord)
- {
- color = LanczosScaler(texcoord, screenSize);
- return color;
- }
- #endif
- /*------------------------------------------------------------------------------
- [GAMMA CORRECTION CODE SECTION]
- ------------------------------------------------------------------------------*/
- float3 EncodeGamma(float3 color, float gamma)
- {
- color = saturate(color);
- color.r = (color.r <= 0.0404482362771082) ?
- color.r / 12.92 : pow((color.r + 0.055) / 1.055, gamma);
- color.g = (color.g <= 0.0404482362771082) ?
- color.g / 12.92 : pow((color.g + 0.055) / 1.055, gamma);
- color.b = (color.b <= 0.0404482362771082) ?
- color.b / 12.92 : pow((color.b + 0.055) / 1.055, gamma);
- return color;
- }
- float3 DecodeGamma(float3 color, float gamma)
- {
- color = saturate(color);
- color.r = (color.r <= 0.00313066844250063) ?
- color.r * 12.92 : 1.055 * pow(color.r, 1.0 / gamma) - 0.055;
- color.g = (color.g <= 0.00313066844250063) ?
- color.g * 12.92 : 1.055 * pow(color.g, 1.0 / gamma) - 0.055;
- color.b = (color.b <= 0.00313066844250063) ?
- color.b * 12.92 : 1.055 * pow(color.b, 1.0 / gamma) - 0.055;
- return color;
- }
- #if GAMMA_CORRECTION == 1
- float4 GammaPass(float4 color, float2 texcoord)
- {
- 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(sampler2D texSample, float2 texcoord)
- {
- float texelSizeX = pixelSize.x * float(SharpenBias);
- float texelSizeY = pixelSize.y * float(SharpenBias);
- float4 nSum = float4(0.0, 0.0, 0.0, 0.0);
- float4 nDenom = float4(0.0, 0.0, 0.0, 0.0);
- float a = frac(texcoord.x * screenSize.x);
- float b = frac(texcoord.y * screenSize.y);
- int nX = int(texcoord.x * screenSize.x);
- int nY = int(texcoord.y * screenSize.y);
- 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 = texture(texSample, uvCoord +
- float2(texelSizeX * float(m), texelSizeY * float(n)));
- float vc1 = Cubic(float(m) - a);
- float4 vecCoeff1 = float4(vc1, vc1, vc1, vc1);
- 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;
- }
- float4 TexSharpenPass(float4 color, float2 texcoord)
- {
- float3 calcSharpen = lumCoeff * float(SharpenStrength);
- float4 blurredColor = SampleBicubic(OGL2Texture, texcoord);
- float3 sharpenedColor = (color.rgb - blurredColor.rgb);
- float sharpenLuma = dot(sharpenedColor, calcSharpen);
- sharpenLuma = clamp(sharpenLuma, -float(SharpenClamp), float(SharpenClamp));
- color.rgb = color.rgb + sharpenLuma;
- color.a = AvgLuminance(color.rgb);
- #if DebugSharpen == 1
- color = saturate(0.5f + float4(sharpenLuma * 4));
- #endif
- return saturate(color);
- }
- #endif
- /*------------------------------------------------------------------------------
- [PIXEL VIBRANCE CODE SECTION]
- ------------------------------------------------------------------------------*/
- #if PIXEL_VIBRANCE == 1
- float4 VibrancePass(float4 color, float2 texcoord)
- {
- float vib = Vibrance;
- float lum = AvgLuminance(color.rgb);
- float3 luma = float3(lum, lum, lum);
- float colorMax = max(color.r, max(color.g, color.b));
- 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 + (colorCoeff * (1.0 - (sign(colorCoeff) * colorSaturation)))));
- color.a = AvgLuminance(color.rgb);
- return saturate(color); //Debug: return colorSaturation.xxxx;
- }
- #endif
- /*------------------------------------------------------------------------------
- [BLENDED BLOOM CODE SECTION]
- ------------------------------------------------------------------------------*/
- #if BLENDED_BLOOM == 1
- float3 BlendAddLight(float3 bloom, float3 blend)
- {
- return saturate(bloom + blend);
- }
- float3 BlendScreen(float3 bloom, float3 blend)
- {
- return (bloom + blend) - (bloom * blend);
- }
- float3 BlendGlow(float3 bloom, float3 blend)
- {
- float glow = AvgLuminance(bloom);
- return lerp((bloom + blend) - (bloom * blend),
- (blend + blend) - (blend * blend), glow);
- }
- float3 BlendAddGlow(float3 bloom, float3 blend)
- {
- 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)
- {
- float lumavg = smootherstep(0.0, 1.0, AvgLuminance(bloom + blend));
- return lerp((bloom * blend), (1.0 -
- ((1.0 - bloom) * (1.0 - blend))), lumavg);
- }
- float3 BlendOverlay(float3 bloom, float3 blend)
- {
- float3 overlay = step(0.5, bloom);
- return lerp((bloom * blend * 2.0), (1.0 - (2.0 *
- (1.0 - bloom) * (1.0 - blend))), overlay);
- }
- float3 BloomCorrection(float3 color)
- {
- float3 bloom = color;
- 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 = bloom;
- return color;
- }
- float4 DefocusFilter(sampler2D tex, float2 texcoord, float2 defocus)
- {
- defocus = clamp(defocus, 1.0, 1.5);
- float2 texel = pixelSize * defocus;
- float4 sampleA = texture(tex, texcoord + float2(0.5, 0.5) * texel);
- float4 sampleB = texture(tex, texcoord + float2(-0.5, 0.5) * texel);
- float4 sampleC = texture(tex, texcoord + float2(0.5, -0.5) * texel);
- float4 sampleD = texture(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;
- float width = BloomWidth;
- float2 defocus = float2(BloomDefocus, BloomDefocus);
- float4 bloom = DefocusFilter(OGL2Texture, texcoord, defocus);
- float2 dx = float2(pixelSize.x * width, 0.0);
- float2 dy = float2(0.0, pixelSize.y * width);
- float2 mdx = float2(dx.x * defocus.x, 0.0);
- float2 mdy = float2(0.0, dy.y * defocus.y);
- float4 blend = bloom * 0.22520613262190495;
- blend += 0.002589001911021066 * texture(OGL2Texture, texcoord - mdx + mdy);
- blend += 0.010778807494659370 * texture(OGL2Texture, texcoord - dx + mdy);
- blend += 0.024146616900339800 * texture(OGL2Texture, texcoord + mdy);
- blend += 0.010778807494659370 * texture(OGL2Texture, texcoord + dx + mdy);
- blend += 0.002589001911021066 * texture(OGL2Texture, texcoord + mdx + mdy);
- blend += 0.010778807494659370 * texture(OGL2Texture, texcoord - mdx + dy);
- blend += 0.044875475183061630 * texture(OGL2Texture, texcoord - dx + dy);
- blend += 0.100529757860782610 * texture(OGL2Texture, texcoord + dy);
- blend += 0.044875475183061630 * texture(OGL2Texture, texcoord + dx + dy);
- blend += 0.010778807494659370 * texture(OGL2Texture, texcoord + mdx + dy);
- blend += 0.024146616900339800 * texture(OGL2Texture, texcoord - mdx);
- blend += 0.100529757860782610 * texture(OGL2Texture, texcoord - dx);
- blend += 0.100529757860782610 * texture(OGL2Texture, texcoord + dx);
- blend += 0.024146616900339800 * texture(OGL2Texture, texcoord + mdx);
- blend += 0.010778807494659370 * texture(OGL2Texture, texcoord - mdx - dy);
- blend += 0.044875475183061630 * texture(OGL2Texture, texcoord - dx - dy);
- blend += 0.100529757860782610 * texture(OGL2Texture, texcoord - dy);
- blend += 0.044875475183061630 * texture(OGL2Texture, texcoord + dx - dy);
- blend += 0.010778807494659370 * texture(OGL2Texture, texcoord + mdx - dy);
- blend += 0.002589001911021066 * texture(OGL2Texture, texcoord - mdx - mdy);
- blend += 0.010778807494659370 * texture(OGL2Texture, texcoord - dx - mdy);
- blend += 0.024146616900339800 * texture(OGL2Texture, texcoord - mdy);
- blend += 0.010778807494659370 * texture(OGL2Texture, texcoord + dx - mdy);
- blend += 0.002589001911021066 * texture(OGL2Texture, texcoord + mdx - mdy);
- blend = lerp(color, blend, float(BlendStrength));
- bloom.xyz = BloomType(bloom.xyz, blend.xyz);
- bloom.xyz = BloomCorrection(bloom.xyz);
- color.w = AvgLuminance(color.xyz);
- bloom.w = AvgLuminance(bloom.xyz);
- bloom.w *= anflare;
- color = lerp(color, bloom, float(BloomStrength));
- return color;
- }
- #endif
- /*------------------------------------------------------------------------------
- [SCENE TONE MAPPING CODE SECTION]
- ------------------------------------------------------------------------------*/
- #if SCENE_TONEMAPPING == 1
- float3 ScaleLuminance(float3 x)
- {
- float W = 1.02; // WhitePoint Scale
- float L = 0.16; // Luminance Scale
- float C = 1.02; // Compression Scale
- float N = clamp(0.82 + 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);
- float3 color;
- color.r = (x.r > L) ? tone.r : C * x.r;
- color.g = (x.g > L) ? tone.g : C * x.g;
- color.b = (x.b > L) ? tone.b : C * x.b;
- return color;
- }
- float3 TmMask(float3 color)
- {
- float3 tone = color;
- float highTone = 6.2; float greyTone = 0.4;
- float midTone = 1.62; 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);
- 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 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;
- }
- float4 TonemapPass(float4 color, float2 texcoord)
- {
- float L = Luminance;
- float3 tonemap = color.rgb;
- float3 luma = float3(L, L, L);
- float blackLevel = length(tonemap);
- tonemap = ScaleLuminance(tonemap);
- float luminanceAverage = AvgLuminance(luma);
- if (TonemapMask == 1) { tonemap = TmMask(tonemap); }
- if (TonemapType == 1) { tonemap = TmCurve(tonemap); }
- // RGB -> XYZ conversion
- float3 XYZ = RGBtoXYZ(tonemap);
- // 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)
- // (Wt) Tone mapped scaling of the initial wp before input modifiers
- float Wt = saturate(Yxy.r / AvgLuminance(XYZ));
- 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);
- // (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 / (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 (TonemapType == 3) { XYZ = TmCurve(XYZ); }
- // XYZ -> RGB conversion
- tonemap = XYZtoRGB(XYZ);
- float shadowmask = pow(saturate(blackLevel), float(BlackLevels));
- tonemap = tonemap * float3(shadowmask, shadowmask, shadowmask);
- color.rgb = tonemap;
- color.a = AvgLuminance(color.rgb);
- return color;
- }
- #endif
- /*------------------------------------------------------------------------------
- [CROSS PROCESSING CODE SECTION]
- ------------------------------------------------------------------------------*/
- #if CROSS_PROCESSING == 1
- float3 CrossShift(float3 color)
- {
- float3 cross;
- float2 CrossMatrix[3] = float2[](
- 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 = AvgLuminance(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
- /*------------------------------------------------------------------------------
- [TV COLORS EMU CODE SECTION]
- ------------------------------------------------------------------------------*/
- #if NTSC_TV_EMULATION == 1
- // conversion from NTSC RGB Reference White D65 ( color space used by NA/Japan TV's ) to XYZ
- vec3 NTSC(vec3 c)
- {
- vec3 v = vec3(pow(c.r, 2.2), pow(c.g, 2.2), pow(c.b, 2.2)); //Inverse Companding
- return RGBtoXYZ(v);
- }
- // conversion from XYZ to sRGB Reference White D65 ( color space used by windows )
- vec3 sRGB(vec3 c)
- {
- vec3 v = XYZtoSRGB(c);
- v = DecodeGamma(v, 2.4); //Companding
- return v;
- }
- // NTSC RGB to sRGB
- vec3 NTSCtoSRGB(vec3 c)
- {
- return sRGB(NTSC(c));
- }
- // Ported from SimoneT TV colors emulation 1.0 Shader
- vec4 TvColorsPass(vec4 color, vec2 texcoord)
- {
- color.rgb = NTSCtoSRGB(color.rgb);
- color.a = AvgLuminance(color.rgb);
- return color;
- }
- #endif
- /*------------------------------------------------------------------------------
- [S-CURVE CONTRAST CODE SECTION]
- ------------------------------------------------------------------------------*/
- #if CURVE_CONTRAST == 1
- float4 ContrastPass(float4 color, float2 texcoord)
- {
- float CurveBlend = CurvesContrast;
- #if CurveType != 2
- float lum = AvgLuminance(color.rgb);
- float3 luma = float3(lum, lum, lum);
- float3 chroma = color.rgb - luma;
- #endif
- #if CurveType == 2
- float3 x = color.rgb;
- #elif (CurveType == 1)
- float3 x = chroma;
- x = x * 0.5 + 0.5;
- #else
- float3 x = luma;
- #endif
- //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.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)
- float3 bc = lerp(b, c, x); //point between b and c (green)
- float3 cd = lerp(c, d, x); //point between c and d (green)
- float3 abbc = lerp(ab, bc, x); //point between ab and bc (blue)
- float3 bccd = lerp(bc, cd, x); //point between bc and cd (blue)
- float3 dest = lerp(abbc, bccd, x); //point on the bezier-curve (black)
- x = dest;
- #if CurveType == 0 //Only Luma
- x = lerp(luma, x, CurveBlend);
- color.rgb = x + chroma;
- #elif (CurveType == 1) //Only Chroma
- x = x * 2 - 1;
- float3 LColor = luma + x;
- color.rgb = lerp(color.rgb, LColor, CurveBlend);
- #elif (CurveType == 2) //Both Luma and Chroma
- float3 LColor = x;
- color.rgb = lerp(color.rgb, LColor, CurveBlend);
- #endif
- color.a = AvgLuminance(color.rgb);
- return saturate(color);
- }
- #endif
- /*------------------------------------------------------------------------------
- [CEL SHADING CODE SECTION]
- ------------------------------------------------------------------------------*/
- #if CEL_SHADING == 1
- float3 CelColor(in float3 RGB)
- {
- float3 HSV;
- float CR = 1.0 / ColorRange, MS = Saturation, ML;
- HSV = RGBtoHSV(RGB);
- ML = fmod(HSV[2], CR);
- HSV[1] *= MS; HSV[2] += ((CR * (HSV[2] + 0.6)) - ML);
- HSV[2] = clamp(HSV[2], float(int(HSV[2] / CR) - 1) * CR, float(int(HSV[2] / CR) + 1) * CR);
- RGB = HSVtoRGB(HSV);
- return RGB;
- }
- float4 CelPass(float4 color, float2 texcoord)
- {
- const int NUM = 9;
- float3 yuv, sum = color.rgb;
- float2 width = float2(0.1, 0.1);
- float rounding = RoundingLevels;
- float lum[NUM];
- float3 col[NUM];
- float2 set[NUM] = float2[](
- float2(-0.0078125, -0.0078125),
- float2(0.00, -0.0078125),
- float2(0.0078125, -0.0078125),
- float2(-0.0078125, 0.00),
- float2(0.00, 0.00),
- float2(0.0078125, 0.00),
- float2(-0.0078125, 0.0078125),
- float2(0.00, 0.0078125),
- float2(0.0078125, 0.0078125) );
- for (int i = 0; i < NUM; i++)
- {
- col[i] = texture(OGL2Texture, texcoord + set[i] * width).rgb;
- col[i] = CelColor(col[i]);
- #if ColorRounding == 1
- col[i].r = round(col[i].r * rounding) / rounding;
- col[i].g = round(col[i].g * rounding) / rounding;
- col[i].b = round(col[i].b * rounding) / rounding;
- #endif
- lum[i] = AvgLuminance(col[i].xyz);
- yuv = RGBtoYUV(col[i]);
- #if UseYuvLuma == 1
- yuv.r = round(yuv.r * rounding) / rounding;
- #endif
- yuv = YUVtoRGB(yuv);
- sum += yuv;
- }
- float3 shaded = sum / NUM;
- float3 shadedColor = lerp(color.rgb, shaded, ShadedStrength);
- float cs; float4 offset; float4 pos0 = texcoord.xyxy;
- float px = textureSize(OGL2Texture, 0).x * float(EdgeScale);
- float py = textureSize(OGL2Texture, 0).y * float(EdgeScale);
- offset.xy = -(offset.zw = float2(1.0/px, 0.0));
- float4 pos1 = pos0 + offset;
- offset.xy = -(offset.zw = float2(0.0, 1.0/py));
- float4 pos2 = pos0 + offset;
- float4 pos3 = pos1 + 2.0 * offset;
- float3 c0 = texture(OGL2Texture, pos3.xy).rgb;
- float3 c1 = texture(OGL2Texture, pos2.xy).rgb;
- float3 c2 = texture(OGL2Texture, pos3.zy).rgb;
- float3 c3 = texture(OGL2Texture, pos1.xy).rgb;
- float3 c5 = texture(OGL2Texture, pos1.zw).rgb;
- float3 c6 = texture(OGL2Texture, pos3.xw).rgb;
- float3 c7 = texture(OGL2Texture, pos2.zw).rgb;
- float3 c8 = texture(OGL2Texture, pos3.zw).rgb;
- float3 o = float3(1.0, 1.0, 1.0);
- float3 h = float3(0.02, 0.02, 0.02);
- float3 hz = h; float k = 0.02; float kz = EdgeFilter / 100.0;
- float3 cz = (color.rgb + h) / (dot(o, color.rgb) + k);
- hz = (cz - ((c0 + h) / (dot(o, c0) + k))); cs = kz / (dot(hz, hz) + kz);
- hz = (cz - ((c1 + h) / (dot(o, c1) + k))); cs += kz / (dot(hz, hz) + kz);
- hz = (cz - ((c2 + h) / (dot(o, c2) + k))); cs += kz / (dot(hz, hz) + kz);
- hz = (cz - ((c3 + h) / (dot(o, c3) + k))); cs += kz / (dot(hz, hz) + kz);
- hz = (cz - ((c5 + h) / (dot(o, c5) + k))); cs += kz / (dot(hz, hz) + kz);
- hz = (cz - ((c6 + h) / (dot(o, c6) + k))); cs += kz / (dot(hz, hz) + kz);
- hz = (cz - ((c7 + h) / (dot(o, c7) + k))); cs += kz / (dot(hz, hz) + kz);
- hz = (cz - ((c8 + h) / (dot(o, c8) + k))); cs += kz / (dot(hz, hz) + kz);
- cs /= 8.0;
- color.rgb = lerp(color.rgb, shadedColor, AvgLuminance(color.rgb)) * pow(cs, CelStrength);
- color.a = AvgLuminance(color.rgb);
- return color;
- }
- #endif
- /*------------------------------------------------------------------------------
- [PAINT SHADING CODE SECTION]
- ------------------------------------------------------------------------------*/
- #if PAINT_SHADING == 1
- float3 PaintShading(float3 color, float2 texcoord)
- {
- float px = textureSize(OGL2Texture, 0).x * float(ResScale);
- float py = textureSize(OGL2Texture, 0).y * float(ResScale);
- float3 m0, m1, m2, m3, k0, k1, k2, k3, shade; int j, i;
- float n = float((PaintRadius + 1.0) * (PaintRadius + 1.0));
- for (j = int(-PaintRadius); j <= 0; ++j) {
- for (i = int(-PaintRadius); i <= 0; ++i) {
- shade = texture(OGL2Texture, texcoord + float2(i, j) / float2(px, py)).rgb;
- m0 += shade; k0 += shade * shade; }}
- for (j = int(-PaintRadius); j <= 0; ++j) {
- for (i = 0; i <= int(PaintRadius); ++i) {
- shade = texture(OGL2Texture, texcoord + float2(i, j) / float2(px, py)).rgb;
- m1 += shade; k1 += shade * shade; }}
- for (j = 0; j <= int(PaintRadius); ++j) {
- for (i = 0; i <= int(PaintRadius); ++i) {
- shade = texture(OGL2Texture, texcoord + float2(i, j) / float2(px, py)).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; }
- #if UseCelEdges == 1
- float cs; float4 offset; float4 pos0 = texcoord.xyxy;
- float ppx = textureSize(OGL2Texture, 0).x * float(EdgeScale);
- float ppy = textureSize(OGL2Texture, 0).y * float(EdgeScale);
- offset.xy = -(offset.zw = float2(1.0/ppx, 0.0));
- float4 pos1 = pos0 + offset;
- offset.xy = -(offset.zw = float2(0.0, 1.0/ppy));
- float4 pos2 = pos0 + offset;
- float4 pos3 = pos1 + 2.0 * offset;
- float3 c0 = texture(OGL2Texture, pos3.xy).rgb;
- float3 c1 = texture(OGL2Texture, pos2.xy).rgb;
- float3 c2 = texture(OGL2Texture, pos3.zy).rgb;
- float3 c3 = texture(OGL2Texture, pos1.xy).rgb;
- float3 c5 = texture(OGL2Texture, pos1.zw).rgb;
- float3 c6 = texture(OGL2Texture, pos3.xw).rgb;
- float3 c7 = texture(OGL2Texture, pos2.zw).rgb;
- float3 c8 = texture(OGL2Texture, pos3.zw).rgb;
- float3 o = float3(1.0, 1.0, 1.0);
- float3 h = float3(0.02, 0.02, 0.02);
- float3 hz = h; float k = 0.02; float kz = EdgeFilter / 100.0;
- float3 cz = (color.rgb + h) / (dot(o, color.rgb) + k);
- hz = (cz - ((c0 + h) / (dot(o, c0) + k))); cs = kz / (dot(hz, hz) + kz);
- hz = (cz - ((c1 + h) / (dot(o, c1) + k))); cs += kz / (dot(hz, hz) + kz);
- hz = (cz - ((c2 + h) / (dot(o, c2) + k))); cs += kz / (dot(hz, hz) + kz);
- hz = (cz - ((c3 + h) / (dot(o, c3) + k))); cs += kz / (dot(hz, hz) + kz);
- hz = (cz - ((c5 + h) / (dot(o, c5) + k))); cs += kz / (dot(hz, hz) + kz);
- hz = (cz - ((c6 + h) / (dot(o, c6) + k))); cs += kz / (dot(hz, hz) + kz);
- hz = (cz - ((c7 + h) / (dot(o, c7) + k))); cs += kz / (dot(hz, hz) + kz);
- hz = (cz - ((c8 + h) / (dot(o, c8) + k))); cs += kz / (dot(hz, hz) + kz);
- cs /= 8.0;
- color.rgb *= pow(cs, CelStrength);
- #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
- float RGBCVtoHUE(float3 RGB, float C, float V)
- {
- float3 Delta = (V - RGB) / C;
- Delta.rgb -= Delta.brg;
- Delta.rgb += float3(2.0, 4.0, 6.0);
- Delta.brg = step(V, RGB) * Delta.brg;
- float H;
- H = max(Delta.r, max(Delta.g, Delta.b));
- return frac(H / 6);
- }
- float3 HSVComplement(float3 HSV)
- {
- float3 complement = HSV;
- complement.x -= 0.5;
- if (complement.x < 0.0) { complement.x += 1.0; }
- return(complement);
- }
- float HueLerp(float h1, float h2, float v)
- {
- float d = abs(h1 - h2);
- if (d <= 0.5)
- { return lerp(h1, h2, v); }
- else if (h1 < h2)
- { return frac(lerp((h1 + 1.0), h2, v)); }
- else
- { return frac(lerp(h1, (h2 + 1.0), v)); }
- }
- float4 ColorGrading(float4 color, float2 texcoord)
- {
- float3 guide = float3(RedGrading, GreenGrading, BlueGrading);
- float amount = GradingStrength;
- float correlation = Correlation;
- float concentration = 2.00;
- float3 colorHSV = RGBtoHSV(color.rgb);
- float3 huePoleA = RGBtoHSV(guide);
- float3 huePoleB = HSVComplement(huePoleA);
- float dist1 = abs(colorHSV.x - huePoleA.x); if (dist1 > 0.5) dist1 = 1.0 - dist1;
- float dist2 = abs(colorHSV.x - huePoleB.x); if (dist2 > 0.5) dist2 = 1.0 - dist2;
- float descent = smoothstep(0.0, correlation, colorHSV.y);
- float3 HSVColor = colorHSV;
- if (dist1 < dist2)
- {
- float c = descent * amount * (1.0 - pow((dist1 * 2.0), 1.0 / concentration));
- HSVColor.x = HueLerp(colorHSV.x, huePoleA.x, c);
- HSVColor.y = lerp(colorHSV.y, huePoleA.y, c);
- }
- else
- {
- float c = descent * amount * (1.0 - pow((dist2 * 2.0), 1.0 / concentration));
- HSVColor.x = HueLerp(colorHSV.x, huePoleB.x, c);
- HSVColor.y = lerp(colorHSV.y, huePoleB.y, c);
- }
- color.rgb = HSVtoRGB(HSVColor);
- color.a = AvgLuminance(color.rgb);
- return saturate(color);
- }
- #endif
- /*------------------------------------------------------------------------------
- [SCANLINES CODE SECTION]
- ------------------------------------------------------------------------------*/
- #if SCANLINES == 1
- float4 ScanlinesPass(float4 color, float2 texcoord)
- {
- float4 intensity;
- float4 fragcoord = gl_FragCoord;
- #if ScanlineType == 0
- if (frac(fragcoord.y * 0.25) > ScanlineScale)
- #elif (ScanlineType == 1)
- if (frac(fragcoord.x * 0.25) > ScanlineScale)
- #elif (ScanlineType == 2)
- if (frac(fragcoord.x * 0.25) > ScanlineScale && frac(fragcoord.y * 0.5) > ScanlineScale)
- #endif
- {
- intensity = float4(0.0, 0.0, 0.0, 0.0);
- }
- else
- {
- intensity = smoothstep(0.2, ScanlineBrightness, color) + normalize(float4(color.xyz, AvgLuminance(color.xyz)));
- }
- float level = (4.0 - texcoord.x) * ScanlineIntensity;
- color = intensity * (0.5 - level) + color * 1.1;
- return color;
- }
- #endif
- /*------------------------------------------------------------------------------
- [VIGNETTE CODE SECTION]
- ------------------------------------------------------------------------------*/
- #if VIGNETTE == 1
- float4 VignettePass(float4 color, float2 texcoord)
- {
- const float2 VignetteCenter = float2(0.5, 0.5);
- float2 tc = texcoord - VignetteCenter;
- tc *= float2((screenSize.x / screenSize.y), VignetteRatio);
- tc /= VignetteRadius;
- float v = dot(tc, tc);
- color.rgb *= (1.0 + pow(v, VignetteSlope * 0.25) * -VignetteAmount);
- return color;
- }
- #endif
- /*------------------------------------------------------------------------------
- [SUBPIXEL DITHERING CODE SECTION]
- ------------------------------------------------------------------------------*/
- #if SP_DITHERING == 1
- float Random(float2 texcoord)
- {
- float seed = dot(texcoord, float2(12.9898, 78.233));
- float sine = sin(seed);
- 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 = Random(gl_FragCoord.xy);
- 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);
- #if ShowMethod == 1
- color.rgb = float3(noise);
- #endif
- #elif DitherMethod == 1 //ordered dithering
- float2 ditherSize = float2(1.0 / 16.0, 10.0 / 36.0);
- float gridPosition = fract(dot(gl_FragCoord.xy, 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 = float3(gridPosition);
- #endif
- #endif
- color.a = AvgLuminance(color.rgb);
- return color;
- }
- #endif
- /*------------------------------------------------------------------------------
- [DEBAND CODE SECTION]
- ------------------------------------------------------------------------------*/
- #if DEBANDING == 1
- //Deband ported from gedosato
- #define DEBAND_SKIP_THRESHOLD_TEST 0 //[0:1] 1 = Skip threshold to see the unfiltered sampling pattern
- #define DEBAND_OUTPUT_BOOST 1.0 //[-2.0:2.0] Default = 1.0. Any value other than the default activates debug mode.
- #define DEBAND_OUTPUT_OFFSET 0.0 //[-1.0:3.0] Default = 0.0. Any value other than the default activates debug mode.
- float rand(float2 pos)
- {
- return frac(sin(dot(pos, float2(12.9898, 78.233))) * 43758.5453);
- }
- bool is_within_threshold(float3 original, float3 other)
- {
- bvec3 cond = notEqual(max(abs(original - other) - DebandThreshold, float3(0.0, 0.0, 0.0)), float3(0.0, 0.0, 0.0));
- return !any(cond);
- }
- float4 DebandPass(float4 color, float2 texcoord)
- {
- float2 step = pixelSize * DebandRadius;
- float2 halfstep = step * 0.5;
- // Compute additional sample positions
- float2 seed = texcoord;
- #if (DebandOffsetMode == 1)
- float2 offset = float2(rand(seed), 0.0);
- #elif(DebandOffsetMode == 2)
- float2 offset = float2(rand(seed).xx);
- #elif(DebandOffsetMode == 3)
- float2 offset = float2(rand(seed), rand(seed + float2(0.1, 0.2)));
- #endif
- float2 on[8] = float2[](
- float2( offset.x, offset.y) * step,
- float2( offset.y, -offset.x) * step,
- float2(-offset.x, -offset.y) * step,
- float2(-offset.y, offset.x) * step,
- float2( offset.x, offset.y) * halfstep,
- float2( offset.y, -offset.x) * halfstep,
- float2(-offset.x, -offset.y) * halfstep,
- float2(-offset.y, offset.x) * halfstep );
- float3 col0 = color.rgb;
- float4 accu = float4(col0, 1.0);
- for(int i=0; i < int(DebandSampleCount); i++)
- {
- float4 cn = float4(texture(OGL2Texture, texcoord + on[i]).rgb, 1.0);
- #if (DEBAND_SKIP_THRESHOLD_TEST == 0)
- if(is_within_threshold(col0, cn.rgb))
- #endif
- accu += cn;
- }
- accu.rgb /= accu.a;
- // Boost to make it easier to inspect the effect's output
- if(DEBAND_OUTPUT_OFFSET != 0.0 || DEBAND_OUTPUT_BOOST != 1.0)
- {
- accu.rgb -= DEBAND_OUTPUT_OFFSET;
- accu.rgb *= DEBAND_OUTPUT_BOOST;
- }
- // Additional dithering
- #if (DebandDithering == 1)
- //Ordered dithering
- float dither_bit = 8.0;
- float grid_position = frac( dot(texcoord,(screenSize * float2(1.0/16.0,10.0/36.0))) + 0.25 );
- float dither_shift = (0.25) * (1.0 / (pow(2,dither_bit) - 1.0));
- float3 dither_shift_RGB = float3(dither_shift, -dither_shift, dither_shift);
- dither_shift_RGB = lerp(2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position);
- accu.rgb += dither_shift_RGB;
- #elif (DebandDithering == 2)
- //Random dithering
- float dither_bit = 8.0;
- float sine = sin(dot(texcoord, float2(12.9898,78.233)));
- float noise = frac(sine * 43758.5453 + texcoord.x);
- float dither_shift = (1.0 / (pow(2,dither_bit) - 1.0));
- float dither_shift_half = (dither_shift * 0.5);
- dither_shift = dither_shift * noise - dither_shift_half;
- accu.rgb += float3(-dither_shift, dither_shift, -dither_shift);
- #elif (DebandDithering == 3)
- float3 vDither = float3(dot(float2(171.0, 231.0), texcoord * screenSize)).xxx;
- vDither.rgb = frac( vDither.rgb / float3( 103.0, 71.0, 97.0 ) ) - float3(0.5, 0.5, 0.5);
- accu.rgb += (vDither.rgb / 255.0);
- #endif
- return accu;
- }
- #endif
- /*------------------------------------------------------------------------------
- [LOTTES CRT CODE SECTION]
- ------------------------------------------------------------------------------*/
- #if LOTTES_CRT == 1
- float ToLinear1(float c)
- {
- c = saturate(c);
- return(c <= 0.04045) ? c / 12.92 : pow((c + 0.055) / 1.055, 2.4);
- }
- float3 ToLinear(float3 c)
- {
- return float3(ToLinear1(c.r), ToLinear1(c.g), ToLinear1(c.b));
- }
- float ToSrgb1(float c)
- {
- c = saturate(c);
- return(c < 0.0031308 ? c * 12.92 : 1.055 * pow(c, 0.41666) -0.055);
- }
- float3 ToSrgb(float3 c)
- {
- return float3(ToSrgb1(c.r), ToSrgb1(c.g), ToSrgb1(c.b));
- }
- float3 Fetch(float2 pos, float2 off)
- {
- float2 res = (screenSize * ResolutionScale);
- pos = round(pos * res + off) / res;
- if(max(abs(pos.x - 0.5), abs(pos.y - 0.5)) > 0.5) { return float3(0.0, 0.0, 0.0); }
- return ToLinear(texture(OGL2Texture, pos.xy).rgb);
- }
- float2 Dist(float2 pos)
- {
- float2 crtRes = float2(CRTSizeX, CRTSizeY);
- float2 res = (crtRes * MaskResolutionScale);
- pos = (pos * res);
- return -((pos - floor(pos)) - float2(0.5, 0.5));
- }
- float Gaus(float pos, float scale)
- {
- return exp2(scale * pos * pos);
- }
- float3 Horz3(float2 pos, float off)
- {
- float3 b = Fetch(pos,float2(-1.0, off));
- float3 c = Fetch(pos,float2( 0.0, off));
- float3 d = Fetch(pos,float2( 1.0, off));
- float dst = Dist(pos).x;
- // Convert distance to weight.
- float scale = FilterCRTAmount;
- float wb = Gaus(dst-1.0, scale);
- float wc = Gaus(dst+0.0, scale);
- float wd = Gaus(dst+1.0, scale);
- return (b*wb+c*wc+d*wd)/(wb+wc+wd);
- }
- float3 Horz5(float2 pos, float off)
- {
- float3 a = Fetch(pos, float2(-2.0, off));
- float3 b = Fetch(pos, float2(-1.0, off));
- float3 c = Fetch(pos, float2( 0.0, off));
- float3 d = Fetch(pos, float2( 1.0, off));
- float3 e = Fetch(pos, float2( 2.0, off));
- float dst = Dist(pos).x;
- // Convert distance to weight.
- float scale = FilterCRTAmount;
- float wa = Gaus(dst-2.0, scale);
- float wb = Gaus(dst-1.0, scale);
- float wc = Gaus(dst+0.0, scale);
- float wd = Gaus(dst+1.0, scale);
- float we = Gaus(dst+2.0, scale);
- return (a*wa+b*wb+c*wc+d*wd+e*we)/(wa+wb+wc+wd+we);
- }
- // Return scanline weight.
- float Scan(float2 pos, float off)
- {
- float dst = Dist(pos).y;
- return Gaus(dst+off, ScanBrightness);
- }
- float3 Tri(float2 pos)
- {
- float3 a = Horz3(pos,-1.0);
- float3 b = Horz5(pos, 0.0);
- float3 c = Horz3(pos, 1.0);
- float wa = Scan(pos,-1.0);
- float wb = Scan(pos, 0.0);
- float wc = Scan(pos, 1.0);
- return a*wa+b*wb+c*wc;
- }
- float2 Warp(float2 pos)
- {
- pos = pos * 2.0-1.0;
- pos *= float2(1.0 + (pos.y*pos.y) * (HorizontalWarp), 1.0 + (pos.x*pos.x) * (VerticalWarp));
- return pos * 0.5 + 0.5;
- }
- float3 Mask(float2 pos)
- {
- #if MaskingType == 1
- // Very compressed TV style shadow mask.
- float lines = MaskAmountLight;
- float odd = 0.0;
- if(frac(pos.x/6.0) < 0.5) odd = 1.0;
- if (frac((pos.y + odd) / 2.0) < 0.5) lines = MaskAmountDark;
- pos.x = frac(pos.x/3.0);
- float3 mask = float3(MaskAmountDark, MaskAmountDark, MaskAmountDark);
- if(pos.x < 0.333) mask.r = MaskAmountLight;
- else if(pos.x < 0.666)mask.g = MaskAmountLight;
- else mask.b = MaskAmountLight;
- mask *= lines;
- return mask;
- #elif MaskingType == 2
- // Aperture-grille.
- pos.x = frac(pos.x/3.0);
- float3 mask = float3(MaskAmountDark, MaskAmountDark, MaskAmountDark);
- if(pos.x < 0.333)mask.r = MaskAmountLight;
- else if(pos.x < 0.666)mask.g = MaskAmountLight;
- else mask.b = MaskAmountLight;
- return mask;
- #elif MaskingType == 3
- // Stretched VGA style shadow mask (same as prior shaders).
- pos.x += pos.y*3.0;
- float3 mask = float3(MaskAmountDark, MaskAmountDark, MaskAmountDark);
- pos.x = frac(pos.x/6.0);
- if(pos.x < 0.333)mask.r = MaskAmountLight;
- else if(pos.x < 0.666)mask.g = MaskAmountLight;
- else mask.b = MaskAmountLight;
- return mask;
- #else
- // VGA style shadow mask.
- pos.xy = floor(pos.xy*float2(1.0, 0.5));
- pos.x += pos.y*3.0;
- float3 mask = float3(MaskAmountDark, MaskAmountDark, MaskAmountDark);
- pos.x = frac(pos.x/6.0);
- if(pos.x < 0.333)mask.r = MaskAmountLight;
- else if(pos.x < 0.666)mask.g = MaskAmountLight;
- else mask.b= MaskAmountLight;
- return mask;
- #endif
- }
- float4 LottesCRTPass(float4 color, float2 texcoord)
- {
- float4 fragcoord = gl_FragCoord;
- float2 inSize = textureSize(OGL2Texture, 0);
- float2 pos = Warp(texcoord.xy * (inSize/screenSize)) * (screenSize/inSize);
- #if UseShadowMask == 0
- color.rgb = Tri(pos);
- #else
- color.rgb = Tri(pos);
- color.rgb *= Mask(floor(texcoord.xy*(inSize.xy/screenSize)*screenSize.xy) + float2(0.5,0.5));
- #endif
- color.rgb = ToSrgb(color.rgb);
- color.a = 1.0;
- return color;
- }
- #endif
- /*------------------------------------------------------------------------------
- [PX BORDER CODE SECTION]
- ------------------------------------------------------------------------------*/
- float4 BorderPass(float4 colorInput, float2 tex)
- {
- float3 border_color_float = BorderColor / 255.0;
- float2 border = (pixelSize.xy * BorderWidth);
- float2 within_border = saturate((-tex * tex + tex) - (-border * border + border));
- bvec2 cond = notEqual(within_border, vec2(0.0f, 0.0f));
- colorInput.rgb = all(cond) ? colorInput.rgb : border_color_float;
- return colorInput;
- }
- /*------------------------------------------------------------------------------
- [PHONG SHADING CODE SECTION]
- ------------------------------------------------------------------------------*/
- #if PHONG_SHADING == 1
- struct material
- {
- vec4 ambient;
- vec4 diffuse;
- vec4 specular;
- float shininess;
- vec4 sceneColor;
- };
- material frontMaterial = material
- (
- gl_FrontMaterial.ambient,
- gl_FrontMaterial.diffuse,
- gl_FrontMaterial.specular,
- gl_FrontMaterial.shininess,
- gl_FrontLightModelProduct.sceneColor
- );
- struct lightSource
- {
- vec4 ambient;
- vec4 diffuse;
- vec4 specular;
- float constantAttenuation;
- float linearAttenuation;
- float quadraticAttenuation;
- };
- lightSource light0 = lightSource
- (
- gl_LightSource[0].ambient,
- gl_LightSource[0].diffuse,
- gl_LightSource[0].specular,
- gl_LightSource[0].constantAttenuation,
- gl_LightSource[0].linearAttenuation,
- gl_LightSource[0].quadraticAttenuation
- );
- float CalcAttenuation(float dist)
- {
- float consAtten = light0.constantAttenuation;
- float lineAtten = light0.linearAttenuation;
- float quadAtten = light0.quadraticAttenuation;
- float atten = (1.0 / (consAtten + lineAtten * dist + quadAtten * dist * dist));
- return atten;
- }
- vec4 PhongPass(vec4 color, vec2 texcoord)
- {
- // setup input params
- vec3 eyeVector = normalize(eyeVect);
- vec3 normalVector = normalize(Normal);
- // calculate reflection
- vec3 reflection = reflect(-lightVect, normalVector);
- // calculate attenuation
- float attenuation = CalcAttenuation(Distance);
- float nDotL = max(dot(normalVector, lightVect), 0.0); // normal, position
- float eDotR = max(dot(eyeVector, reflection), 0.0); // eyeVec, reflect
- // calculate scene ambient:
- vec4 scene = gl_LightModel.ambient * frontMaterial.ambient;
- vec3 ambient = vec3(scene + light0.ambient + frontMaterial.ambient);
- // calculate mat diffuse:
- vec3 diffuse = vec3(attenuation) * vec3(light0.diffuse * frontMaterial.diffuse) * nDotL;
- diffuse = clamp(diffuse, 0.0, 1.0);
- // calculate specular highlights:
- vec3 specular = vec3(attenuation) * vec3(light0.specular * frontMaterial.specular) *
- pow(eDotR, frontMaterial.shininess); specular = clamp(specular, 0.0, 1.0);
- // calculate phong lighting:
- vec3 phong = ambient + diffuse + specular;
- color.xyz *= phong;
- color.w = AvgLuminance(color.xyz);
- return color;
- }
- #endif
- /*------------------------------------------------------------------------------
- [MAIN() & COMBINE PASS CODE SECTION]
- ------------------------------------------------------------------------------*/
- void main()
- {
- float2 texcoord = TexCoord.xy;
- float4 color = texture(OGL2Texture, texcoord);
- #if BILINEAR_FILTERING == 1
- color = BiLinearPass(color, texcoord);
- #endif
- #if GAUSSIAN_FILTERING == 1
- color = GaussianPass(color, texcoord);
- #endif
- #if BICUBIC_FILTERING == 1
- color = BiCubicPass(color, texcoord);
- #endif
- #if BILATERAL_FILTERING == 1
- color = BilateralPass(color, texcoord);
- #endif
- #if DDTI_FILTERING == 1
- color = DDTPass(color, texcoord);
- #endif
- #if BICUBLIC_SCALER == 1
- color = BiCubicScalerPass(color, texcoord);
- #endif
- #if LANCZOS_SCALER == 1
- color = LanczosScalerPass(color, texcoord);
- #endif
- #if DLAA == 1
- color = DLAAPass(color, texcoord);
- #endif
- #if SSAA == 1
- color = SSAAPass(color, texcoord);
- #endif
- #if SFAA == 1
- color = SFAAPass(color, texcoord);
- #endif
- #if FXAA == 1
- color = FXAAPass(color, texcoord);
- #endif
- #if XBRV == 1
- color = xBRPass(color, texcoord);
- #endif
- #if LOTTES_CRT == 1
- color = LottesCRTPass(color, texcoord);
- #endif
- #if PAINT_SHADING == 1
- color = PaintPass(color, texcoord);
- #endif
- #if TEXTURE_SHARPEN == 1
- color = TexSharpenPass(color, texcoord);
- #endif
- #if PHONG_SHADING == 1
- color = PhongPass(color, texcoord);
- #endif
- #if GAMMA_CORRECTION == 1
- color = GammaPass(color, texcoord);
- #endif
- #if PIXEL_VIBRANCE == 1
- color = VibrancePass(color, texcoord);
- #endif
- #if CEL_SHADING == 1
- color = CelPass(color, texcoord);
- #endif
- #if COLOR_GRADING == 1
- color = ColorGrading(color, texcoord);
- #endif
- #if NTSC_TV_EMULATION == 1
- color = TvColorsPass(color, texcoord);
- #endif
- #if COLOR_CORRECTION == 1
- color = CorrectionPass(color, texcoord);
- #endif
- #if CROSS_PROCESSING == 1
- color = CrossPass(color, texcoord);
- #endif
- #if BLENDED_BLOOM == 1
- color = BloomPass(color, texcoord);
- #endif
- #if SCENE_TONEMAPPING == 1
- color = TonemapPass(color, texcoord);
- #endif
- #if CURVE_CONTRAST == 1
- color = ContrastPass(color, texcoord);
- #endif
- #if VIGNETTE == 1
- color = VignettePass(color, texcoord);
- #endif
- #if SCANLINES == 1
- color = ScanlinesPass(color, texcoord);
- #endif
- #if SP_DITHERING == 1
- color = DitherPass(color, texcoord);
- #endif
- #if DEBANDING == 1
- color = DebandPass(color, texcoord);
- #endif
- #if PX_BORDER == 1
- color = BorderPass(color, texcoord);
- #endif
- FragColor = color;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement