傲世三国之三分天下-高清HD加强版
This commit is contained in:
701
Shaders/crt/crt-lottes-fast-no-warp-bilinear.glsl
Normal file
701
Shaders/crt/crt-lottes-fast-no-warp-bilinear.glsl
Normal file
@@ -0,0 +1,701 @@
|
||||
//_____________________________/\_______________________________
|
||||
//==============================================================
|
||||
//
|
||||
//
|
||||
// [CRTS] PUBLIC DOMAIN CRT-STYLED SCALAR - 20180120b
|
||||
//
|
||||
// by Timothy Lottes
|
||||
// https://www.shadertoy.com/view/MtSfRK
|
||||
// adapted for RetroArch by hunterk
|
||||
//
|
||||
//
|
||||
//==============================================================
|
||||
////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////
|
||||
//_____________________________/\_______________________________
|
||||
//==============================================================
|
||||
//
|
||||
// WHAT'S NEW
|
||||
//
|
||||
//--------------------------------------------------------------
|
||||
// Evolution of prior shadertoy example
|
||||
//--------------------------------------------------------------
|
||||
// This one is semi-optimized
|
||||
// - Less texture fetches
|
||||
// - Didn't get to instruction level optimization
|
||||
// - Could likely use texture fetch to generate phosphor mask
|
||||
//--------------------------------------------------------------
|
||||
// Added options to disable unused features
|
||||
//--------------------------------------------------------------
|
||||
// Added in exposure matching
|
||||
// - Given scan-line effect and mask always darkens image
|
||||
// - Uses generalized tonemapper to boost mid-level
|
||||
// - Note this can compress highlights
|
||||
// - And won't get back peak brightness
|
||||
// - But best option if one doesn't want as much darkening
|
||||
//--------------------------------------------------------------
|
||||
// Includes option saturation and contrast controls
|
||||
//--------------------------------------------------------------
|
||||
// Added in subtractive aperture grille
|
||||
// - This is a bit brighter than prior
|
||||
//--------------------------------------------------------------
|
||||
// Make sure input to this filter is already low-resolution
|
||||
// - This is not designed to work on titles doing the following
|
||||
// - Rendering to hi-res with nearest sampling
|
||||
//--------------------------------------------------------------
|
||||
// Added a fast and more pixely option for 2 tap/pixel
|
||||
//--------------------------------------------------------------
|
||||
// Improved the vignette when WARP is enabled
|
||||
//--------------------------------------------------------------
|
||||
// Didn't test HLSL or CPU options
|
||||
// - Will incorportate patches if they are broken
|
||||
// - But out of time to try them myself
|
||||
//==============================================================
|
||||
////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////
|
||||
//_____________________________/\_______________________________
|
||||
//==============================================================
|
||||
//
|
||||
// LICENSE = UNLICENSE (aka PUBLIC DOMAIN)
|
||||
//
|
||||
//--------------------------------------------------------------
|
||||
// This is free and unencumbered software released into the
|
||||
// public domain.
|
||||
//--------------------------------------------------------------
|
||||
// Anyone is free to copy, modify, publish, use, compile, sell,
|
||||
// or distribute this software, either in source code form or as
|
||||
// a compiled binary, for any purpose, commercial or
|
||||
// non-commercial, and by any means.
|
||||
//--------------------------------------------------------------
|
||||
// In jurisdictions that recognize copyright laws, the author or
|
||||
// authors of this software dedicate any and all copyright
|
||||
// interest in the software to the public domain. We make this
|
||||
// dedication for the benefit of the public at large and to the
|
||||
// detriment of our heirs and successors. We intend this
|
||||
// dedication to be an overt act of relinquishment in perpetuity
|
||||
// of all present and future rights to this software under
|
||||
// copyright law.
|
||||
//--------------------------------------------------------------
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
// KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
// AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//--------------------------------------------------------------
|
||||
// For more information, please refer to
|
||||
// <http://unlicense.org/>
|
||||
//==============================================================
|
||||
////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma parameter MASK "Mask Type" 1.0 0.0 3.0 1.0
|
||||
#pragma parameter MASK_INTENSITY "Mask Intensity" 0.5 0.0 1.0 0.05
|
||||
#pragma parameter SCANLINE_THINNESS "Scanline Intensity" 0.5 0.0 1.0 0.1
|
||||
#pragma parameter SCAN_BLUR "Sharpness" 2.5 1.0 3.0 0.1
|
||||
#pragma parameter CURVATURE "Curvature" 0.02 0.0 0.25 0.01
|
||||
#pragma parameter TRINITRON_CURVE "Trinitron-style Curve" 0.0 0.0 1.0 1.0
|
||||
#pragma parameter CORNER "Corner Round" 3.0 0.0 11.0 1.0
|
||||
#pragma parameter CRT_GAMMA "CRT Gamma" 2.4 0.0 51.0 0.1
|
||||
|
||||
#if defined(VERTEX)
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
#define COMPAT_VARYING out
|
||||
#define COMPAT_ATTRIBUTE in
|
||||
#define COMPAT_TEXTURE texture
|
||||
#else
|
||||
#define COMPAT_VARYING varying
|
||||
#define COMPAT_ATTRIBUTE attribute
|
||||
#define COMPAT_TEXTURE texture2D
|
||||
#endif
|
||||
|
||||
#ifdef GL_ES
|
||||
#define COMPAT_PRECISION mediump
|
||||
#else
|
||||
#define COMPAT_PRECISION
|
||||
#endif
|
||||
|
||||
COMPAT_ATTRIBUTE vec4 VertexCoord;
|
||||
COMPAT_ATTRIBUTE vec4 COLOR;
|
||||
COMPAT_ATTRIBUTE vec4 TexCoord;
|
||||
COMPAT_VARYING vec4 COL0;
|
||||
COMPAT_VARYING vec4 TEX0;
|
||||
|
||||
vec4 _oPosition1;
|
||||
uniform mat4 MVPMatrix;
|
||||
uniform COMPAT_PRECISION int FrameDirection;
|
||||
uniform COMPAT_PRECISION int FrameCount;
|
||||
uniform COMPAT_PRECISION vec2 OutputSize;
|
||||
uniform COMPAT_PRECISION vec2 TextureSize;
|
||||
uniform COMPAT_PRECISION vec2 InputSize;
|
||||
|
||||
// compatibility #defines
|
||||
#define vTexCoord TEX0.xy
|
||||
#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
|
||||
#define OutSize vec4(OutputSize, 1.0 / OutputSize)
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = MVPMatrix * VertexCoord;
|
||||
TEX0.xy = TexCoord.xy;
|
||||
}
|
||||
|
||||
#elif defined(FRAGMENT)
|
||||
|
||||
#ifdef GL_ES
|
||||
#ifdef GL_FRAGMENT_PRECISION_HIGH
|
||||
precision highp float;
|
||||
#else
|
||||
precision mediump float;
|
||||
#endif
|
||||
#define COMPAT_PRECISION mediump
|
||||
#else
|
||||
#define COMPAT_PRECISION
|
||||
#endif
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
#define COMPAT_VARYING in
|
||||
#define COMPAT_TEXTURE texture
|
||||
out COMPAT_PRECISION vec4 FragColor;
|
||||
#else
|
||||
#define COMPAT_VARYING varying
|
||||
#define FragColor gl_FragColor
|
||||
#define COMPAT_TEXTURE texture2D
|
||||
#endif
|
||||
|
||||
uniform COMPAT_PRECISION int FrameDirection;
|
||||
uniform COMPAT_PRECISION int FrameCount;
|
||||
uniform COMPAT_PRECISION vec2 OutputSize;
|
||||
uniform COMPAT_PRECISION vec2 TextureSize;
|
||||
uniform COMPAT_PRECISION vec2 InputSize;
|
||||
uniform sampler2D Texture;
|
||||
COMPAT_VARYING vec4 TEX0;
|
||||
|
||||
// compatibility #defines
|
||||
#define Source Texture
|
||||
#define vTexCoord TEX0.xy
|
||||
|
||||
#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
|
||||
#define OutSize vec4(OutputSize, 1.0 / OutputSize)
|
||||
|
||||
#ifdef PARAMETER_UNIFORM
|
||||
uniform COMPAT_PRECISION float CRT_GAMMA;
|
||||
uniform COMPAT_PRECISION float SCANLINE_THINNESS;
|
||||
uniform COMPAT_PRECISION float SCAN_BLUR;
|
||||
uniform COMPAT_PRECISION float MASK_INTENSITY;
|
||||
uniform COMPAT_PRECISION float CURVATURE;
|
||||
uniform COMPAT_PRECISION float CORNER;
|
||||
uniform COMPAT_PRECISION float MASK;
|
||||
uniform COMPAT_PRECISION float TRINITRON_CURVE;
|
||||
#else
|
||||
#define CRT_GAMMA 2.4
|
||||
#define SCANLINE_THINNESS 0.5
|
||||
#define SCAN_BLUR 2.5
|
||||
#define MASK_INTENSITY 0.54
|
||||
#define CURVATURE 0.00
|
||||
#define CORNER 3.0
|
||||
#define MASK 1.0
|
||||
#define TRINITRON_CURVE 0.0
|
||||
#endif
|
||||
|
||||
//_____________________________/\_______________________________
|
||||
//==============================================================
|
||||
//
|
||||
// GAMMA FUNCTIONS
|
||||
//
|
||||
//--------------------------------------------------------------
|
||||
//--------------------------------------------------------------
|
||||
// Since shadertoy doesn't have sRGB textures
|
||||
// And we need linear input into shader
|
||||
// Don't do this in your code
|
||||
float FromSrgb1(float c){
|
||||
return (c<=0.04045)?c*(1.0/12.92):
|
||||
pow(c*(1.0/1.055)+(0.055/1.055),CRT_GAMMA);}
|
||||
//--------------------------------------------------------------
|
||||
vec3 FromSrgb(vec3 c){return vec3(
|
||||
FromSrgb1(c.r),FromSrgb1(c.g),FromSrgb1(c.b));}
|
||||
|
||||
// Convert from linear to sRGB
|
||||
// Since shader toy output is not linear
|
||||
float ToSrgb1(float c){
|
||||
return(c<0.0031308?c*12.92:1.055*pow(c,0.41666)-0.055);}
|
||||
//--------------------------------------------------------------
|
||||
vec3 ToSrgb(vec3 c){return vec3(
|
||||
ToSrgb1(c.r),ToSrgb1(c.g),ToSrgb1(c.b));}
|
||||
//--------------------------------------------------------------
|
||||
|
||||
//_____________________________/\_______________________________
|
||||
//==============================================================
|
||||
//
|
||||
// DEFINES
|
||||
//
|
||||
//--------------------------------------------------------------
|
||||
// CRTS_CPU - CPU code
|
||||
// CRTS_GPU - GPU code
|
||||
//--------------------------------------------------------------
|
||||
// CRTS_GLSL - GLSL
|
||||
// CRTS_HLSL - HLSL (not tested yet)
|
||||
//--------------------------------------------------------------
|
||||
// CRTS_DEBUG - Define to see on/off split screen
|
||||
//--------------------------------------------------------------
|
||||
// CRTS_WARP - Apply screen warp
|
||||
//--------------------------------------------------------------
|
||||
// CRTS_2_TAP - Faster very pixely 2-tap filter (off is 8)
|
||||
//--------------------------------------------------------------
|
||||
// CRTS_MASK_GRILLE - Aperture grille (aka Trinitron)
|
||||
// CRTS_MASK_GRILLE_LITE - Brighter (subtractive channels)
|
||||
// CRTS_MASK_NONE - No mask
|
||||
// CRTS_MASK_SHADOW - Horizontally stretched shadow mask
|
||||
//--------------------------------------------------------------
|
||||
// CRTS_TONE - Normalize mid-level and process color
|
||||
// CRTS_CONTRAST - Process color - enable contrast control
|
||||
// CRTS_SATURATION - Process color - enable saturation control
|
||||
//--------------------------------------------------------------
|
||||
#define CRTS_STATIC
|
||||
#define CrtsPow
|
||||
#define CRTS_RESTRICT
|
||||
//==============================================================
|
||||
////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
//==============================================================
|
||||
// SETUP FOR CRTS
|
||||
//--------------------------------------------------------------
|
||||
//==============================================================
|
||||
//#define CRTS_DEBUG 1
|
||||
#define CRTS_GPU 1
|
||||
#define CRTS_GLSL 1
|
||||
//--------------------------------------------------------------
|
||||
//#define CRTS_2_TAP 1
|
||||
//--------------------------------------------------------------
|
||||
#define CRTS_TONE 1
|
||||
#define CRTS_CONTRAST 0
|
||||
#define CRTS_SATURATION 0
|
||||
//--------------------------------------------------------------
|
||||
#define CRTS_WARP 1
|
||||
//--------------------------------------------------------------
|
||||
// Try different masks -> moved to runtime parameters
|
||||
//#define CRTS_MASK_GRILLE 1
|
||||
//#define CRTS_MASK_GRILLE_LITE 1
|
||||
//#define CRTS_MASK_NONE 1
|
||||
//#define CRTS_MASK_SHADOW 1
|
||||
//--------------------------------------------------------------
|
||||
// Scanline thinness
|
||||
// 0.50 = fused scanlines
|
||||
// 0.70 = recommended default
|
||||
// 1.00 = thinner scanlines (too thin)
|
||||
#define INPUT_THIN 0.5 + (0.5 * SCANLINE_THINNESS)
|
||||
//--------------------------------------------------------------
|
||||
// Horizonal scan blur
|
||||
// -3.0 = pixely
|
||||
// -2.5 = default
|
||||
// -2.0 = smooth
|
||||
// -1.0 = too blurry
|
||||
#define INPUT_BLUR -1.0 * SCAN_BLUR
|
||||
//--------------------------------------------------------------
|
||||
// Shadow mask effect, ranges from,
|
||||
// 0.25 = large amount of mask (not recommended, too dark)
|
||||
// 0.50 = recommended default
|
||||
// 1.00 = no shadow mask
|
||||
#define INPUT_MASK 1.0 - MASK_INTENSITY
|
||||
//--------------------------------------------------------------
|
||||
#define INPUT_X InputSize.x
|
||||
#define INPUT_Y InputSize.y
|
||||
//--------------------------------------------------------------
|
||||
// Setup the function which returns input image color
|
||||
vec3 CrtsFetch(vec2 uv){
|
||||
// For shadertoy, scale to get native texels in the image
|
||||
uv*=vec2(INPUT_X,INPUT_Y)/TextureSize.xy;
|
||||
// Move towards intersting parts
|
||||
// uv+=vec2(0.5,0.5);
|
||||
// Non-shadertoy case would not have the color conversion
|
||||
return FromSrgb(COMPAT_TEXTURE(Texture,uv.xy,-16.0).rgb);}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////
|
||||
//_____________________________/\_______________________________
|
||||
//==============================================================
|
||||
//
|
||||
// GPU CODE
|
||||
//
|
||||
//==============================================================
|
||||
#ifdef CRTS_GPU
|
||||
//_____________________________/\_______________________________
|
||||
//==============================================================
|
||||
// PORTABILITY
|
||||
//==============================================================
|
||||
#ifdef CRTS_GLSL
|
||||
#define CrtsF1 float
|
||||
#define CrtsF2 vec2
|
||||
#define CrtsF3 vec3
|
||||
#define CrtsF4 vec4
|
||||
#define CrtsFractF1 fract
|
||||
#define CrtsRcpF1(x) (1.0/(x))
|
||||
#define CrtsSatF1(x) clamp((x),0.0,1.0)
|
||||
//--------------------------------------------------------------
|
||||
CrtsF1 CrtsMax3F1(CrtsF1 a,CrtsF1 b,CrtsF1 c){
|
||||
return max(a,max(b,c));}
|
||||
#endif
|
||||
//==============================================================
|
||||
#ifdef CRTS_HLSL
|
||||
#define CrtsF1 float
|
||||
#define CrtsF2 float2
|
||||
#define CrtsF3 float3
|
||||
#define CrtsF4 float4
|
||||
#define CrtsFractF1 frac
|
||||
#define CrtsRcpF1(x) (1.0/(x))
|
||||
#define CrtsSatF1(x) saturate(x)
|
||||
//--------------------------------------------------------------
|
||||
CrtsF1 CrtsMax3F1(CrtsF1 a,CrtsF1 b,CrtsF1 c){
|
||||
return max(a,max(b,c));}
|
||||
#endif
|
||||
//_____________________________/\_______________________________
|
||||
//==============================================================
|
||||
// TONAL CONTROL CONSTANT GENERATION
|
||||
//--------------------------------------------------------------
|
||||
// This is in here for rapid prototyping
|
||||
// Please use the CPU code and pass in as constants
|
||||
//==============================================================
|
||||
CrtsF4 CrtsTone(
|
||||
CrtsF1 contrast,
|
||||
CrtsF1 saturation,
|
||||
CrtsF1 thin,
|
||||
CrtsF1 mask){
|
||||
//--------------------------------------------------------------
|
||||
if(MASK == 0.0) mask=1.0;
|
||||
//--------------------------------------------------------------
|
||||
if(MASK == 1.0){
|
||||
// Normal R mask is {1.0,mask,mask}
|
||||
// LITE R mask is {mask,1.0,1.0}
|
||||
mask=0.5+mask*0.5;
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
CrtsF4 ret;
|
||||
CrtsF1 midOut=0.18/((1.5-thin)*(0.5*mask+0.5));
|
||||
CrtsF1 pMidIn=pow(0.18,contrast);
|
||||
ret.x=contrast;
|
||||
ret.y=((-pMidIn)+midOut)/((1.0-pMidIn)*midOut);
|
||||
ret.z=((-pMidIn)*midOut+pMidIn)/(midOut*(-pMidIn)+midOut);
|
||||
ret.w=contrast+saturation;
|
||||
return ret;}
|
||||
//_____________________________/\_______________________________
|
||||
//==============================================================
|
||||
// MASK
|
||||
//--------------------------------------------------------------
|
||||
// Letting LCD/OLED pixel elements function like CRT phosphors
|
||||
// So "phosphor" resolution scales with display resolution
|
||||
//--------------------------------------------------------------
|
||||
// Not applying any warp to the mask (want high frequency)
|
||||
// Real aperture grille has a mask which gets wider on ends
|
||||
// Not attempting to be "real" but instead look the best
|
||||
//--------------------------------------------------------------
|
||||
// Shadow mask is stretched horizontally
|
||||
// RRGGBB
|
||||
// GBBRRG
|
||||
// RRGGBB
|
||||
// This tends to look better on LCDs than vertical
|
||||
// Also 2 pixel width is required to get triad centered
|
||||
//--------------------------------------------------------------
|
||||
// The LITE version of the Aperture Grille is brighter
|
||||
// Uses {dark,1.0,1.0} for R channel
|
||||
// Non LITE version uses {1.0,dark,dark}
|
||||
//--------------------------------------------------------------
|
||||
// 'pos' - This is 'fragCoord.xy'
|
||||
// Pixel {0,0} should be {0.5,0.5}
|
||||
// Pixel {1,1} should be {1.5,1.5}
|
||||
//--------------------------------------------------------------
|
||||
// 'dark' - Exposure of of masked channel
|
||||
// 0.0=fully off, 1.0=no effect
|
||||
//==============================================================
|
||||
CrtsF3 CrtsMask(CrtsF2 pos,CrtsF1 dark){
|
||||
if(MASK == 2.0){
|
||||
CrtsF3 m=CrtsF3(dark,dark,dark);
|
||||
CrtsF1 x=CrtsFractF1(pos.x*(1.0/3.0));
|
||||
if(x<(1.0/3.0))m.r=1.0;
|
||||
else if(x<(2.0/3.0))m.g=1.0;
|
||||
else m.b=1.0;
|
||||
return m;
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
if(MASK == 1.0){
|
||||
CrtsF3 m=CrtsF3(1.0,1.0,1.0);
|
||||
CrtsF1 x=CrtsFractF1(pos.x*(1.0/3.0));
|
||||
if(x<(1.0/3.0))m.r=dark;
|
||||
else if(x<(2.0/3.0))m.g=dark;
|
||||
else m.b=dark;
|
||||
return m;
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
if(MASK == 0.0){
|
||||
return CrtsF3(1.0,1.0,1.0);
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
if(MASK == 3.0){
|
||||
pos.x+=pos.y*2.9999;
|
||||
CrtsF3 m=CrtsF3(dark,dark,dark);
|
||||
CrtsF1 x=CrtsFractF1(pos.x*(1.0/6.0));
|
||||
if(x<(1.0/3.0))m.r=1.0;
|
||||
else if(x<(2.0/3.0))m.g=1.0;
|
||||
else m.b=1.0;
|
||||
return m;
|
||||
}
|
||||
}
|
||||
//_____________________________/\_______________________________
|
||||
//==============================================================
|
||||
// FILTER ENTRY
|
||||
//--------------------------------------------------------------
|
||||
// Input must be linear
|
||||
// Output color is linear
|
||||
//--------------------------------------------------------------
|
||||
// Must have fetch function setup: CrtsF3 CrtsFetch(CrtsF2 uv)
|
||||
// - The 'uv' range is {0.0 to 1.0} for input texture
|
||||
// - Output of this must be linear color
|
||||
//--------------------------------------------------------------
|
||||
// SCANLINE MATH & AUTO-EXPOSURE NOTES
|
||||
// ===================================
|
||||
// Each output line has contribution from at most 2 scanlines
|
||||
// Scanlines are shaped by a windowed cosine function
|
||||
// This shape blends together well with only 2 lines of overlap
|
||||
//--------------------------------------------------------------
|
||||
// Base scanline intensity is as follows
|
||||
// which leaves output intensity range from {0 to 1.0}
|
||||
// --------
|
||||
// thin := range {thick 0.5 to thin 1.0}
|
||||
// off := range {0.0 to <1.0},
|
||||
// sub-pixel offset between two scanlines
|
||||
// --------
|
||||
// a0=cos(min(0.5, off *thin)*2pi)*0.5+0.5;
|
||||
// a1=cos(min(0.5,(1.0-off)*thin)*2pi)*0.5+0.5;
|
||||
//--------------------------------------------------------------
|
||||
// This leads to a image darkening factor of roughly:
|
||||
// {(1.5-thin)/1.0}
|
||||
// This is further reduced by the mask:
|
||||
// {1.0/2.0+mask*1.0/2.0}
|
||||
// Reciprocal of combined effect is used for auto-exposure
|
||||
// to scale up the mid-level in the tonemapper
|
||||
//==============================================================
|
||||
CrtsF3 CrtsFilter(
|
||||
//--------------------------------------------------------------
|
||||
// SV_POSITION, fragCoord.xy
|
||||
CrtsF2 ipos,
|
||||
//--------------------------------------------------------------
|
||||
// inputSize / outputSize (in pixels)
|
||||
CrtsF2 inputSizeDivOutputSize,
|
||||
//--------------------------------------------------------------
|
||||
// 0.5 * inputSize (in pixels)
|
||||
CrtsF2 halfInputSize,
|
||||
//--------------------------------------------------------------
|
||||
// 1.0 / inputSize (in pixels)
|
||||
CrtsF2 rcpInputSize,
|
||||
//--------------------------------------------------------------
|
||||
// 1.0 / outputSize (in pixels)
|
||||
CrtsF2 rcpOutputSize,
|
||||
//--------------------------------------------------------------
|
||||
// 2.0 / outputSize (in pixels)
|
||||
CrtsF2 twoDivOutputSize,
|
||||
//--------------------------------------------------------------
|
||||
// inputSize.y
|
||||
CrtsF1 inputHeight,
|
||||
//--------------------------------------------------------------
|
||||
// Warp scanlines but not phosphor mask
|
||||
// 0.0 = no warp
|
||||
// 1.0/64.0 = light warping
|
||||
// 1.0/32.0 = more warping
|
||||
// Want x and y warping to be different (based on aspect)
|
||||
CrtsF2 warp,
|
||||
//--------------------------------------------------------------
|
||||
// Scanline thinness
|
||||
// 0.50 = fused scanlines
|
||||
// 0.70 = recommended default
|
||||
// 1.00 = thinner scanlines (too thin)
|
||||
// Shared with CrtsTone() function
|
||||
CrtsF1 thin,
|
||||
//--------------------------------------------------------------
|
||||
// Horizonal scan blur
|
||||
// -3.0 = pixely
|
||||
// -2.5 = default
|
||||
// -2.0 = smooth
|
||||
// -1.0 = too blurry
|
||||
CrtsF1 blur,
|
||||
//--------------------------------------------------------------
|
||||
// Shadow mask effect, ranges from,
|
||||
// 0.25 = large amount of mask (not recommended, too dark)
|
||||
// 0.50 = recommended default
|
||||
// 1.00 = no shadow mask
|
||||
// Shared with CrtsTone() function
|
||||
CrtsF1 mask,
|
||||
//--------------------------------------------------------------
|
||||
// Tonal curve parameters generated by CrtsTone()
|
||||
CrtsF4 tone
|
||||
//--------------------------------------------------------------
|
||||
){
|
||||
//--------------------------------------------------------------
|
||||
#ifdef CRTS_DEBUG
|
||||
CrtsF2 uv=ipos*rcpOutputSize;
|
||||
// Show second half processed, and first half un-processed
|
||||
if(uv.x<0.5){
|
||||
// Force nearest to get squares
|
||||
uv*=1.0/rcpInputSize;
|
||||
uv=floor(uv)+CrtsF2(0.5,0.5);
|
||||
uv*=rcpInputSize;
|
||||
CrtsF3 color=CrtsFetch(uv);
|
||||
return color;}
|
||||
#endif
|
||||
//--------------------------------------------------------------
|
||||
// Optional apply warp
|
||||
CrtsF2 pos;
|
||||
#ifdef CRTS_WARP
|
||||
// Convert to {-1 to 1} range
|
||||
pos=ipos*twoDivOutputSize-CrtsF2(1.0,1.0);
|
||||
// Distort pushes image outside {-1 to 1} range
|
||||
pos*=CrtsF2(
|
||||
1.0+(pos.y*pos.y)*warp.x,
|
||||
1.0+(pos.x*pos.x)*warp.y);
|
||||
// TODO: Vignette needs optimization
|
||||
CrtsF1 vin=(1.0-(
|
||||
(1.0-CrtsSatF1(pos.x*pos.x))*(1.0-CrtsSatF1(pos.y*pos.y)))) * (0.998 + (0.001 * CORNER));
|
||||
vin=CrtsSatF1((-vin)*inputHeight+inputHeight);
|
||||
// Leave in {0 to inputSize}
|
||||
pos=pos*halfInputSize+halfInputSize;
|
||||
#else
|
||||
pos=ipos*inputSizeDivOutputSize;
|
||||
#endif
|
||||
//--------------------------------------------------------------
|
||||
// Snap to center of first scanline
|
||||
CrtsF1 y0=floor(pos.y-0.5)+0.5;
|
||||
#ifdef CRTS_2_TAP
|
||||
// Using Inigo's "Improved Texture Interpolation"
|
||||
// http://iquilezles.org/www/articles/texture/texture.htm
|
||||
pos.x+=0.5;
|
||||
CrtsF1 xi=floor(pos.x);
|
||||
CrtsF1 xf=pos.x-xi;
|
||||
xf=xf*xf*xf*(xf*(xf*6.0-15.0)+10.0);
|
||||
CrtsF1 x0=xi+xf-0.5;
|
||||
CrtsF2 p=CrtsF2(x0*rcpInputSize.x,y0*rcpInputSize.y);
|
||||
// Coordinate adjusted bilinear fetch from 2 nearest scanlines
|
||||
CrtsF3 colA=CrtsFetch(p);
|
||||
p.y+=rcpInputSize.y;
|
||||
CrtsF3 colB=CrtsFetch(p);
|
||||
#else
|
||||
// Snap to center of one of four pixels
|
||||
CrtsF1 x0=floor(pos.x-1.5)+0.5;
|
||||
// Inital UV position
|
||||
CrtsF2 p=CrtsF2(x0*rcpInputSize.x,y0*rcpInputSize.y);
|
||||
// Fetch 4 nearest texels from 2 nearest scanlines
|
||||
CrtsF3 colA0=CrtsFetch(p);
|
||||
p.x+=rcpInputSize.x;
|
||||
CrtsF3 colA1=CrtsFetch(p);
|
||||
p.x+=rcpInputSize.x;
|
||||
CrtsF3 colA2=CrtsFetch(p);
|
||||
p.x+=rcpInputSize.x;
|
||||
CrtsF3 colA3=CrtsFetch(p);
|
||||
p.y+=rcpInputSize.y;
|
||||
CrtsF3 colB3=CrtsFetch(p);
|
||||
p.x-=rcpInputSize.x;
|
||||
CrtsF3 colB2=CrtsFetch(p);
|
||||
p.x-=rcpInputSize.x;
|
||||
CrtsF3 colB1=CrtsFetch(p);
|
||||
p.x-=rcpInputSize.x;
|
||||
CrtsF3 colB0=CrtsFetch(p);
|
||||
#endif
|
||||
//--------------------------------------------------------------
|
||||
// Vertical filter
|
||||
// Scanline intensity is using sine wave
|
||||
// Easy filter window and integral used later in exposure
|
||||
CrtsF1 off=pos.y-y0;
|
||||
CrtsF1 pi2=6.28318530717958;
|
||||
CrtsF1 hlf=0.5;
|
||||
CrtsF1 scanA=cos(min(0.5, off *thin )*pi2)*hlf+hlf;
|
||||
CrtsF1 scanB=cos(min(0.5,(-off)*thin+thin)*pi2)*hlf+hlf;
|
||||
//--------------------------------------------------------------
|
||||
#ifdef CRTS_2_TAP
|
||||
#ifdef CRTS_WARP
|
||||
// Get rid of wrong pixels on edge
|
||||
scanA*=vin;
|
||||
scanB*=vin;
|
||||
#endif
|
||||
// Apply vertical filter
|
||||
CrtsF3 color=(colA*scanA)+(colB*scanB);
|
||||
#else
|
||||
// Horizontal kernel is simple gaussian filter
|
||||
CrtsF1 off0=pos.x-x0;
|
||||
CrtsF1 off1=off0-1.0;
|
||||
CrtsF1 off2=off0-2.0;
|
||||
CrtsF1 off3=off0-3.0;
|
||||
CrtsF1 pix0=exp2(blur*off0*off0);
|
||||
CrtsF1 pix1=exp2(blur*off1*off1);
|
||||
CrtsF1 pix2=exp2(blur*off2*off2);
|
||||
CrtsF1 pix3=exp2(blur*off3*off3);
|
||||
CrtsF1 pixT=CrtsRcpF1(pix0+pix1+pix2+pix3);
|
||||
#ifdef CRTS_WARP
|
||||
// Get rid of wrong pixels on edge
|
||||
pixT*=vin;
|
||||
#endif
|
||||
scanA*=pixT;
|
||||
scanB*=pixT;
|
||||
// Apply horizontal and vertical filters
|
||||
CrtsF3 color=
|
||||
(colA0*pix0+colA1*pix1+colA2*pix2+colA3*pix3)*scanA +
|
||||
(colB0*pix0+colB1*pix1+colB2*pix2+colB3*pix3)*scanB;
|
||||
#endif
|
||||
//--------------------------------------------------------------
|
||||
// Apply phosphor mask
|
||||
color*=CrtsMask(ipos,mask);
|
||||
//--------------------------------------------------------------
|
||||
// Optional color processing
|
||||
#ifdef CRTS_TONE
|
||||
// Tonal control, start by protecting from /0
|
||||
CrtsF1 peak=max(1.0/(256.0*65536.0),
|
||||
CrtsMax3F1(color.r,color.g,color.b));
|
||||
// Compute the ratios of {R,G,B}
|
||||
CrtsF3 ratio=color*CrtsRcpF1(peak);
|
||||
// Apply tonal curve to peak value
|
||||
#ifdef CRTS_CONTRAST
|
||||
peak=pow(peak,tone.x);
|
||||
#endif
|
||||
peak=peak*CrtsRcpF1(peak*tone.y+tone.z);
|
||||
// Apply saturation
|
||||
#ifdef CRTS_SATURATION
|
||||
ratio=pow(ratio,CrtsF3(tone.w,tone.w,tone.w));
|
||||
#endif
|
||||
// Reconstruct color
|
||||
return ratio*peak;
|
||||
#else
|
||||
return color;
|
||||
#endif
|
||||
//--------------------------------------------------------------
|
||||
}
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 warp_factor;
|
||||
warp_factor.x = CURVATURE;
|
||||
warp_factor.y = (3.0 / 4.0) * warp_factor.x; // assume 4:3 aspect
|
||||
warp_factor.x *= (1.0 - TRINITRON_CURVE);
|
||||
FragColor.rgb = CrtsFilter(vTexCoord.xy * OutputSize.xy*(TextureSize.xy / InputSize.xy),
|
||||
InputSize.xy / OutputSize.xy,
|
||||
InputSize.xy * vec2(0.5,0.5),
|
||||
1.0/InputSize.xy,
|
||||
1.0/OutputSize.xy,
|
||||
2.0/OutputSize.xy,
|
||||
InputSize.y,
|
||||
warp_factor,
|
||||
INPUT_THIN,
|
||||
INPUT_BLUR,
|
||||
INPUT_MASK,
|
||||
CrtsTone(1.0,0.0,INPUT_THIN,INPUT_MASK));
|
||||
|
||||
// Shadertoy outputs non-linear color
|
||||
FragColor.rgb=ToSrgb(FragColor.rgb);
|
||||
}
|
||||
#endif
|
||||
73
Shaders/interpolation/bilinear.glsl
Normal file
73
Shaders/interpolation/bilinear.glsl
Normal file
@@ -0,0 +1,73 @@
|
||||
#if defined(VERTEX)
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
#define COMPAT_VARYING out
|
||||
#define COMPAT_ATTRIBUTE in
|
||||
#define COMPAT_TEXTURE texture
|
||||
#else
|
||||
#define COMPAT_VARYING varying
|
||||
#define COMPAT_ATTRIBUTE attribute
|
||||
#define COMPAT_TEXTURE texture2D
|
||||
#endif
|
||||
|
||||
#ifdef GL_ES
|
||||
#define COMPAT_PRECISION mediump
|
||||
#else
|
||||
#define COMPAT_PRECISION
|
||||
#endif
|
||||
|
||||
COMPAT_ATTRIBUTE vec4 VertexCoord;
|
||||
COMPAT_ATTRIBUTE vec4 COLOR;
|
||||
COMPAT_ATTRIBUTE vec4 TexCoord;
|
||||
COMPAT_VARYING vec4 COL0;
|
||||
COMPAT_VARYING vec4 TEX0;
|
||||
|
||||
uniform mat4 MVPMatrix;
|
||||
uniform COMPAT_PRECISION int FrameDirection;
|
||||
uniform COMPAT_PRECISION int FrameCount;
|
||||
uniform COMPAT_PRECISION vec2 OutputSize;
|
||||
uniform COMPAT_PRECISION vec2 TextureSize;
|
||||
uniform COMPAT_PRECISION vec2 InputSize;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = VertexCoord.x * MVPMatrix[0] + VertexCoord.y * MVPMatrix[1] + VertexCoord.z * MVPMatrix[2] + VertexCoord.w * MVPMatrix[3];
|
||||
TEX0.xy = TexCoord.xy;
|
||||
}
|
||||
|
||||
#elif defined(FRAGMENT)
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
#define COMPAT_VARYING in
|
||||
#define COMPAT_TEXTURE texture
|
||||
out vec4 FragColor;
|
||||
#else
|
||||
#define COMPAT_VARYING varying
|
||||
#define FragColor gl_FragColor
|
||||
#define COMPAT_TEXTURE texture2D
|
||||
#endif
|
||||
|
||||
#ifdef GL_ES
|
||||
#ifdef GL_FRAGMENT_PRECISION_HIGH
|
||||
precision highp float;
|
||||
#else
|
||||
precision mediump float;
|
||||
#endif
|
||||
#define COMPAT_PRECISION mediump
|
||||
#else
|
||||
#define COMPAT_PRECISION
|
||||
#endif
|
||||
|
||||
uniform COMPAT_PRECISION int FrameDirection;
|
||||
uniform COMPAT_PRECISION int FrameCount;
|
||||
uniform COMPAT_PRECISION vec2 OutputSize;
|
||||
uniform COMPAT_PRECISION vec2 TextureSize;
|
||||
uniform COMPAT_PRECISION vec2 InputSize;
|
||||
uniform sampler2D Texture;
|
||||
COMPAT_VARYING vec4 TEX0;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = COMPAT_TEXTURE(Texture, TEX0.xy);
|
||||
}
|
||||
#endif
|
||||
137
Shaders/interpolation/catmull-rom-bilinear.glsl
Normal file
137
Shaders/interpolation/catmull-rom-bilinear.glsl
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
The following code is licensed under the MIT license: https://gist.github.com/TheRealMJP/bc503b0b87b643d3505d41eab8b332ae
|
||||
Ported from code: https://gist.github.com/TheRealMJP/c83b8c0f46b63f3a88a5986f4fa982b1
|
||||
Samples a texture with Catmull-Rom filtering, using 9 texture fetches instead of 16.
|
||||
See http://vec3.ca/bicubic-filtering-in-fewer-taps/ for more details
|
||||
ATENTION: This code only work using LINEAR filter sampling set on Retroarch!
|
||||
Modified to use 5 texture fetches
|
||||
*/
|
||||
|
||||
#if defined(VERTEX)
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
#define COMPAT_VARYING out
|
||||
#define COMPAT_ATTRIBUTE in
|
||||
#define COMPAT_TEXTURE texture
|
||||
#else
|
||||
#define COMPAT_VARYING varying
|
||||
#define COMPAT_ATTRIBUTE attribute
|
||||
#define COMPAT_TEXTURE texture2D
|
||||
#endif
|
||||
|
||||
#ifdef GL_ES
|
||||
#define COMPAT_PRECISION mediump
|
||||
precision COMPAT_PRECISION float;
|
||||
#else
|
||||
#define COMPAT_PRECISION
|
||||
#endif
|
||||
|
||||
COMPAT_ATTRIBUTE vec4 VertexCoord;
|
||||
COMPAT_ATTRIBUTE vec4 COLOR;
|
||||
COMPAT_ATTRIBUTE vec4 TexCoord;
|
||||
COMPAT_VARYING vec4 COL0;
|
||||
COMPAT_VARYING vec4 TEX0;
|
||||
|
||||
uniform mat4 MVPMatrix;
|
||||
uniform COMPAT_PRECISION int FrameDirection;
|
||||
uniform COMPAT_PRECISION int FrameCount;
|
||||
uniform COMPAT_PRECISION vec2 OutputSize;
|
||||
uniform COMPAT_PRECISION vec2 TextureSize;
|
||||
uniform COMPAT_PRECISION vec2 InputSize;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = MVPMatrix * VertexCoord;
|
||||
COL0 = COLOR;
|
||||
TEX0.xy = TexCoord.xy;
|
||||
}
|
||||
|
||||
#elif defined(FRAGMENT)
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
#define COMPAT_VARYING in
|
||||
#define COMPAT_TEXTURE texture
|
||||
out mediump vec4 FragColor;
|
||||
#else
|
||||
#define COMPAT_VARYING varying
|
||||
#define FragColor gl_FragColor
|
||||
#define COMPAT_TEXTURE texture2D
|
||||
#endif
|
||||
|
||||
#ifdef GL_ES
|
||||
#ifdef GL_FRAGMENT_PRECISION_HIGH
|
||||
precision highp float;
|
||||
#else
|
||||
precision mediump float;
|
||||
#endif
|
||||
#define COMPAT_PRECISION mediump
|
||||
#else
|
||||
#define COMPAT_PRECISION
|
||||
#endif
|
||||
|
||||
uniform COMPAT_PRECISION int FrameDirection;
|
||||
uniform COMPAT_PRECISION int FrameCount;
|
||||
uniform COMPAT_PRECISION vec2 OutputSize;
|
||||
uniform COMPAT_PRECISION vec2 TextureSize;
|
||||
uniform COMPAT_PRECISION vec2 InputSize;
|
||||
uniform sampler2D Texture;
|
||||
COMPAT_VARYING vec4 TEX0;
|
||||
|
||||
// compatibility #defines
|
||||
#define Source Texture
|
||||
#define vTexCoord TEX0.xy
|
||||
|
||||
#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
|
||||
#define outsize vec4(OutputSize, 1.0 / OutputSize)
|
||||
|
||||
void main()
|
||||
{
|
||||
// We're going to sample a a 4x4 grid of texels surrounding the target UV coordinate. We'll do this by rounding
|
||||
// down the sample location to get the exact center of our "starting" texel. The starting texel will be at
|
||||
// location [1, 1] in the grid, where [0, 0] is the top left corner.
|
||||
vec2 samplePos = vTexCoord * SourceSize.xy;
|
||||
vec2 texPos1 = floor(samplePos - 0.5) + 0.5;
|
||||
|
||||
// Compute the fractional offset from our starting texel to our original sample location, which we'll
|
||||
// feed into the Catmull-Rom spline function to get our filter weights.
|
||||
vec2 f = samplePos - texPos1;
|
||||
|
||||
// Compute the Catmull-Rom weights using the fractional offset that we calculated earlier.
|
||||
// These equations are pre-expanded based on our knowledge of where the texels will be located,
|
||||
// which lets us avoid having to evaluate a piece-wise function.
|
||||
vec2 w0 = f * (-0.5 + f * (1.0 - 0.5 * f));
|
||||
vec2 w1 = 1.0 + f * f * (-2.5 + 1.5 * f);
|
||||
vec2 w2 = f * (0.5 + f * (2.0 - 1.5 * f));
|
||||
vec2 w3 = f * f * (-0.5 + 0.5 * f);
|
||||
|
||||
// Work out weighting factors and sampling offsets that will let us use bilinear filtering to
|
||||
// simultaneously evaluate the middle 2 samples from the 4x4 grid.
|
||||
vec2 w12 = w1 + w2;
|
||||
vec2 offset12 = w2 / (w1 + w2);
|
||||
|
||||
// Compute the final UV coordinates we'll use for sampling the texture
|
||||
vec2 texPos0 = texPos1 - 1.;
|
||||
vec2 texPos3 = texPos1 + 2.;
|
||||
vec2 texPos12 = texPos1 + offset12;
|
||||
|
||||
texPos0 *= SourceSize.zw;
|
||||
texPos3 *= SourceSize.zw;
|
||||
texPos12 *= SourceSize.zw;
|
||||
|
||||
float wtm = w12.x * w0.y;
|
||||
float wml = w0.x * w12.y;
|
||||
float wmm = w12.x * w12.y;
|
||||
float wmr = w3.x * w12.y;
|
||||
float wbm = w12.x * w3.y;
|
||||
|
||||
vec3 result = vec3(0.0f);
|
||||
|
||||
result += COMPAT_TEXTURE(Source, vec2(texPos12.x, texPos0.y)).rgb * wtm;
|
||||
result += COMPAT_TEXTURE(Source, vec2(texPos0.x, texPos12.y)).rgb * wml;
|
||||
result += COMPAT_TEXTURE(Source, vec2(texPos12.x, texPos12.y)).rgb * wmm;
|
||||
result += COMPAT_TEXTURE(Source, vec2(texPos3.x, texPos12.y)).rgb * wmr;
|
||||
result += COMPAT_TEXTURE(Source, vec2(texPos12.x, texPos3.y)).rgb * wbm;
|
||||
|
||||
FragColor = vec4(result * (1./(wtm+wml+wmm+wmr+wbm)), 1.0);
|
||||
}
|
||||
#endif
|
||||
324
Shaders/interpolation/fsr.glsl
Normal file
324
Shaders/interpolation/fsr.glsl
Normal file
@@ -0,0 +1,324 @@
|
||||
/*
|
||||
FSR - [EASU] EDGE ADAPTIVE SPATIAL UPSAMPLING
|
||||
Ported from https://www.shadertoy.com/view/stXSWB, MIT license
|
||||
*/
|
||||
|
||||
#if defined(VERTEX)
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
#define COMPAT_VARYING out
|
||||
#define COMPAT_ATTRIBUTE in
|
||||
#define COMPAT_TEXTURE texture
|
||||
#else
|
||||
#define COMPAT_VARYING varying
|
||||
#define COMPAT_ATTRIBUTE attribute
|
||||
#define COMPAT_TEXTURE texture2D
|
||||
#endif
|
||||
|
||||
#ifdef GL_ES
|
||||
#define COMPAT_PRECISION mediump
|
||||
#else
|
||||
#define COMPAT_PRECISION
|
||||
#endif
|
||||
|
||||
COMPAT_ATTRIBUTE vec4 VertexCoord;
|
||||
COMPAT_ATTRIBUTE vec4 COLOR;
|
||||
COMPAT_ATTRIBUTE vec4 TexCoord;
|
||||
COMPAT_VARYING vec4 COL0;
|
||||
COMPAT_VARYING vec4 TEX0;
|
||||
|
||||
uniform mat4 MVPMatrix;
|
||||
uniform COMPAT_PRECISION int FrameDirection;
|
||||
uniform COMPAT_PRECISION int FrameCount;
|
||||
uniform COMPAT_PRECISION vec2 OutputSize;
|
||||
uniform COMPAT_PRECISION vec2 TextureSize;
|
||||
uniform COMPAT_PRECISION vec2 InputSize;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = MVPMatrix * VertexCoord;
|
||||
COL0 = COLOR;
|
||||
TEX0.xy = TexCoord.xy;
|
||||
}
|
||||
|
||||
#elif defined(FRAGMENT)
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
#define COMPAT_VARYING in
|
||||
#define COMPAT_TEXTURE texture
|
||||
out vec4 FragColor;
|
||||
#else
|
||||
#define COMPAT_VARYING varying
|
||||
#define FragColor gl_FragColor
|
||||
#define COMPAT_TEXTURE texture2D
|
||||
#endif
|
||||
|
||||
#ifdef GL_ES
|
||||
#ifdef GL_FRAGMENT_PRECISION_HIGH
|
||||
precision highp float;
|
||||
#else
|
||||
precision mediump float;
|
||||
#endif
|
||||
#define COMPAT_PRECISION mediump
|
||||
#else
|
||||
#define COMPAT_PRECISION
|
||||
#endif
|
||||
|
||||
uniform COMPAT_PRECISION int FrameDirection;
|
||||
uniform COMPAT_PRECISION int FrameCount;
|
||||
uniform COMPAT_PRECISION vec2 OutputSize;
|
||||
uniform COMPAT_PRECISION vec2 TextureSize;
|
||||
uniform COMPAT_PRECISION vec2 InputSize;
|
||||
uniform sampler2D Texture;
|
||||
COMPAT_VARYING vec4 TEX0;
|
||||
|
||||
// compatibility #defines
|
||||
#define Source Texture
|
||||
#define vTexCoord TEX0.xy
|
||||
|
||||
#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
|
||||
#define outsize vec4(OutputSize, 1.0 / OutputSize)
|
||||
|
||||
vec3 FsrEasuCF(vec2 p) {
|
||||
return COMPAT_TEXTURE(Source,p).rgb;
|
||||
}
|
||||
|
||||
/**** EASU ****/
|
||||
void FsrEasuCon(
|
||||
out vec4 con0,
|
||||
out vec4 con1,
|
||||
out vec4 con2,
|
||||
out vec4 con3,
|
||||
// This the rendered image resolution being upscaled
|
||||
vec2 inputViewportInPixels,
|
||||
// This is the resolution of the resource containing the input image (useful for dynamic resolution)
|
||||
vec2 inputSizeInPixels,
|
||||
// This is the display resolution which the input image gets upscaled to
|
||||
vec2 outputSizeInPixels
|
||||
)
|
||||
{
|
||||
// Output integer position to a pixel position in viewport.
|
||||
con0 = vec4(
|
||||
inputViewportInPixels.x/outputSizeInPixels.x,
|
||||
inputViewportInPixels.y/outputSizeInPixels.y,
|
||||
.5*inputViewportInPixels.x/outputSizeInPixels.x-.5,
|
||||
.5*inputViewportInPixels.y/outputSizeInPixels.y-.5
|
||||
);
|
||||
// Viewport pixel position to normalized image space.
|
||||
// This is used to get upper-left of 'F' tap.
|
||||
con1 = vec4(1,1,1,-1)/inputSizeInPixels.xyxy;
|
||||
// Centers of gather4, first offset from upper-left of 'F'.
|
||||
// +---+---+
|
||||
// | | |
|
||||
// +--(0)--+
|
||||
// | b | c |
|
||||
// +---F---+---+---+
|
||||
// | e | f | g | h |
|
||||
// +--(1)--+--(2)--+
|
||||
// | i | j | k | l |
|
||||
// +---+---+---+---+
|
||||
// | n | o |
|
||||
// +--(3)--+
|
||||
// | | |
|
||||
// +---+---+
|
||||
// These are from (0) instead of 'F'.
|
||||
con2 = vec4(-1,2,1,2)/inputSizeInPixels.xyxy;
|
||||
con3 = vec4(0,4,0,0)/inputSizeInPixels.xyxy;
|
||||
}
|
||||
|
||||
// Filtering for a given tap for the scalar.
|
||||
void FsrEasuTapF(
|
||||
inout vec3 aC, // Accumulated color, with negative lobe.
|
||||
inout float aW, // Accumulated weight.
|
||||
vec2 off, // Pixel offset from resolve position to tap.
|
||||
vec2 dir, // Gradient direction.
|
||||
vec2 len, // Length.
|
||||
float lob, // Negative lobe strength.
|
||||
float clp, // Clipping point.
|
||||
vec3 c
|
||||
)
|
||||
{
|
||||
// Tap color.
|
||||
// Rotate offset by direction.
|
||||
vec2 v = vec2(dot(off, dir), dot(off,vec2(-dir.y,dir.x)));
|
||||
// Anisotropy.
|
||||
v *= len;
|
||||
// Compute distance^2.
|
||||
float d2 = min(dot(v,v),clp);
|
||||
// Limit to the window as at corner, 2 taps can easily be outside.
|
||||
// Approximation of lancos2 without sin() or rcp(), or sqrt() to get x.
|
||||
// (25/16 * (2/5 * x^2 - 1)^2 - (25/16 - 1)) * (1/4 * x^2 - 1)^2
|
||||
// |_______________________________________| |_______________|
|
||||
// base window
|
||||
// The general form of the 'base' is,
|
||||
// (a*(b*x^2-1)^2-(a-1))
|
||||
// Where 'a=1/(2*b-b^2)' and 'b' moves around the negative lobe.
|
||||
float wB = .4 * d2 - 1.;
|
||||
float wA = lob * d2 -1.;
|
||||
wB *= wB;
|
||||
wA *= wA;
|
||||
wB = 1.5625*wB-.5625;
|
||||
float w= wB * wA;
|
||||
// Do weighted average.
|
||||
aC += c*w;
|
||||
aW += w;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
// Accumulate direction and length.
|
||||
void FsrEasuSetF(
|
||||
inout vec2 dir,
|
||||
inout float len,
|
||||
float w,
|
||||
float lA,float lB,float lC,float lD,float lE
|
||||
)
|
||||
{
|
||||
// Direction is the '+' diff.
|
||||
// a
|
||||
// b c d
|
||||
// e
|
||||
// Then takes magnitude from abs average of both sides of 'c'.
|
||||
// Length converts gradient reversal to 0, smoothly to non-reversal at 1, shaped, then adding horz and vert terms.
|
||||
float lenX = max(abs(lD - lC), abs(lC - lB));
|
||||
float dirX = lD - lB;
|
||||
dir.x += dirX * w;
|
||||
lenX = clamp(abs(dirX)/lenX,0.,1.);
|
||||
lenX *= lenX;
|
||||
len += lenX * w;
|
||||
// Repeat for the y axis.
|
||||
float lenY = max(abs(lE - lC), abs(lC - lA));
|
||||
float dirY = lE - lA;
|
||||
dir.y += dirY * w;
|
||||
lenY = clamp(abs(dirY) / lenY,0.,1.);
|
||||
lenY *= lenY;
|
||||
len += lenY * w;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
void FsrEasuF(
|
||||
out vec3 pix,
|
||||
vec2 ip, // Integer pixel position in output.
|
||||
// Constants generated by FsrEasuCon().
|
||||
vec4 con0, // xy = output to input scale, zw = first pixel offset correction
|
||||
vec4 con1,
|
||||
vec4 con2,
|
||||
vec4 con3
|
||||
)
|
||||
{
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
// Get position of 'f'.
|
||||
vec2 pp = ip * con0.xy + con0.zw; // Corresponding input pixel/subpixel
|
||||
vec2 fp = floor(pp);// fp = source nearest pixel
|
||||
pp -= fp; // pp = source subpixel
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
// 12-tap kernel.
|
||||
// b c
|
||||
// e f g h
|
||||
// i j k l
|
||||
// n o
|
||||
// Gather 4 ordering.
|
||||
// a b
|
||||
// r g
|
||||
vec2 p0 = fp * con1.xy + con1.zw;
|
||||
|
||||
// These are from p0 to avoid pulling two constants on pre-Navi hardware.
|
||||
vec2 p1 = p0 + con2.xy;
|
||||
vec2 p2 = p0 + con2.zw;
|
||||
vec2 p3 = p0 + con3.xy;
|
||||
|
||||
// TextureGather is not available on WebGL2
|
||||
vec4 off = vec4(-.5,.5,-.5,.5)*con1.xxyy;
|
||||
// textureGather to texture offsets
|
||||
// x=west y=east z=north w=south
|
||||
vec3 bC = FsrEasuCF(p0 + off.xw); float bL = bC.g + 0.5 *(bC.r + bC.b);
|
||||
vec3 cC = FsrEasuCF(p0 + off.yw); float cL = cC.g + 0.5 *(cC.r + cC.b);
|
||||
vec3 iC = FsrEasuCF(p1 + off.xw); float iL = iC.g + 0.5 *(iC.r + iC.b);
|
||||
vec3 jC = FsrEasuCF(p1 + off.yw); float jL = jC.g + 0.5 *(jC.r + jC.b);
|
||||
vec3 fC = FsrEasuCF(p1 + off.yz); float fL = fC.g + 0.5 *(fC.r + fC.b);
|
||||
vec3 eC = FsrEasuCF(p1 + off.xz); float eL = eC.g + 0.5 *(eC.r + eC.b);
|
||||
vec3 kC = FsrEasuCF(p2 + off.xw); float kL = kC.g + 0.5 *(kC.r + kC.b);
|
||||
vec3 lC = FsrEasuCF(p2 + off.yw); float lL = lC.g + 0.5 *(lC.r + lC.b);
|
||||
vec3 hC = FsrEasuCF(p2 + off.yz); float hL = hC.g + 0.5 *(hC.r + hC.b);
|
||||
vec3 gC = FsrEasuCF(p2 + off.xz); float gL = gC.g + 0.5 *(gC.r + gC.b);
|
||||
vec3 oC = FsrEasuCF(p3 + off.yz); float oL = oC.g + 0.5 *(oC.r + oC.b);
|
||||
vec3 nC = FsrEasuCF(p3 + off.xz); float nL = nC.g + 0.5 *(nC.r + nC.b);
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
// Simplest multi-channel approximate luma possible (luma times 2, in 2 FMA/MAD).
|
||||
// Accumulate for bilinear interpolation.
|
||||
vec2 dir = vec2(0);
|
||||
float len = 0.;
|
||||
|
||||
FsrEasuSetF(dir, len, (1.-pp.x)*(1.-pp.y), bL, eL, fL, gL, jL);
|
||||
FsrEasuSetF(dir, len, pp.x *(1.-pp.y), cL, fL, gL, hL, kL);
|
||||
FsrEasuSetF(dir, len, (1.-pp.x)* pp.y , fL, iL, jL, kL, nL);
|
||||
FsrEasuSetF(dir, len, pp.x * pp.y , gL, jL, kL, lL, oL);
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
// Normalize with approximation, and cleanup close to zero.
|
||||
vec2 dir2 = dir * dir;
|
||||
float dirR = dir2.x + dir2.y;
|
||||
bool zro = dirR < (1.0/32768.0);
|
||||
dirR = inversesqrt(dirR);
|
||||
dirR = zro ? 1.0 : dirR;
|
||||
dir.x = zro ? 1.0 : dir.x;
|
||||
dir *= vec2(dirR);
|
||||
// Transform from {0 to 2} to {0 to 1} range, and shape with square.
|
||||
len = len * 0.5;
|
||||
len *= len;
|
||||
// Stretch kernel {1.0 vert|horz, to sqrt(2.0) on diagonal}.
|
||||
float stretch = dot(dir,dir) / (max(abs(dir.x), abs(dir.y)));
|
||||
// Anisotropic length after rotation,
|
||||
// x := 1.0 lerp to 'stretch' on edges
|
||||
// y := 1.0 lerp to 2x on edges
|
||||
vec2 len2 = vec2(1. +(stretch-1.0)*len, 1. -.5 * len);
|
||||
// Based on the amount of 'edge',
|
||||
// the window shifts from +/-{sqrt(2.0) to slightly beyond 2.0}.
|
||||
float lob = .5 - .29 * len;
|
||||
// Set distance^2 clipping point to the end of the adjustable window.
|
||||
float clp = 1./lob;
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
// Accumulation mixed with min/max of 4 nearest.
|
||||
// b c
|
||||
// e f g h
|
||||
// i j k l
|
||||
// n o
|
||||
vec3 min4 = min(min(fC,gC),min(jC,kC));
|
||||
vec3 max4 = max(max(fC,gC),max(jC,kC));
|
||||
// Accumulation.
|
||||
vec3 aC = vec3(0);
|
||||
float aW = 0.;
|
||||
FsrEasuTapF(aC, aW, vec2( 0,-1)-pp, dir, len2, lob, clp, bC);
|
||||
FsrEasuTapF(aC, aW, vec2( 1,-1)-pp, dir, len2, lob, clp, cC);
|
||||
FsrEasuTapF(aC, aW, vec2(-1, 1)-pp, dir, len2, lob, clp, iC);
|
||||
FsrEasuTapF(aC, aW, vec2( 0, 1)-pp, dir, len2, lob, clp, jC);
|
||||
FsrEasuTapF(aC, aW, vec2( 0, 0)-pp, dir, len2, lob, clp, fC);
|
||||
FsrEasuTapF(aC, aW, vec2(-1, 0)-pp, dir, len2, lob, clp, eC);
|
||||
FsrEasuTapF(aC, aW, vec2( 1, 1)-pp, dir, len2, lob, clp, kC);
|
||||
FsrEasuTapF(aC, aW, vec2( 2, 1)-pp, dir, len2, lob, clp, lC);
|
||||
FsrEasuTapF(aC, aW, vec2( 2, 0)-pp, dir, len2, lob, clp, hC);
|
||||
FsrEasuTapF(aC, aW, vec2( 1, 0)-pp, dir, len2, lob, clp, gC);
|
||||
FsrEasuTapF(aC, aW, vec2( 1, 2)-pp, dir, len2, lob, clp, oC);
|
||||
FsrEasuTapF(aC, aW, vec2( 0, 2)-pp, dir, len2, lob, clp, nC);
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
// Normalize and dering.
|
||||
pix=min(max4,max(min4,aC/aW));
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 c;
|
||||
vec4 con0,con1,con2,con3;
|
||||
|
||||
vec2 fragCoord = vTexCoord.xy * OutputSize.xy;
|
||||
|
||||
FsrEasuCon(
|
||||
con0, con1, con2, con3, SourceSize.xy, SourceSize.xy, OutputSize.xy
|
||||
);
|
||||
FsrEasuF(c, fragCoord, con0, con1, con2, con3);
|
||||
FragColor = vec4(c.xyz, 1);
|
||||
}
|
||||
|
||||
#endif
|
||||
178
Shaders/interpolation/fsr.glsl.pass1
Normal file
178
Shaders/interpolation/fsr.glsl.pass1
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
FSR - [RCAS] ROBUST CONTRAST ADAPTIVE SHARPENING
|
||||
Ported from https://www.shadertoy.com/view/stXSWB, MIT license
|
||||
*/
|
||||
|
||||
#pragma parameter FSR_SHARPENING "FSR RCAS Sharpening Amount (Lower = Sharper)" 0.6 0.0 2.0 0.1
|
||||
|
||||
#if defined(VERTEX)
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
#define COMPAT_VARYING out
|
||||
#define COMPAT_ATTRIBUTE in
|
||||
#define COMPAT_TEXTURE texture
|
||||
#else
|
||||
#define COMPAT_VARYING varying
|
||||
#define COMPAT_ATTRIBUTE attribute
|
||||
#define COMPAT_TEXTURE texture2D
|
||||
#endif
|
||||
|
||||
#ifdef GL_ES
|
||||
#define COMPAT_PRECISION mediump
|
||||
#else
|
||||
#define COMPAT_PRECISION
|
||||
#endif
|
||||
|
||||
COMPAT_ATTRIBUTE vec4 VertexCoord;
|
||||
COMPAT_ATTRIBUTE vec4 COLOR;
|
||||
COMPAT_ATTRIBUTE vec4 TexCoord;
|
||||
COMPAT_VARYING vec4 COL0;
|
||||
COMPAT_VARYING vec4 TEX0;
|
||||
|
||||
uniform mat4 MVPMatrix;
|
||||
uniform COMPAT_PRECISION int FrameDirection;
|
||||
uniform COMPAT_PRECISION int FrameCount;
|
||||
uniform COMPAT_PRECISION vec2 OutputSize;
|
||||
uniform COMPAT_PRECISION vec2 TextureSize;
|
||||
uniform COMPAT_PRECISION vec2 InputSize;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = MVPMatrix * VertexCoord;
|
||||
COL0 = COLOR;
|
||||
TEX0.xy = TexCoord.xy;
|
||||
}
|
||||
|
||||
#elif defined(FRAGMENT)
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
#define COMPAT_VARYING in
|
||||
#define COMPAT_TEXTURE texture
|
||||
out vec4 FragColor;
|
||||
#else
|
||||
#define COMPAT_VARYING varying
|
||||
#define FragColor gl_FragColor
|
||||
#define COMPAT_TEXTURE texture2D
|
||||
#endif
|
||||
|
||||
#ifdef GL_ES
|
||||
#ifdef GL_FRAGMENT_PRECISION_HIGH
|
||||
precision highp float;
|
||||
#else
|
||||
precision mediump float;
|
||||
#endif
|
||||
#define COMPAT_PRECISION mediump
|
||||
#else
|
||||
#define COMPAT_PRECISION
|
||||
#endif
|
||||
|
||||
uniform COMPAT_PRECISION int FrameDirection;
|
||||
uniform COMPAT_PRECISION int FrameCount;
|
||||
uniform COMPAT_PRECISION vec2 OutputSize;
|
||||
uniform COMPAT_PRECISION vec2 TextureSize;
|
||||
uniform COMPAT_PRECISION vec2 InputSize;
|
||||
uniform sampler2D Texture;
|
||||
COMPAT_VARYING vec4 TEX0;
|
||||
|
||||
// compatibility #defines
|
||||
#define Source Texture
|
||||
#define vTexCoord TEX0.xy
|
||||
|
||||
#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
|
||||
#define outsize vec4(OutputSize, 1.0 / OutputSize)
|
||||
|
||||
#ifdef PARAMETER_UNIFORM
|
||||
uniform COMPAT_PRECISION float FSR_SHARPENING;
|
||||
#else
|
||||
#define FSR_SHARPENING 0.6
|
||||
#endif
|
||||
|
||||
#define FSR_RCAS_LIMIT (0.25-(1.0/16.0))
|
||||
//#define FSR_RCAS_DENOISE
|
||||
|
||||
// Input callback prototypes that need to be implemented by calling shader
|
||||
vec4 FsrRcasLoadF(vec2 p);
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
void FsrRcasCon(
|
||||
out float con,
|
||||
// The scale is {0.0 := maximum, to N>0, where N is the number of stops (halving) of the reduction of sharpness}.
|
||||
float sharpness
|
||||
){
|
||||
// Transform from stops to linear value.
|
||||
con = exp2(-sharpness);
|
||||
}
|
||||
|
||||
vec3 FsrRcasF(
|
||||
vec2 ip, // Integer pixel position in output.
|
||||
float con
|
||||
)
|
||||
{
|
||||
// Constant generated by RcasSetup().
|
||||
// Algorithm uses minimal 3x3 pixel neighborhood.
|
||||
// b
|
||||
// d e f
|
||||
// h
|
||||
vec2 sp = vec2(ip);
|
||||
vec3 b = FsrRcasLoadF(sp + vec2( 0,-1)).rgb;
|
||||
vec3 d = FsrRcasLoadF(sp + vec2(-1, 0)).rgb;
|
||||
vec3 e = FsrRcasLoadF(sp).rgb;
|
||||
vec3 f = FsrRcasLoadF(sp+vec2( 1, 0)).rgb;
|
||||
vec3 h = FsrRcasLoadF(sp+vec2( 0, 1)).rgb;
|
||||
// Luma times 2.
|
||||
float bL = b.g + .5 * (b.b + b.r);
|
||||
float dL = d.g + .5 * (d.b + d.r);
|
||||
float eL = e.g + .5 * (e.b + e.r);
|
||||
float fL = f.g + .5 * (f.b + f.r);
|
||||
float hL = h.g + .5 * (h.b + h.r);
|
||||
// Noise detection.
|
||||
float nz = .25 * (bL + dL + fL + hL) - eL;
|
||||
nz=clamp(
|
||||
abs(nz)
|
||||
/(
|
||||
max(max(bL,dL),max(eL,max(fL,hL)))
|
||||
-min(min(bL,dL),min(eL,min(fL,hL)))
|
||||
),
|
||||
0., 1.
|
||||
);
|
||||
nz=1.-.5*nz;
|
||||
// Min and max of ring.
|
||||
vec3 mn4 = min(b, min(f, h));
|
||||
vec3 mx4 = max(b, max(f, h));
|
||||
// Immediate constants for peak range.
|
||||
vec2 peakC = vec2(1., -4.);
|
||||
// Limiters, these need to be high precision RCPs.
|
||||
vec3 hitMin = mn4 / (4. * mx4);
|
||||
vec3 hitMax = (peakC.x - mx4) / (4.* mn4 + peakC.y);
|
||||
vec3 lobeRGB = max(-hitMin, hitMax);
|
||||
float lobe = max(
|
||||
-FSR_RCAS_LIMIT,
|
||||
min(max(lobeRGB.r, max(lobeRGB.g, lobeRGB.b)), 0.)
|
||||
)*con;
|
||||
// Apply noise removal.
|
||||
#ifdef FSR_RCAS_DENOISE
|
||||
lobe *= nz;
|
||||
#endif
|
||||
// Resolve, which needs the medium precision rcp approximation to avoid visible tonality changes.
|
||||
return (lobe * (b + d + h + f) + e) / (4. * lobe + 1.);
|
||||
}
|
||||
|
||||
|
||||
vec4 FsrRcasLoadF(vec2 p) {
|
||||
return COMPAT_TEXTURE(Source,p/OutputSize.xy);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 fragCoord = vTexCoord.xy * OutputSize.xy;
|
||||
|
||||
// Set up constants
|
||||
float con;
|
||||
FsrRcasCon(con, FSR_SHARPENING);
|
||||
|
||||
// Perform RCAS pass
|
||||
vec3 col = FsrRcasF(fragCoord, con);
|
||||
|
||||
FragColor = vec4(col,1);
|
||||
}
|
||||
|
||||
#endif
|
||||
202
Shaders/interpolation/jinc2-dedither.glsl
Normal file
202
Shaders/interpolation/jinc2-dedither.glsl
Normal file
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
Hyllian's jinc windowed-jinc 2-lobe sharper with anti-ringing Shader
|
||||
|
||||
Copyright (C) 2011-2016 Hyllian/Jararaca - sergiogdb@gmail.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#define JINC2_WINDOW_SINC 0.405
|
||||
#define JINC2_SINC 0.79
|
||||
#define JINC2_AR_STRENGTH 0.8
|
||||
|
||||
#define texCoord TEX0
|
||||
|
||||
#if defined(VERTEX)
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
#define OUT out
|
||||
#define IN in
|
||||
#define tex2D texture
|
||||
#else
|
||||
#define OUT varying
|
||||
#define IN attribute
|
||||
#define tex2D texture2D
|
||||
#endif
|
||||
|
||||
#ifdef GL_ES
|
||||
#define COMPAT_PRECISION mediump
|
||||
#else
|
||||
#define COMPAT_PRECISION
|
||||
#endif
|
||||
|
||||
|
||||
IN vec4 VertexCoord;
|
||||
IN vec4 Color;
|
||||
IN vec2 TexCoord;
|
||||
OUT vec4 color;
|
||||
OUT vec2 texCoord;
|
||||
|
||||
uniform mat4 MVPMatrix;
|
||||
uniform COMPAT_PRECISION int FrameDirection;
|
||||
uniform COMPAT_PRECISION int FrameCount;
|
||||
uniform COMPAT_PRECISION vec2 OutputSize;
|
||||
uniform COMPAT_PRECISION vec2 TextureSize;
|
||||
uniform COMPAT_PRECISION vec2 InputSize;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = MVPMatrix * VertexCoord;
|
||||
color = Color;
|
||||
texCoord = TexCoord * 1.0001;
|
||||
}
|
||||
|
||||
#elif defined(FRAGMENT)
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
#define IN in
|
||||
#define tex2D texture
|
||||
out vec4 FragColor;
|
||||
#else
|
||||
#define IN varying
|
||||
#define FragColor gl_FragColor
|
||||
#define tex2D texture2D
|
||||
#endif
|
||||
|
||||
#ifdef GL_ES
|
||||
#ifdef GL_FRAGMENT_PRECISION_HIGH
|
||||
precision highp float;
|
||||
#else
|
||||
precision mediump float;
|
||||
#endif
|
||||
#define COMPAT_PRECISION mediump
|
||||
#else
|
||||
#define COMPAT_PRECISION
|
||||
#endif
|
||||
|
||||
uniform COMPAT_PRECISION int FrameDirection;
|
||||
uniform COMPAT_PRECISION int FrameCount;
|
||||
uniform COMPAT_PRECISION vec2 OutputSize;
|
||||
uniform COMPAT_PRECISION vec2 TextureSize;
|
||||
uniform COMPAT_PRECISION vec2 InputSize;
|
||||
uniform sampler2D s_p;
|
||||
IN vec2 texCoord;
|
||||
|
||||
const float halfpi = 1.5707963267948966192313216916398;
|
||||
const float pi = 3.1415926535897932384626433832795;
|
||||
const float wa = JINC2_WINDOW_SINC*pi;
|
||||
const float wb = JINC2_SINC*pi;
|
||||
|
||||
// Calculates the distance between two points
|
||||
float d(vec2 pt1, vec2 pt2)
|
||||
{
|
||||
vec2 v = pt2 - pt1;
|
||||
return sqrt(dot(v,v));
|
||||
}
|
||||
|
||||
vec3 min4(vec3 a, vec3 b, vec3 c, vec3 d)
|
||||
{
|
||||
return min(a, min(b, min(c, d)));
|
||||
}
|
||||
|
||||
vec3 max4(vec3 a, vec3 b, vec3 c, vec3 d)
|
||||
{
|
||||
return max(a, max(b, max(c, d)));
|
||||
}
|
||||
|
||||
vec4 resampler(vec4 x)
|
||||
{
|
||||
vec4 res;
|
||||
|
||||
res = (x==vec4(0.0, 0.0, 0.0, 0.0)) ? vec4(wa*wb) : sin(x*wa)*sin(x*wb)/(x*x);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
vec3 color;
|
||||
vec4 weights[4];
|
||||
|
||||
vec2 dx = vec2(1.0, 0.0);
|
||||
vec2 dy = vec2(0.0, 1.0);
|
||||
|
||||
vec2 pc = texCoord*TextureSize;
|
||||
|
||||
vec2 tc = (floor(pc-vec2(0.5,0.5))+vec2(0.5,0.5));
|
||||
|
||||
weights[0] = resampler(vec4(d(pc, tc -dx -dy), d(pc, tc -dy), d(pc, tc +dx -dy), d(pc, tc+2.0*dx -dy)));
|
||||
weights[1] = resampler(vec4(d(pc, tc -dx ), d(pc, tc ), d(pc, tc +dx ), d(pc, tc+2.0*dx )));
|
||||
weights[2] = resampler(vec4(d(pc, tc -dx +dy), d(pc, tc +dy), d(pc, tc +dx +dy), d(pc, tc+2.0*dx +dy)));
|
||||
weights[3] = resampler(vec4(d(pc, tc -dx+2.0*dy), d(pc, tc +2.0*dy), d(pc, tc +dx+2.0*dy), d(pc, tc+2.0*dx+2.0*dy)));
|
||||
|
||||
dx = dx/TextureSize;
|
||||
dy = dy/TextureSize;
|
||||
tc = tc/TextureSize;
|
||||
|
||||
vec3 c00 = tex2D(s_p, tc -dx -dy).xyz;
|
||||
vec3 c10 = tex2D(s_p, tc -dy).xyz;
|
||||
vec3 c20 = tex2D(s_p, tc +dx -dy).xyz;
|
||||
vec3 c30 = tex2D(s_p, tc+2.0*dx -dy).xyz;
|
||||
vec3 c01 = tex2D(s_p, tc -dx ).xyz;
|
||||
vec3 c11 = tex2D(s_p, tc ).xyz;
|
||||
vec3 c21 = tex2D(s_p, tc +dx ).xyz;
|
||||
vec3 c31 = tex2D(s_p, tc+2.0*dx ).xyz;
|
||||
vec3 c02 = tex2D(s_p, tc -dx +dy).xyz;
|
||||
vec3 c12 = tex2D(s_p, tc +dy).xyz;
|
||||
vec3 c22 = tex2D(s_p, tc +dx +dy).xyz;
|
||||
vec3 c32 = tex2D(s_p, tc+2.0*dx +dy).xyz;
|
||||
vec3 c03 = tex2D(s_p, tc -dx+2.0*dy).xyz;
|
||||
vec3 c13 = tex2D(s_p, tc +2.0*dy).xyz;
|
||||
vec3 c23 = tex2D(s_p, tc +dx+2.0*dy).xyz;
|
||||
vec3 c33 = tex2D(s_p, tc+2.0*dx+2.0*dy).xyz;
|
||||
|
||||
color = tex2D(s_p, texCoord).xyz;
|
||||
|
||||
// Get min/max samples
|
||||
vec3 min_sample = min4(c11, c21, c12, c22);
|
||||
vec3 max_sample = max4(c11, c21, c12, c22);
|
||||
/*
|
||||
color = mat4x3(c00, c10, c20, c30) * weights[0];
|
||||
color+= mat4x3(c01, c11, c21, c31) * weights[1];
|
||||
color+= mat4x3(c02, c12, c22, c32) * weights[2];
|
||||
color+= mat4x3(c03, c13, c23, c33) * weights[3];
|
||||
mat4 wgts = mat4(weights[0], weights[1], weights[2], weights[3]);
|
||||
vec4 wsum = wgts * vec4(1.0,1.0,1.0,1.0);
|
||||
color = color/(dot(wsum, vec4(1.0,1.0,1.0,1.0)));
|
||||
*/
|
||||
|
||||
|
||||
color = vec3(dot(weights[0], vec4(c00.x, c10.x, c20.x, c30.x)), dot(weights[0], vec4(c00.y, c10.y, c20.y, c30.y)), dot(weights[0], vec4(c00.z, c10.z, c20.z, c30.z)));
|
||||
color+= vec3(dot(weights[1], vec4(c01.x, c11.x, c21.x, c31.x)), dot(weights[1], vec4(c01.y, c11.y, c21.y, c31.y)), dot(weights[1], vec4(c01.z, c11.z, c21.z, c31.z)));
|
||||
color+= vec3(dot(weights[2], vec4(c02.x, c12.x, c22.x, c32.x)), dot(weights[2], vec4(c02.y, c12.y, c22.y, c32.y)), dot(weights[2], vec4(c02.z, c12.z, c22.z, c32.z)));
|
||||
color+= vec3(dot(weights[3], vec4(c03.x, c13.x, c23.x, c33.x)), dot(weights[3], vec4(c03.y, c13.y, c23.y, c33.y)), dot(weights[3], vec4(c03.z, c13.z, c23.z, c33.z)));
|
||||
color = color/(dot(weights[0], vec4(1,1,1,1)) + dot(weights[1], vec4(1,1,1,1)) + dot(weights[2], vec4(1,1,1,1)) + dot(weights[3], vec4(1,1,1,1)));
|
||||
|
||||
// Anti-ringing
|
||||
vec3 aux = color;
|
||||
color = clamp(color, min_sample, max_sample);
|
||||
color = mix(aux, color, JINC2_AR_STRENGTH);
|
||||
|
||||
// final sum and weight normalization
|
||||
FragColor.xyz = color;
|
||||
}
|
||||
#endif
|
||||
205
Shaders/interpolation/lanczos2-sharp.glsl
Normal file
205
Shaders/interpolation/lanczos2-sharp.glsl
Normal file
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
Hyllian's jinc windowed-jinc 2-lobe sharper with anti-ringing Shader
|
||||
|
||||
Copyright (C) 2011-2016 Hyllian/Jararaca - sergiogdb@gmail.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#define JINC2_WINDOW_SINC 0.5
|
||||
#define JINC2_SINC 1.0
|
||||
#define JINC2_AR_STRENGTH 0.8
|
||||
|
||||
#define texCoord TEX0
|
||||
|
||||
#if defined(VERTEX)
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
#define OUT out
|
||||
#define IN in
|
||||
#define tex2D texture
|
||||
#else
|
||||
#define OUT varying
|
||||
#define IN attribute
|
||||
#define tex2D texture2D
|
||||
#endif
|
||||
|
||||
#ifdef GL_ES
|
||||
#define COMPAT_PRECISION mediump
|
||||
#else
|
||||
#define COMPAT_PRECISION
|
||||
#endif
|
||||
|
||||
|
||||
IN vec4 VertexCoord;
|
||||
IN vec4 Color;
|
||||
IN vec2 TexCoord;
|
||||
OUT vec4 color;
|
||||
OUT vec2 texCoord;
|
||||
|
||||
uniform mat4 MVPMatrix;
|
||||
uniform COMPAT_PRECISION int FrameDirection;
|
||||
uniform COMPAT_PRECISION int FrameCount;
|
||||
uniform COMPAT_PRECISION vec2 OutputSize;
|
||||
uniform COMPAT_PRECISION vec2 TextureSize;
|
||||
uniform COMPAT_PRECISION vec2 InputSize;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = MVPMatrix * VertexCoord;
|
||||
color = Color;
|
||||
texCoord = TexCoord;
|
||||
}
|
||||
|
||||
#elif defined(FRAGMENT)
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
#define IN in
|
||||
#define tex2D texture
|
||||
out vec4 FragColor;
|
||||
#else
|
||||
#define IN varying
|
||||
#define FragColor gl_FragColor
|
||||
#define tex2D texture2D
|
||||
#endif
|
||||
|
||||
#ifdef GL_ES
|
||||
#ifdef GL_FRAGMENT_PRECISION_HIGH
|
||||
precision highp float;
|
||||
#else
|
||||
precision mediump float;
|
||||
#endif
|
||||
#define COMPAT_PRECISION mediump
|
||||
#else
|
||||
#define COMPAT_PRECISION
|
||||
#endif
|
||||
|
||||
uniform COMPAT_PRECISION int FrameDirection;
|
||||
uniform COMPAT_PRECISION int FrameCount;
|
||||
uniform COMPAT_PRECISION vec2 OutputSize;
|
||||
uniform COMPAT_PRECISION vec2 TextureSize;
|
||||
uniform COMPAT_PRECISION vec2 InputSize;
|
||||
uniform sampler2D s_p;
|
||||
IN vec2 texCoord;
|
||||
|
||||
const float halfpi = 1.5707963267948966192313216916398;
|
||||
const float pi = 3.1415926535897932384626433832795;
|
||||
const float wa = JINC2_WINDOW_SINC*pi;
|
||||
const float wb = JINC2_SINC*pi;
|
||||
|
||||
// Calculates the distance between two points
|
||||
float d(vec2 pt1, vec2 pt2)
|
||||
{
|
||||
vec2 v = pt2 - pt1;
|
||||
return sqrt(dot(v,v));
|
||||
}
|
||||
|
||||
vec3 min4(vec3 a, vec3 b, vec3 c, vec3 d)
|
||||
{
|
||||
return min(a, min(b, min(c, d)));
|
||||
}
|
||||
|
||||
vec3 max4(vec3 a, vec3 b, vec3 c, vec3 d)
|
||||
{
|
||||
return max(a, max(b, max(c, d)));
|
||||
}
|
||||
|
||||
vec4 resampler(vec4 x)
|
||||
{
|
||||
vec4 res;
|
||||
|
||||
res.x = (x.x==0.0) ? wa*wb : sin(x.x*wa)*sin(x.x*wb)/(x.x*x.x);
|
||||
res.y = (x.y==0.0) ? wa*wb : sin(x.y*wa)*sin(x.y*wb)/(x.y*x.y);
|
||||
res.z = (x.z==0.0) ? wa*wb : sin(x.z*wa)*sin(x.z*wb)/(x.z*x.z);
|
||||
res.w = (x.w==0.0) ? wa*wb : sin(x.w*wa)*sin(x.w*wb)/(x.w*x.w);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
vec3 color;
|
||||
vec4 weights[4];
|
||||
|
||||
vec2 dx = vec2(1.0, 0.0);
|
||||
vec2 dy = vec2(0.0, 1.0);
|
||||
|
||||
vec2 pc = texCoord*TextureSize;
|
||||
|
||||
vec2 tc = (floor(pc-vec2(0.5,0.5))+vec2(0.5,0.5));
|
||||
|
||||
weights[0] = resampler(vec4(d(pc, tc -dx -dy), d(pc, tc -dy), d(pc, tc +dx -dy), d(pc, tc+2.0*dx -dy)));
|
||||
weights[1] = resampler(vec4(d(pc, tc -dx ), d(pc, tc ), d(pc, tc +dx ), d(pc, tc+2.0*dx )));
|
||||
weights[2] = resampler(vec4(d(pc, tc -dx +dy), d(pc, tc +dy), d(pc, tc +dx +dy), d(pc, tc+2.0*dx +dy)));
|
||||
weights[3] = resampler(vec4(d(pc, tc -dx+2.0*dy), d(pc, tc +2.0*dy), d(pc, tc +dx+2.0*dy), d(pc, tc+2.0*dx+2.0*dy)));
|
||||
|
||||
dx = dx/TextureSize;
|
||||
dy = dy/TextureSize;
|
||||
tc = tc/TextureSize;
|
||||
|
||||
vec3 c00 = tex2D(s_p, tc -dx -dy).xyz;
|
||||
vec3 c10 = tex2D(s_p, tc -dy).xyz;
|
||||
vec3 c20 = tex2D(s_p, tc +dx -dy).xyz;
|
||||
vec3 c30 = tex2D(s_p, tc+2.0*dx -dy).xyz;
|
||||
vec3 c01 = tex2D(s_p, tc -dx ).xyz;
|
||||
vec3 c11 = tex2D(s_p, tc ).xyz;
|
||||
vec3 c21 = tex2D(s_p, tc +dx ).xyz;
|
||||
vec3 c31 = tex2D(s_p, tc+2.0*dx ).xyz;
|
||||
vec3 c02 = tex2D(s_p, tc -dx +dy).xyz;
|
||||
vec3 c12 = tex2D(s_p, tc +dy).xyz;
|
||||
vec3 c22 = tex2D(s_p, tc +dx +dy).xyz;
|
||||
vec3 c32 = tex2D(s_p, tc+2.0*dx +dy).xyz;
|
||||
vec3 c03 = tex2D(s_p, tc -dx+2.0*dy).xyz;
|
||||
vec3 c13 = tex2D(s_p, tc +2.0*dy).xyz;
|
||||
vec3 c23 = tex2D(s_p, tc +dx+2.0*dy).xyz;
|
||||
vec3 c33 = tex2D(s_p, tc+2.0*dx+2.0*dy).xyz;
|
||||
|
||||
color = tex2D(s_p, texCoord).xyz;
|
||||
|
||||
// Get min/max samples
|
||||
vec3 min_sample = min4(c11, c21, c12, c22);
|
||||
vec3 max_sample = max4(c11, c21, c12, c22);
|
||||
/*
|
||||
color = mat4x3(c00, c10, c20, c30) * weights[0];
|
||||
color+= mat4x3(c01, c11, c21, c31) * weights[1];
|
||||
color+= mat4x3(c02, c12, c22, c32) * weights[2];
|
||||
color+= mat4x3(c03, c13, c23, c33) * weights[3];
|
||||
mat4 wgts = mat4(weights[0], weights[1], weights[2], weights[3]);
|
||||
vec4 wsum = wgts * vec4(1.0,1.0,1.0,1.0);
|
||||
color = color/(dot(wsum, vec4(1.0,1.0,1.0,1.0)));
|
||||
*/
|
||||
|
||||
|
||||
color = vec3(dot(weights[0], vec4(c00.x, c10.x, c20.x, c30.x)), dot(weights[0], vec4(c00.y, c10.y, c20.y, c30.y)), dot(weights[0], vec4(c00.z, c10.z, c20.z, c30.z)));
|
||||
color+= vec3(dot(weights[1], vec4(c01.x, c11.x, c21.x, c31.x)), dot(weights[1], vec4(c01.y, c11.y, c21.y, c31.y)), dot(weights[1], vec4(c01.z, c11.z, c21.z, c31.z)));
|
||||
color+= vec3(dot(weights[2], vec4(c02.x, c12.x, c22.x, c32.x)), dot(weights[2], vec4(c02.y, c12.y, c22.y, c32.y)), dot(weights[2], vec4(c02.z, c12.z, c22.z, c32.z)));
|
||||
color+= vec3(dot(weights[3], vec4(c03.x, c13.x, c23.x, c33.x)), dot(weights[3], vec4(c03.y, c13.y, c23.y, c33.y)), dot(weights[3], vec4(c03.z, c13.z, c23.z, c33.z)));
|
||||
color = color/(dot(weights[0], vec4(1,1,1,1)) + dot(weights[1], vec4(1,1,1,1)) + dot(weights[2], vec4(1,1,1,1)) + dot(weights[3], vec4(1,1,1,1)));
|
||||
|
||||
// Anti-ringing
|
||||
vec3 aux = color;
|
||||
color = clamp(color, min_sample, max_sample);
|
||||
color = mix(aux, color, JINC2_AR_STRENGTH);
|
||||
|
||||
// final sum and weight normalization
|
||||
FragColor.xyz = color;
|
||||
}
|
||||
#endif
|
||||
73
Shaders/nearest-neighbor.glsl
Normal file
73
Shaders/nearest-neighbor.glsl
Normal file
@@ -0,0 +1,73 @@
|
||||
#if defined(VERTEX)
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
#define COMPAT_VARYING out
|
||||
#define COMPAT_ATTRIBUTE in
|
||||
#define COMPAT_TEXTURE texture
|
||||
#else
|
||||
#define COMPAT_VARYING varying
|
||||
#define COMPAT_ATTRIBUTE attribute
|
||||
#define COMPAT_TEXTURE texture2D
|
||||
#endif
|
||||
|
||||
#ifdef GL_ES
|
||||
#define COMPAT_PRECISION mediump
|
||||
#else
|
||||
#define COMPAT_PRECISION
|
||||
#endif
|
||||
|
||||
COMPAT_ATTRIBUTE vec4 VertexCoord;
|
||||
COMPAT_ATTRIBUTE vec4 COLOR;
|
||||
COMPAT_ATTRIBUTE vec4 TexCoord;
|
||||
COMPAT_VARYING vec4 COL0;
|
||||
COMPAT_VARYING vec4 TEX0;
|
||||
|
||||
uniform mat4 MVPMatrix;
|
||||
uniform COMPAT_PRECISION int FrameDirection;
|
||||
uniform COMPAT_PRECISION int FrameCount;
|
||||
uniform COMPAT_PRECISION vec2 OutputSize;
|
||||
uniform COMPAT_PRECISION vec2 TextureSize;
|
||||
uniform COMPAT_PRECISION vec2 InputSize;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = VertexCoord.x * MVPMatrix[0] + VertexCoord.y * MVPMatrix[1] + VertexCoord.z * MVPMatrix[2] + VertexCoord.w * MVPMatrix[3];
|
||||
TEX0.xy = TexCoord.xy;
|
||||
}
|
||||
|
||||
#elif defined(FRAGMENT)
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
#define COMPAT_VARYING in
|
||||
#define COMPAT_TEXTURE texture
|
||||
out vec4 FragColor;
|
||||
#else
|
||||
#define COMPAT_VARYING varying
|
||||
#define FragColor gl_FragColor
|
||||
#define COMPAT_TEXTURE texture2D
|
||||
#endif
|
||||
|
||||
#ifdef GL_ES
|
||||
#ifdef GL_FRAGMENT_PRECISION_HIGH
|
||||
precision highp float;
|
||||
#else
|
||||
precision mediump float;
|
||||
#endif
|
||||
#define COMPAT_PRECISION mediump
|
||||
#else
|
||||
#define COMPAT_PRECISION
|
||||
#endif
|
||||
|
||||
uniform COMPAT_PRECISION int FrameDirection;
|
||||
uniform COMPAT_PRECISION int FrameCount;
|
||||
uniform COMPAT_PRECISION vec2 OutputSize;
|
||||
uniform COMPAT_PRECISION vec2 TextureSize;
|
||||
uniform COMPAT_PRECISION vec2 InputSize;
|
||||
uniform sampler2D Texture;
|
||||
COMPAT_VARYING vec4 TEX0;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = COMPAT_TEXTURE(Texture, TEX0.xy);
|
||||
}
|
||||
#endif
|
||||
10
Shaders/readme.txt
Normal file
10
Shaders/readme.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
This is a package of pixel shaders intended for old school emulators.
|
||||
Copyrights are held by the respective authors.
|
||||
|
||||
https://github.com/libretro/glsl-shaders
|
||||
|
||||
|
||||
Note: Filename must end with "bilinear.glsl" to enable bilinear hardware filtering (GL_LINEAR)
|
||||
|
||||
|
||||
Extract shader-package.zip to unlock 100+ additional shaders
|
||||
106
Shaders/scanlines/scanline.glsl
Normal file
106
Shaders/scanlines/scanline.glsl
Normal file
@@ -0,0 +1,106 @@
|
||||
// Parameter lines go here:
|
||||
#pragma parameter SCANLINE_BASE_BRIGHTNESS "Scanline Base Brightness" 0.95 0.0 1.0 0.01
|
||||
#pragma parameter SCANLINE_SINE_COMP_A "Scanline Sine Comp A" 0.0 0.0 0.10 0.01
|
||||
#pragma parameter SCANLINE_SINE_COMP_B "Scanline Sine Comp B" 0.15 0.0 1.0 0.05
|
||||
|
||||
#define pi 3.141592654
|
||||
|
||||
#if defined(VERTEX)
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
#define COMPAT_VARYING out
|
||||
#define COMPAT_ATTRIBUTE in
|
||||
#define COMPAT_TEXTURE texture
|
||||
#else
|
||||
#define COMPAT_VARYING varying
|
||||
#define COMPAT_ATTRIBUTE attribute
|
||||
#define COMPAT_TEXTURE texture2D
|
||||
#endif
|
||||
|
||||
#ifdef GL_ES
|
||||
#define COMPAT_PRECISION mediump
|
||||
#else
|
||||
#define COMPAT_PRECISION
|
||||
#endif
|
||||
|
||||
COMPAT_ATTRIBUTE vec4 VertexCoord;
|
||||
COMPAT_ATTRIBUTE vec4 COLOR;
|
||||
COMPAT_ATTRIBUTE vec4 TexCoord;
|
||||
COMPAT_VARYING vec4 COL0;
|
||||
COMPAT_VARYING vec4 TEX0;
|
||||
COMPAT_VARYING vec2 omega;
|
||||
|
||||
vec4 _oPosition1;
|
||||
uniform mat4 MVPMatrix;
|
||||
uniform COMPAT_PRECISION int FrameDirection;
|
||||
uniform COMPAT_PRECISION int FrameCount;
|
||||
uniform COMPAT_PRECISION vec2 OutputSize;
|
||||
uniform COMPAT_PRECISION vec2 TextureSize;
|
||||
uniform COMPAT_PRECISION vec2 InputSize;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = MVPMatrix * VertexCoord;
|
||||
COL0 = COLOR;
|
||||
TEX0.xy = TexCoord.xy;
|
||||
omega = vec2(pi * OutputSize.x, 2.0 * pi * TextureSize.y);
|
||||
}
|
||||
|
||||
#elif defined(FRAGMENT)
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
#define COMPAT_VARYING in
|
||||
#define COMPAT_TEXTURE texture
|
||||
out vec4 FragColor;
|
||||
#else
|
||||
#define COMPAT_VARYING varying
|
||||
#define FragColor gl_FragColor
|
||||
#define COMPAT_TEXTURE texture2D
|
||||
#endif
|
||||
|
||||
#ifdef GL_ES
|
||||
#ifdef GL_FRAGMENT_PRECISION_HIGH
|
||||
precision highp float;
|
||||
#else
|
||||
precision mediump float;
|
||||
#endif
|
||||
#define COMPAT_PRECISION mediump
|
||||
#else
|
||||
#define COMPAT_PRECISION
|
||||
#endif
|
||||
|
||||
uniform COMPAT_PRECISION int FrameDirection;
|
||||
uniform COMPAT_PRECISION int FrameCount;
|
||||
uniform COMPAT_PRECISION vec2 OutputSize;
|
||||
uniform COMPAT_PRECISION vec2 TextureSize;
|
||||
uniform COMPAT_PRECISION vec2 InputSize;
|
||||
uniform sampler2D Texture;
|
||||
COMPAT_VARYING vec4 TEX0;
|
||||
COMPAT_VARYING vec2 omega;
|
||||
|
||||
// compatibility #defines
|
||||
#define Source Texture
|
||||
#define vTexCoord TEX0.xy
|
||||
|
||||
#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
|
||||
#define OutputSize vec4(OutputSize, 1.0 / OutputSize)
|
||||
|
||||
#ifdef PARAMETER_UNIFORM
|
||||
// All parameter floats need to have COMPAT_PRECISION in front of them
|
||||
uniform COMPAT_PRECISION float SCANLINE_BASE_BRIGHTNESS;
|
||||
uniform COMPAT_PRECISION float SCANLINE_SINE_COMP_A;
|
||||
uniform COMPAT_PRECISION float SCANLINE_SINE_COMP_B;
|
||||
#else
|
||||
#define SCANLINE_BASE_BRIGHTNESS 0.95
|
||||
#define SCANLINE_SINE_COMP_A 0.0
|
||||
#define SCANLINE_SINE_COMP_B 0.15
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 sine_comp = vec2(SCANLINE_SINE_COMP_A, SCANLINE_SINE_COMP_B);
|
||||
vec3 res = COMPAT_TEXTURE(Source, vTexCoord).xyz;
|
||||
vec3 scanline = res * (SCANLINE_BASE_BRIGHTNESS + dot(sine_comp * sin(vTexCoord * omega), vec2(1.0, 1.0)));
|
||||
FragColor = vec4(scanline.x, scanline.y, scanline.z, 1.0);
|
||||
}
|
||||
#endif
|
||||
BIN
Shaders/shader-package.zip
Normal file
BIN
Shaders/shader-package.zip
Normal file
Binary file not shown.
178
Shaders/sharpen/rca-sharpen.glsl
Normal file
178
Shaders/sharpen/rca-sharpen.glsl
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
FSR - [RCAS] ROBUST CONTRAST ADAPTIVE SHARPENING
|
||||
Ported from https://www.shadertoy.com/view/stXSWB, MIT license
|
||||
*/
|
||||
|
||||
#pragma parameter FSR_SHARPENING "FSR RCAS Sharpening Amount (Lower = Sharper)" 0.6 0.0 2.0 0.1
|
||||
|
||||
#if defined(VERTEX)
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
#define COMPAT_VARYING out
|
||||
#define COMPAT_ATTRIBUTE in
|
||||
#define COMPAT_TEXTURE texture
|
||||
#else
|
||||
#define COMPAT_VARYING varying
|
||||
#define COMPAT_ATTRIBUTE attribute
|
||||
#define COMPAT_TEXTURE texture2D
|
||||
#endif
|
||||
|
||||
#ifdef GL_ES
|
||||
#define COMPAT_PRECISION mediump
|
||||
#else
|
||||
#define COMPAT_PRECISION
|
||||
#endif
|
||||
|
||||
COMPAT_ATTRIBUTE vec4 VertexCoord;
|
||||
COMPAT_ATTRIBUTE vec4 COLOR;
|
||||
COMPAT_ATTRIBUTE vec4 TexCoord;
|
||||
COMPAT_VARYING vec4 COL0;
|
||||
COMPAT_VARYING vec4 TEX0;
|
||||
|
||||
uniform mat4 MVPMatrix;
|
||||
uniform COMPAT_PRECISION int FrameDirection;
|
||||
uniform COMPAT_PRECISION int FrameCount;
|
||||
uniform COMPAT_PRECISION vec2 OutputSize;
|
||||
uniform COMPAT_PRECISION vec2 TextureSize;
|
||||
uniform COMPAT_PRECISION vec2 InputSize;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = MVPMatrix * VertexCoord;
|
||||
COL0 = COLOR;
|
||||
TEX0.xy = TexCoord.xy;
|
||||
}
|
||||
|
||||
#elif defined(FRAGMENT)
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
#define COMPAT_VARYING in
|
||||
#define COMPAT_TEXTURE texture
|
||||
out vec4 FragColor;
|
||||
#else
|
||||
#define COMPAT_VARYING varying
|
||||
#define FragColor gl_FragColor
|
||||
#define COMPAT_TEXTURE texture2D
|
||||
#endif
|
||||
|
||||
#ifdef GL_ES
|
||||
#ifdef GL_FRAGMENT_PRECISION_HIGH
|
||||
precision highp float;
|
||||
#else
|
||||
precision mediump float;
|
||||
#endif
|
||||
#define COMPAT_PRECISION mediump
|
||||
#else
|
||||
#define COMPAT_PRECISION
|
||||
#endif
|
||||
|
||||
uniform COMPAT_PRECISION int FrameDirection;
|
||||
uniform COMPAT_PRECISION int FrameCount;
|
||||
uniform COMPAT_PRECISION vec2 OutputSize;
|
||||
uniform COMPAT_PRECISION vec2 TextureSize;
|
||||
uniform COMPAT_PRECISION vec2 InputSize;
|
||||
uniform sampler2D Texture;
|
||||
COMPAT_VARYING vec4 TEX0;
|
||||
|
||||
// compatibility #defines
|
||||
#define Source Texture
|
||||
#define vTexCoord TEX0.xy
|
||||
|
||||
#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
|
||||
#define outsize vec4(OutputSize, 1.0 / OutputSize)
|
||||
|
||||
#ifdef PARAMETER_UNIFORM
|
||||
uniform COMPAT_PRECISION float FSR_SHARPENING;
|
||||
#else
|
||||
#define FSR_SHARPENING 0.6
|
||||
#endif
|
||||
|
||||
#define FSR_RCAS_LIMIT (0.25-(1.0/16.0))
|
||||
//#define FSR_RCAS_DENOISE
|
||||
|
||||
// Input callback prototypes that need to be implemented by calling shader
|
||||
vec4 FsrRcasLoadF(vec2 p);
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
void FsrRcasCon(
|
||||
out float con,
|
||||
// The scale is {0.0 := maximum, to N>0, where N is the number of stops (halving) of the reduction of sharpness}.
|
||||
float sharpness
|
||||
){
|
||||
// Transform from stops to linear value.
|
||||
con = exp2(-sharpness);
|
||||
}
|
||||
|
||||
vec3 FsrRcasF(
|
||||
vec2 ip, // Integer pixel position in output.
|
||||
float con
|
||||
)
|
||||
{
|
||||
// Constant generated by RcasSetup().
|
||||
// Algorithm uses minimal 3x3 pixel neighborhood.
|
||||
// b
|
||||
// d e f
|
||||
// h
|
||||
vec2 sp = vec2(ip);
|
||||
vec3 b = FsrRcasLoadF(sp + vec2( 0,-1)).rgb;
|
||||
vec3 d = FsrRcasLoadF(sp + vec2(-1, 0)).rgb;
|
||||
vec3 e = FsrRcasLoadF(sp).rgb;
|
||||
vec3 f = FsrRcasLoadF(sp+vec2( 1, 0)).rgb;
|
||||
vec3 h = FsrRcasLoadF(sp+vec2( 0, 1)).rgb;
|
||||
// Luma times 2.
|
||||
float bL = b.g + .5 * (b.b + b.r);
|
||||
float dL = d.g + .5 * (d.b + d.r);
|
||||
float eL = e.g + .5 * (e.b + e.r);
|
||||
float fL = f.g + .5 * (f.b + f.r);
|
||||
float hL = h.g + .5 * (h.b + h.r);
|
||||
// Noise detection.
|
||||
float nz = .25 * (bL + dL + fL + hL) - eL;
|
||||
nz=clamp(
|
||||
abs(nz)
|
||||
/(
|
||||
max(max(bL,dL),max(eL,max(fL,hL)))
|
||||
-min(min(bL,dL),min(eL,min(fL,hL)))
|
||||
),
|
||||
0., 1.
|
||||
);
|
||||
nz=1.-.5*nz;
|
||||
// Min and max of ring.
|
||||
vec3 mn4 = min(b, min(f, h));
|
||||
vec3 mx4 = max(b, max(f, h));
|
||||
// Immediate constants for peak range.
|
||||
vec2 peakC = vec2(1., -4.);
|
||||
// Limiters, these need to be high precision RCPs.
|
||||
vec3 hitMin = mn4 / (4. * mx4);
|
||||
vec3 hitMax = (peakC.x - mx4) / (4.* mn4 + peakC.y);
|
||||
vec3 lobeRGB = max(-hitMin, hitMax);
|
||||
float lobe = max(
|
||||
-FSR_RCAS_LIMIT,
|
||||
min(max(lobeRGB.r, max(lobeRGB.g, lobeRGB.b)), 0.)
|
||||
)*con;
|
||||
// Apply noise removal.
|
||||
#ifdef FSR_RCAS_DENOISE
|
||||
lobe *= nz;
|
||||
#endif
|
||||
// Resolve, which needs the medium precision rcp approximation to avoid visible tonality changes.
|
||||
return (lobe * (b + d + h + f) + e) / (4. * lobe + 1.);
|
||||
}
|
||||
|
||||
|
||||
vec4 FsrRcasLoadF(vec2 p) {
|
||||
return COMPAT_TEXTURE(Source,p/OutputSize.xy);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 fragCoord = vTexCoord.xy * OutputSize.xy;
|
||||
|
||||
// Set up constants
|
||||
float con;
|
||||
FsrRcasCon(con, FSR_SHARPENING);
|
||||
|
||||
// Perform RCAS pass
|
||||
vec3 col = FsrRcasF(fragCoord, con);
|
||||
|
||||
FragColor = vec4(col,1);
|
||||
}
|
||||
|
||||
#endif
|
||||
300
Shaders/xbr/xbr-lv2-noblend.glsl
Normal file
300
Shaders/xbr/xbr-lv2-noblend.glsl
Normal file
@@ -0,0 +1,300 @@
|
||||
#version 130
|
||||
|
||||
/*
|
||||
Hyllian's xBR-lv2-noblend Shader
|
||||
|
||||
Copyright (C) 2011-2016 Hyllian - sergiogdb@gmail.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
Incorporates some of the ideas from SABR shader. Thanks to Joshua Street.
|
||||
*/
|
||||
|
||||
#pragma parameter XBR_EQ_THRESHOLD "Eq Threshold" 0.6 0.0 2.0 0.1
|
||||
#pragma parameter XBR_LV2_COEFFICIENT "Lv2 Coefficient" 2.0 1.0 3.0 0.1
|
||||
|
||||
#define mul(a,b) (b*a)
|
||||
|
||||
// Uncomment just one of the three params below to choose the corner detection
|
||||
#define CORNER_A
|
||||
//#define CORNER_B
|
||||
//#define CORNER_C
|
||||
//#define CORNER_D
|
||||
|
||||
#define lv2_cf XBR_LV2_COEFFICIENT
|
||||
|
||||
#define texCoord TEX0
|
||||
#define t1 TEX1
|
||||
#define t2 TEX2
|
||||
#define t3 TEX3
|
||||
#define t4 TEX4
|
||||
#define t5 TEX5
|
||||
#define t6 TEX6
|
||||
#define t7 TEX7
|
||||
|
||||
#if defined(VERTEX)
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
#define OUT out
|
||||
#define IN in
|
||||
#define tex2D texture
|
||||
#else
|
||||
#define OUT varying
|
||||
#define IN attribute
|
||||
#define tex2D texture2D
|
||||
#endif
|
||||
|
||||
#ifdef GL_ES
|
||||
#define PRECISION mediump
|
||||
#else
|
||||
#define PRECISION
|
||||
#endif
|
||||
|
||||
|
||||
IN vec4 VertexCoord;
|
||||
IN vec4 Color;
|
||||
IN vec2 TexCoord;
|
||||
|
||||
OUT vec4 color;
|
||||
OUT vec2 texCoord;
|
||||
OUT vec4 t1;
|
||||
OUT vec4 t2;
|
||||
OUT vec4 t3;
|
||||
OUT vec4 t4;
|
||||
OUT vec4 t5;
|
||||
OUT vec4 t6;
|
||||
OUT vec4 t7;
|
||||
|
||||
uniform mat4 MVPMatrix;
|
||||
uniform PRECISION int FrameDirection;
|
||||
uniform PRECISION int FrameCount;
|
||||
uniform PRECISION vec2 OutputSize;
|
||||
uniform PRECISION vec2 TextureSize;
|
||||
uniform PRECISION vec2 InputSize;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = MVPMatrix * VertexCoord;
|
||||
color = Color;
|
||||
|
||||
float dx = (1.0/TextureSize.x);
|
||||
float dy = (1.0/TextureSize.y);
|
||||
|
||||
texCoord = TexCoord;
|
||||
texCoord.x *= 1.00000001;
|
||||
t1 = TexCoord.xxxy + vec4( -dx, 0, dx,-2.0*dy); // A1 B1 C1
|
||||
t2 = TexCoord.xxxy + vec4( -dx, 0, dx, -dy); // A B C
|
||||
t3 = TexCoord.xxxy + vec4( -dx, 0, dx, 0); // D E F
|
||||
t4 = TexCoord.xxxy + vec4( -dx, 0, dx, dy); // G H I
|
||||
t5 = TexCoord.xxxy + vec4( -dx, 0, dx, 2.0*dy); // G5 H5 I5
|
||||
t6 = TexCoord.xyyy + vec4(-2.0*dx,-dy, 0, dy); // A0 D0 G0
|
||||
t7 = TexCoord.xyyy + vec4( 2.0*dx,-dy, 0, dy); // C4 F4 I4
|
||||
}
|
||||
|
||||
|
||||
#elif defined(FRAGMENT)
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
#define IN in
|
||||
#define tex2D texture
|
||||
out vec4 FragColor;
|
||||
#else
|
||||
#define IN varying
|
||||
#define FragColor gl_FragColor
|
||||
#define tex2D texture2D
|
||||
#endif
|
||||
|
||||
#ifdef GL_ES
|
||||
#ifdef GL_FRAGMENT_PRECISION_HIGH
|
||||
precision highp float;
|
||||
#else
|
||||
precision mediump float;
|
||||
#endif
|
||||
#define PRECISION mediump
|
||||
#else
|
||||
#define PRECISION
|
||||
#endif
|
||||
|
||||
uniform PRECISION int FrameDirection;
|
||||
uniform PRECISION int FrameCount;
|
||||
uniform PRECISION vec2 OutputSize;
|
||||
uniform PRECISION vec2 TextureSize;
|
||||
uniform PRECISION vec2 InputSize;
|
||||
uniform sampler2D decal;
|
||||
IN vec2 texCoord;
|
||||
IN vec4 t1;
|
||||
IN vec4 t2;
|
||||
IN vec4 t3;
|
||||
IN vec4 t4;
|
||||
IN vec4 t5;
|
||||
IN vec4 t6;
|
||||
IN vec4 t7;
|
||||
|
||||
#ifdef PARAMETER_UNIFORM
|
||||
uniform PRECISION float XBR_EQ_THRESHOLD;
|
||||
uniform PRECISION float XBR_LV2_COEFFICIENT;
|
||||
#else
|
||||
#define XBR_EQ_THRESHOLD 0.6
|
||||
#define XBR_LV2_COEFFICIENT 2.0
|
||||
#endif
|
||||
// END PARAMETERS //
|
||||
|
||||
const vec3 Y = vec3(0.2126, 0.7152, 0.0722);
|
||||
|
||||
// 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));
|
||||
}
|
||||
|
||||
vec4 weighted_distance(vec4 a, vec4 b, vec4 c, vec4 d, vec4 e, vec4 f, vec4 g, vec4 h, vec4 i, vec4 j, vec4 k, vec4 l)
|
||||
{
|
||||
return (df(a,b) + df(a,c) + df(d,e) + df(d,f) + df(i,j) + df(k,l) + 2.0*df(g,h));
|
||||
}
|
||||
|
||||
float c_df(vec3 c1, vec3 c2)
|
||||
{
|
||||
vec3 df = abs(c1 - c2);
|
||||
return df.r + df.g + df.b;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 edri, edr, edr_l, edr_u; // px = pixel, edr = edge detection rule
|
||||
vec4 irlv1, irlv2l, irlv2u, block_3d;
|
||||
bvec4 nc, px;
|
||||
vec4 fx, fx_l, fx_u; // inequations of straight lines.
|
||||
|
||||
vec2 fp = fract(texCoord*TextureSize);
|
||||
|
||||
vec3 A1 = tex2D(decal, t1.xw ).xyz;
|
||||
vec3 B1 = tex2D(decal, t1.yw ).xyz;
|
||||
vec3 C1 = tex2D(decal, t1.zw ).xyz;
|
||||
vec3 A = tex2D(decal, t2.xw ).xyz;
|
||||
vec3 B = tex2D(decal, t2.yw ).xyz;
|
||||
vec3 C = tex2D(decal, t2.zw ).xyz;
|
||||
vec3 D = tex2D(decal, t3.xw ).xyz;
|
||||
vec3 E = tex2D(decal, t3.yw ).xyz;
|
||||
vec3 F = tex2D(decal, t3.zw ).xyz;
|
||||
vec3 G = tex2D(decal, t4.xw ).xyz;
|
||||
vec3 H = tex2D(decal, t4.yw ).xyz;
|
||||
vec3 I = tex2D(decal, t4.zw ).xyz;
|
||||
vec3 G5 = tex2D(decal, t5.xw ).xyz;
|
||||
vec3 H5 = tex2D(decal, t5.yw ).xyz;
|
||||
vec3 I5 = tex2D(decal, t5.zw ).xyz;
|
||||
vec3 A0 = tex2D(decal, t6.xy ).xyz;
|
||||
vec3 D0 = tex2D(decal, t6.xz ).xyz;
|
||||
vec3 G0 = tex2D(decal, t6.xw ).xyz;
|
||||
vec3 C4 = tex2D(decal, t7.xy ).xyz;
|
||||
vec3 F4 = tex2D(decal, t7.xz ).xyz;
|
||||
vec3 I4 = tex2D(decal, t7.xw ).xyz;
|
||||
|
||||
vec4 b = mul( mat4x3(B, D, H, F), Y );
|
||||
vec4 c = mul( mat4x3(C, A, G, I), Y );
|
||||
vec4 e = mul( mat4x3(E, E, E, E), Y );
|
||||
vec4 d = b.yzwx;
|
||||
vec4 f = b.wxyz;
|
||||
vec4 g = c.zwxy;
|
||||
vec4 h = b.zwxy;
|
||||
vec4 i = c.wxyz;
|
||||
|
||||
vec4 i4 = mul( mat4x3(I4, C1, A0, G5), Y );
|
||||
vec4 i5 = mul( mat4x3(I5, C4, A1, G0), Y );
|
||||
vec4 h5 = mul( mat4x3(H5, F4, B1, D0), Y );
|
||||
vec4 f4 = h5.yzwx;
|
||||
|
||||
vec4 Ao = vec4( 1.0, -1.0, -1.0, 1.0 );
|
||||
vec4 Bo = vec4( 1.0, 1.0, -1.0,-1.0 );
|
||||
vec4 Co = vec4( 1.5, 0.5, -0.5, 0.5 );
|
||||
vec4 Ax = vec4( 1.0, -1.0, -1.0, 1.0 );
|
||||
vec4 Bx = vec4( 0.5, 2.0, -0.5,-2.0 );
|
||||
vec4 Cx = vec4( 1.0, 1.0, -0.5, 0.0 );
|
||||
vec4 Ay = vec4( 1.0, -1.0, -1.0, 1.0 );
|
||||
vec4 By = vec4( 2.0, 0.5, -2.0,-0.5 );
|
||||
vec4 Cy = vec4( 2.0, 0.0, -1.0, 0.5 );
|
||||
|
||||
// These inequations define the line below which interpolation occurs.
|
||||
fx = vec4(greaterThan(Ao*fp.y+Bo*fp.x, Co));
|
||||
fx_l = vec4(greaterThan(Ax*fp.y+Bx*fp.x, Cx));
|
||||
fx_u = vec4(greaterThan(Ay*fp.y+By*fp.x, Cy));
|
||||
|
||||
#ifdef CORNER_A
|
||||
irlv1 = diff(e,f) * diff(e,h);
|
||||
#endif
|
||||
#ifdef CORNER_B
|
||||
irlv1 = (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 = (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 = (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 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) * irlv1;
|
||||
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;
|
||||
|
||||
nc = bvec4( edr * ( fx + edr_l * (fx_l)) + edr_u * fx_u);
|
||||
|
||||
px = lessThanEqual(df(e, f), df(e, h));
|
||||
|
||||
vec3 res1 = nc.x ? px.x ? F : H : nc.y ? px.y ? B : F : nc.z ? px.z ? D : B : E;
|
||||
vec3 res2 = nc.w ? px.w ? H : D : nc.z ? px.z ? D : B : nc.y ? px.y ? B : F : E;
|
||||
|
||||
vec2 df12 = abs( mul( mat2x3(res1, res2), Y ) - e.xy);
|
||||
|
||||
vec3 res = mix(res1, res2, step(df12.x, df12.y));
|
||||
|
||||
FragColor.xyz = res;
|
||||
}
|
||||
#endif
|
||||
337
Shaders/xbrz/xbrz-freescale-multipass.glsl
Normal file
337
Shaders/xbrz/xbrz-freescale-multipass.glsl
Normal file
@@ -0,0 +1,337 @@
|
||||
/*
|
||||
Hyllian's xBR-vertex code and texel mapping
|
||||
|
||||
Copyright (C) 2011/2016 Hyllian - sergiogdb@gmail.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
// This shader also uses code and/or concepts from xBRZ as it appears
|
||||
// in the Desmume source code. The license for which is as follows:
|
||||
|
||||
// ****************************************************************************
|
||||
// * This file is part of the HqMAME project. It is distributed under *
|
||||
// * GNU General Public License: http://www.gnu.org/licenses/gpl-3.0 *
|
||||
// * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved *
|
||||
// * *
|
||||
// * Additionally and as a special exception, the author gives permission *
|
||||
// * to link the code of this program with the MAME library (or with modified *
|
||||
// * versions of MAME that use the same license as MAME), and distribute *
|
||||
// * linked combinations including the two. You must obey the GNU General *
|
||||
// * Public License in all respects for all of the code used other than MAME. *
|
||||
// * If you modify this file, you may extend this exception to your version *
|
||||
// * of the file, but you are not obligated to do so. If you do not wish to *
|
||||
// * do so, delete this exception statement from your version. *
|
||||
// ****************************************************************************
|
||||
|
||||
#if defined(VERTEX)
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
#define COMPAT_VARYING out
|
||||
#define COMPAT_ATTRIBUTE in
|
||||
#define COMPAT_TEXTURE texture
|
||||
#else
|
||||
#define COMPAT_VARYING varying
|
||||
#define COMPAT_ATTRIBUTE attribute
|
||||
#define COMPAT_TEXTURE texture2D
|
||||
#endif
|
||||
|
||||
#ifdef GL_ES
|
||||
#define COMPAT_PRECISION mediump
|
||||
#else
|
||||
#define COMPAT_PRECISION
|
||||
#endif
|
||||
|
||||
COMPAT_ATTRIBUTE vec4 VertexCoord;
|
||||
COMPAT_ATTRIBUTE vec4 COLOR;
|
||||
COMPAT_ATTRIBUTE vec4 TexCoord;
|
||||
COMPAT_VARYING vec4 COL0;
|
||||
COMPAT_VARYING vec4 TEX0;
|
||||
|
||||
vec4 _oPosition1;
|
||||
uniform mat4 MVPMatrix;
|
||||
uniform COMPAT_PRECISION int FrameDirection;
|
||||
uniform COMPAT_PRECISION int FrameCount;
|
||||
uniform COMPAT_PRECISION vec2 OutputSize;
|
||||
uniform COMPAT_PRECISION vec2 TextureSize;
|
||||
uniform COMPAT_PRECISION vec2 InputSize;
|
||||
|
||||
// compatibility #defines
|
||||
#define vTexCoord TEX0.xy
|
||||
#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
|
||||
#define OutSize vec4(OutputSize, 1.0 / OutputSize)
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = MVPMatrix * VertexCoord;
|
||||
TEX0.xy = TexCoord.xy * 1.0001;
|
||||
}
|
||||
|
||||
#elif defined(FRAGMENT)
|
||||
|
||||
#ifdef GL_ES
|
||||
#ifdef GL_FRAGMENT_PRECISION_HIGH
|
||||
precision highp float;
|
||||
#else
|
||||
precision mediump float;
|
||||
#endif
|
||||
#define COMPAT_PRECISION mediump
|
||||
#else
|
||||
#define COMPAT_PRECISION
|
||||
#endif
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
#define COMPAT_VARYING in
|
||||
#define COMPAT_TEXTURE texture
|
||||
out COMPAT_PRECISION vec4 FragColor;
|
||||
#else
|
||||
#define COMPAT_VARYING varying
|
||||
#define FragColor gl_FragColor
|
||||
#define COMPAT_TEXTURE texture2D
|
||||
#endif
|
||||
|
||||
uniform COMPAT_PRECISION int FrameDirection;
|
||||
uniform COMPAT_PRECISION int FrameCount;
|
||||
uniform COMPAT_PRECISION vec2 OutputSize;
|
||||
uniform COMPAT_PRECISION vec2 TextureSize;
|
||||
uniform COMPAT_PRECISION vec2 InputSize;
|
||||
uniform sampler2D Texture;
|
||||
COMPAT_VARYING vec4 TEX0;
|
||||
// in variables go here as COMPAT_VARYING whatever
|
||||
|
||||
// compatibility #defines
|
||||
#define Source Texture
|
||||
#define vTexCoord TEX0.xy
|
||||
|
||||
#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
|
||||
#define OutSize vec4(OutputSize, 1.0 / OutputSize)
|
||||
|
||||
#define BLEND_NONE 0
|
||||
#define BLEND_NORMAL 1
|
||||
#define BLEND_DOMINANT 2
|
||||
#define LUMINANCE_WEIGHT 1.0
|
||||
#define EQUAL_COLOR_TOLERANCE 30.0/255.0
|
||||
#define STEEP_DIRECTION_THRESHOLD 2.2
|
||||
#define DOMINANT_DIRECTION_THRESHOLD 3.6
|
||||
|
||||
float DistYCbCr(vec3 pixA, vec3 pixB)
|
||||
{
|
||||
const vec3 w = vec3(0.2627, 0.6780, 0.0593);
|
||||
const float scaleB = 0.5 / (1.0 - w.b);
|
||||
const float scaleR = 0.5 / (1.0 - w.r);
|
||||
vec3 diff = pixA - pixB;
|
||||
float Y = dot(diff.rgb, w);
|
||||
float Cb = scaleB * (diff.b - Y);
|
||||
float Cr = scaleR * (diff.r - Y);
|
||||
|
||||
return sqrt(((LUMINANCE_WEIGHT * Y) * (LUMINANCE_WEIGHT * Y)) + (Cb * Cb) + (Cr * Cr));
|
||||
}
|
||||
|
||||
bool IsPixEqual(const vec3 pixA, const vec3 pixB)
|
||||
{
|
||||
return (DistYCbCr(pixA, pixB) < EQUAL_COLOR_TOLERANCE);
|
||||
}
|
||||
|
||||
float get_left_ratio(vec2 center, vec2 origin, vec2 direction, vec2 scale)
|
||||
{
|
||||
vec2 P0 = center - origin;
|
||||
vec2 proj = direction * (dot(P0, direction) / dot(direction, direction));
|
||||
vec2 distv = P0 - proj;
|
||||
vec2 orth = vec2(-direction.y, direction.x);
|
||||
float side = sign(dot(P0, orth));
|
||||
float v = side * length(distv * scale);
|
||||
|
||||
// return step(0, v);
|
||||
return smoothstep(-sqrt(2.0)/2.0, sqrt(2.0)/2.0, v);
|
||||
}
|
||||
|
||||
#define eq(a,b) (a == b)
|
||||
#define neq(a,b) (a != b)
|
||||
|
||||
#define P(x,y) COMPAT_TEXTURE(Source, coord + SourceSize.zw * vec2(x, y)).rgb
|
||||
|
||||
void main()
|
||||
{
|
||||
//---------------------------------------
|
||||
// Input Pixel Mapping: -|x|x|x|-
|
||||
// x|A|B|C|x
|
||||
// x|D|E|F|x
|
||||
// x|G|H|I|x
|
||||
// -|x|x|x|-
|
||||
|
||||
vec2 pos = fract(vTexCoord * SourceSize.xy) - vec2(0.5, 0.5);
|
||||
vec2 coord = vTexCoord - pos * SourceSize.zw;
|
||||
|
||||
vec3 A = P(-1.,-1.);
|
||||
vec3 B = P( 0.,-1.);
|
||||
vec3 C = P( 1.,-1.);
|
||||
vec3 D = P(-1., 0.);
|
||||
vec3 E = P( 0., 0.);
|
||||
vec3 F = P( 1., 0.);
|
||||
vec3 G = P(-1., 1.);
|
||||
vec3 H = P( 0., 1.);
|
||||
vec3 I = P( 1., 1.);
|
||||
|
||||
// blendResult Mapping: x|y|
|
||||
// w|z|
|
||||
ivec4 blendResult = ivec4(BLEND_NONE,BLEND_NONE,BLEND_NONE,BLEND_NONE);
|
||||
|
||||
// Preprocess corners
|
||||
// Pixel Tap Mapping: -|-|-|-|-
|
||||
// -|-|B|C|-
|
||||
// -|D|E|F|x
|
||||
// -|G|H|I|x
|
||||
// -|-|x|x|-
|
||||
if (!((eq(E,F) && eq(H,I)) || (eq(E,H) && eq(F,I))))
|
||||
{
|
||||
float dist_H_F = DistYCbCr(G, E) + DistYCbCr(E, C) + DistYCbCr(P(0.,2.), I) + DistYCbCr(I, P(2.,0.)) + (4.0 * DistYCbCr(H, F));
|
||||
float dist_E_I = DistYCbCr(D, H) + DistYCbCr(H, P(1.,2.)) + DistYCbCr(B, F) + DistYCbCr(F, P(2.,1.)) + (4.0 * DistYCbCr(E, I));
|
||||
bool dominantGradient = (DOMINANT_DIRECTION_THRESHOLD * dist_H_F) < dist_E_I;
|
||||
blendResult.z = ((dist_H_F < dist_E_I) && neq(E,F) && neq(E,H)) ? ((dominantGradient) ? BLEND_DOMINANT : BLEND_NORMAL) : BLEND_NONE;
|
||||
}
|
||||
|
||||
|
||||
// Pixel Tap Mapping: -|-|-|-|-
|
||||
// -|A|B|-|-
|
||||
// x|D|E|F|-
|
||||
// x|G|H|I|-
|
||||
// -|x|x|-|-
|
||||
if (!((eq(D,E) && eq(G,H)) || (eq(D,G) && eq(E,H))))
|
||||
{
|
||||
float dist_G_E = DistYCbCr(P(-2.,1.) , D) + DistYCbCr(D, B) + DistYCbCr(P(-1.,2.), H) + DistYCbCr(H, F) + (4.0 * DistYCbCr(G, E));
|
||||
float dist_D_H = DistYCbCr(P(-2.,0.) , G) + DistYCbCr(G, P(0.,2.)) + DistYCbCr(A, E) + DistYCbCr(E, I) + (4.0 * DistYCbCr(D, H));
|
||||
bool dominantGradient = (DOMINANT_DIRECTION_THRESHOLD * dist_D_H) < dist_G_E;
|
||||
blendResult.w = ((dist_G_E > dist_D_H) && neq(E,D) && neq(E,H)) ? ((dominantGradient) ? BLEND_DOMINANT : BLEND_NORMAL) : BLEND_NONE;
|
||||
}
|
||||
|
||||
// Pixel Tap Mapping: -|-|x|x|-
|
||||
// -|A|B|C|x
|
||||
// -|D|E|F|x
|
||||
// -|-|H|I|-
|
||||
// -|-|-|-|-
|
||||
if (!((eq(B,C) && eq(E,F)) || (eq(B,E) && eq(C,F))))
|
||||
{
|
||||
float dist_E_C = DistYCbCr(D, B) + DistYCbCr(B, P(1,-2)) + DistYCbCr(H, F) + DistYCbCr(F, P(2.,-1.)) + (4.0 * DistYCbCr(E, C));
|
||||
float dist_B_F = DistYCbCr(A, E) + DistYCbCr(E, I) + DistYCbCr(P(0.,-2.), C) + DistYCbCr(C, P(2.,0.)) + (4.0 * DistYCbCr(B, F));
|
||||
bool dominantGradient = (DOMINANT_DIRECTION_THRESHOLD * dist_B_F) < dist_E_C;
|
||||
blendResult.y = ((dist_E_C > dist_B_F) && neq(E,B) && neq(E,F)) ? ((dominantGradient) ? BLEND_DOMINANT : BLEND_NORMAL) : BLEND_NONE;
|
||||
}
|
||||
|
||||
// Pixel Tap Mapping: -|x|x|-|-
|
||||
// x|A|B|C|-
|
||||
// x|D|E|F|-
|
||||
// -|G|H|-|-
|
||||
// -|-|-|-|-
|
||||
if (!((eq(A,B) && eq(D,E)) || (eq(A,D) && eq(B,E))))
|
||||
{
|
||||
float dist_D_B = DistYCbCr(P(-2.,0.), A) + DistYCbCr(A, P(0.,-2.)) + DistYCbCr(G, E) + DistYCbCr(E, C) + (4.0 * DistYCbCr(D, B));
|
||||
float dist_A_E = DistYCbCr(P(-2.,-1.), D) + DistYCbCr(D, H) + DistYCbCr(P(-1.,-2.), B) + DistYCbCr(B, F) + (4.0 * DistYCbCr(A, E));
|
||||
bool dominantGradient = (DOMINANT_DIRECTION_THRESHOLD * dist_D_B) < dist_A_E;
|
||||
blendResult.x = ((dist_D_B < dist_A_E) && neq(E,D) && neq(E,B)) ? ((dominantGradient) ? BLEND_DOMINANT : BLEND_NORMAL) : BLEND_NONE;
|
||||
}
|
||||
|
||||
FragColor = vec4(blendResult);
|
||||
|
||||
// Pixel Tap Mapping: -|-|-|-|-
|
||||
// -|-|B|C|-
|
||||
// -|D|E|F|x
|
||||
// -|G|H|I|x
|
||||
// -|-|x|x|-
|
||||
if(blendResult.z == BLEND_DOMINANT || (blendResult.z == BLEND_NORMAL &&
|
||||
!((blendResult.y != BLEND_NONE && !IsPixEqual(E, G)) || (blendResult.w != BLEND_NONE && !IsPixEqual(E, C)) ||
|
||||
(IsPixEqual(G, H) && IsPixEqual(H, I) && IsPixEqual(I, F) && IsPixEqual(F, C) && !IsPixEqual(E, I)))))
|
||||
{
|
||||
FragColor.z += 4.0;
|
||||
|
||||
float dist_F_G = DistYCbCr(F, G);
|
||||
float dist_H_C = DistYCbCr(H, C);
|
||||
|
||||
if((STEEP_DIRECTION_THRESHOLD * dist_F_G <= dist_H_C) && neq(E,G) && neq(D,G))
|
||||
FragColor.z += 16.0;
|
||||
|
||||
if((STEEP_DIRECTION_THRESHOLD * dist_H_C <= dist_F_G) && neq(E,C) && neq(B,C))
|
||||
FragColor.z += 64.0;
|
||||
}
|
||||
|
||||
// Pixel Tap Mapping: -|-|-|-|-
|
||||
// -|A|B|-|-
|
||||
// x|D|E|F|-
|
||||
// x|G|H|I|-
|
||||
// -|x|x|-|-
|
||||
if(blendResult.w == BLEND_DOMINANT || (blendResult.w == BLEND_NORMAL &&
|
||||
!((blendResult.z != BLEND_NONE && !IsPixEqual(E, A)) || (blendResult.x != BLEND_NONE && !IsPixEqual(E, I)) ||
|
||||
(IsPixEqual(A, D) && IsPixEqual(D, G) && IsPixEqual(G, H) && IsPixEqual(H, I) && !IsPixEqual(E, G)))))
|
||||
{
|
||||
FragColor.w += 4.0;
|
||||
|
||||
float dist_H_A = DistYCbCr(H, A);
|
||||
float dist_D_I = DistYCbCr(D, I);
|
||||
|
||||
if((STEEP_DIRECTION_THRESHOLD * dist_H_A <= dist_D_I) && neq(E,A) && neq(B,A))
|
||||
FragColor.w += 16.0;
|
||||
|
||||
if((STEEP_DIRECTION_THRESHOLD * dist_D_I <= dist_H_A) && neq(E,I) && neq(F,I))
|
||||
FragColor.w += 64.0;
|
||||
}
|
||||
|
||||
// Pixel Tap Mapping: -|-|x|x|-
|
||||
// -|A|B|C|x
|
||||
// -|D|E|F|x
|
||||
// -|-|H|I|-
|
||||
// -|-|-|-|-
|
||||
if(blendResult.y == BLEND_DOMINANT || (blendResult.y == BLEND_NORMAL &&
|
||||
!((blendResult.x != BLEND_NONE && !IsPixEqual(E, I)) || (blendResult.z != BLEND_NONE && !IsPixEqual(E, A)) ||
|
||||
(IsPixEqual(I, F) && IsPixEqual(F, C) && IsPixEqual(C, B) && IsPixEqual(B, A) && !IsPixEqual(E, C)))))
|
||||
{
|
||||
FragColor.y += 4.0;
|
||||
|
||||
float dist_B_I = DistYCbCr(B, I);
|
||||
float dist_F_A = DistYCbCr(F, A);
|
||||
|
||||
if((STEEP_DIRECTION_THRESHOLD * dist_B_I <= dist_F_A) && neq(E,I) && neq(H,I))
|
||||
FragColor.y += 16.0;
|
||||
|
||||
if((STEEP_DIRECTION_THRESHOLD * dist_F_A <= dist_B_I) && neq(E,A) && neq(D,A))
|
||||
FragColor.y += 64.0;
|
||||
}
|
||||
|
||||
// Pixel Tap Mapping: -|x|x|-|-
|
||||
// x|A|B|C|-
|
||||
// x|D|E|F|-
|
||||
// -|G|H|-|-
|
||||
// -|-|-|-|-
|
||||
if(blendResult.x == BLEND_DOMINANT || (blendResult.x == BLEND_NORMAL &&
|
||||
!((blendResult.w != BLEND_NONE && !IsPixEqual(E, C)) || (blendResult.y != BLEND_NONE && !IsPixEqual(E, G)) ||
|
||||
(IsPixEqual(C, B) && IsPixEqual(B, A) && IsPixEqual(A, D) && IsPixEqual(D, G) && !IsPixEqual(E, A)))))
|
||||
{
|
||||
FragColor.x += 4.0;
|
||||
|
||||
float dist_D_C = DistYCbCr(D, C);
|
||||
float dist_B_G = DistYCbCr(B, G);
|
||||
|
||||
if((STEEP_DIRECTION_THRESHOLD * dist_D_C <= dist_B_G) && neq(E,C) && neq(F,C))
|
||||
FragColor.x += 16.0;
|
||||
|
||||
if((STEEP_DIRECTION_THRESHOLD * dist_B_G <= dist_D_C) && neq(E,G) && neq(H,G))
|
||||
FragColor.x += 64.0;
|
||||
}
|
||||
FragColor /= 255.0;
|
||||
}
|
||||
#endif
|
||||
277
Shaders/xbrz/xbrz-freescale-multipass.glsl.pass1
Normal file
277
Shaders/xbrz/xbrz-freescale-multipass.glsl.pass1
Normal file
@@ -0,0 +1,277 @@
|
||||
/*
|
||||
Hyllian's xBR-vertex code and texel mapping
|
||||
|
||||
Copyright (C) 2011/2016 Hyllian - sergiogdb@gmail.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
// This shader also uses code and/or concepts from xBRZ as it appears
|
||||
// in the Desmume source code. The license for which is as follows:
|
||||
|
||||
// ****************************************************************************
|
||||
// * This file is part of the HqMAME project. It is distributed under *
|
||||
// * GNU General Public License: http://www.gnu.org/licenses/gpl-3.0 *
|
||||
// * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved *
|
||||
// * *
|
||||
// * Additionally and as a special exception, the author gives permission *
|
||||
// * to link the code of this program with the MAME library (or with modified *
|
||||
// * versions of MAME that use the same license as MAME), and distribute *
|
||||
// * linked combinations including the two. You must obey the GNU General *
|
||||
// * Public License in all respects for all of the code used other than MAME. *
|
||||
// * If you modify this file, you may extend this exception to your version *
|
||||
// * of the file, but you are not obligated to do so. If you do not wish to *
|
||||
// * do so, delete this exception statement from your version. *
|
||||
// ****************************************************************************
|
||||
|
||||
#if defined(VERTEX)
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
#define COMPAT_VARYING out
|
||||
#define COMPAT_ATTRIBUTE in
|
||||
#define COMPAT_TEXTURE texture
|
||||
#else
|
||||
#define COMPAT_VARYING varying
|
||||
#define COMPAT_ATTRIBUTE attribute
|
||||
#define COMPAT_TEXTURE texture2D
|
||||
#endif
|
||||
|
||||
#ifdef GL_ES
|
||||
#define COMPAT_PRECISION mediump
|
||||
#else
|
||||
#define COMPAT_PRECISION
|
||||
#endif
|
||||
|
||||
COMPAT_ATTRIBUTE vec4 VertexCoord;
|
||||
COMPAT_ATTRIBUTE vec4 COLOR;
|
||||
COMPAT_ATTRIBUTE vec4 TexCoord;
|
||||
COMPAT_VARYING vec4 COL0;
|
||||
COMPAT_VARYING vec4 TEX0;
|
||||
|
||||
vec4 _oPosition1;
|
||||
uniform mat4 MVPMatrix;
|
||||
uniform COMPAT_PRECISION int FrameDirection;
|
||||
uniform COMPAT_PRECISION int FrameCount;
|
||||
uniform COMPAT_PRECISION vec2 OutputSize;
|
||||
uniform COMPAT_PRECISION vec2 TextureSize;
|
||||
uniform COMPAT_PRECISION vec2 InputSize;
|
||||
|
||||
// compatibility #defines
|
||||
#define vTexCoord TEX0.xy
|
||||
#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
|
||||
#define OutSize vec4(OutputSize, 1.0 / OutputSize)
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = MVPMatrix * VertexCoord;
|
||||
TEX0.xy = TexCoord.xy * 1.0001;
|
||||
}
|
||||
|
||||
#elif defined(FRAGMENT)
|
||||
|
||||
#ifdef GL_ES
|
||||
#ifdef GL_FRAGMENT_PRECISION_HIGH
|
||||
precision highp float;
|
||||
#else
|
||||
precision mediump float;
|
||||
#endif
|
||||
#define COMPAT_PRECISION mediump
|
||||
#else
|
||||
#define COMPAT_PRECISION
|
||||
#endif
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
#define COMPAT_VARYING in
|
||||
#define COMPAT_TEXTURE texture
|
||||
out COMPAT_PRECISION vec4 FragColor;
|
||||
#else
|
||||
#define COMPAT_VARYING varying
|
||||
#define FragColor gl_FragColor
|
||||
#define COMPAT_TEXTURE texture2D
|
||||
#endif
|
||||
|
||||
uniform COMPAT_PRECISION int FrameDirection;
|
||||
uniform COMPAT_PRECISION int FrameCount;
|
||||
uniform COMPAT_PRECISION vec2 OutputSize;
|
||||
uniform COMPAT_PRECISION vec2 TextureSize;
|
||||
uniform COMPAT_PRECISION vec2 InputSize;
|
||||
uniform sampler2D Texture;
|
||||
uniform sampler2D PassPrev2Texture;
|
||||
uniform COMPAT_PRECISION vec2 PassPrev2TextureSize;
|
||||
COMPAT_VARYING vec4 TEX0;
|
||||
|
||||
// compatibility #defines
|
||||
#define Source Texture
|
||||
#define vTexCoord TEX0.xy
|
||||
|
||||
#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
|
||||
#define OutSize vec4(OutputSize, 1.0 / OutputSize)
|
||||
#define OriginalSize vec4(PassPrev2TextureSize, 1.0 / PassPrev2TextureSize)
|
||||
|
||||
#define BLEND_NONE 0.
|
||||
#define BLEND_NORMAL 1.
|
||||
#define BLEND_DOMINANT 2.
|
||||
#define LUMINANCE_WEIGHT 1.0
|
||||
#define EQUAL_COLOR_TOLERANCE 30.0/255.0
|
||||
#define STEEP_DIRECTION_THRESHOLD 2.2
|
||||
#define DOMINANT_DIRECTION_THRESHOLD 3.6
|
||||
|
||||
float DistYCbCr(vec3 pixA, vec3 pixB)
|
||||
{
|
||||
const vec3 w = vec3(0.2627, 0.6780, 0.0593);
|
||||
const float scaleB = 0.5 / (1.0 - w.b);
|
||||
const float scaleR = 0.5 / (1.0 - w.r);
|
||||
vec3 diff = pixA - pixB;
|
||||
float Y = dot(diff.rgb, w);
|
||||
float Cb = scaleB * (diff.b - Y);
|
||||
float Cr = scaleR * (diff.r - Y);
|
||||
|
||||
return sqrt(((LUMINANCE_WEIGHT * Y) * (LUMINANCE_WEIGHT * Y)) + (Cb * Cb) + (Cr * Cr));
|
||||
}
|
||||
|
||||
bool IsPixEqual(const vec3 pixA, const vec3 pixB)
|
||||
{
|
||||
return (DistYCbCr(pixA, pixB) < EQUAL_COLOR_TOLERANCE);
|
||||
}
|
||||
|
||||
float get_left_ratio(vec2 center, vec2 origin, vec2 direction, vec2 scale)
|
||||
{
|
||||
vec2 P0 = center - origin;
|
||||
vec2 proj = direction * (dot(P0, direction) / dot(direction, direction));
|
||||
vec2 distv = P0 - proj;
|
||||
vec2 orth = vec2(-direction.y, direction.x);
|
||||
float side = sign(dot(P0, orth));
|
||||
float v = side * length(distv * scale);
|
||||
|
||||
// return step(0, v);
|
||||
return smoothstep(-sqrt(2.0)/2.0, sqrt(2.0)/2.0, v);
|
||||
}
|
||||
|
||||
#define eq(a,b) (a == b)
|
||||
#define neq(a,b) (a != b)
|
||||
|
||||
#define P(x,y) COMPAT_TEXTURE(PassPrev2Texture, coord + OriginalSize.zw * vec2(x, y)).rgb
|
||||
|
||||
void main()
|
||||
{
|
||||
//---------------------------------------
|
||||
// Input Pixel Mapping: -|B|-
|
||||
// D|E|F
|
||||
// -|H|-
|
||||
|
||||
vec2 scale = OutputSize.xy * OriginalSize.zw;
|
||||
vec2 pos = fract(vTexCoord * OriginalSize.xy) - vec2(0.5, 0.5);
|
||||
vec2 coord = vTexCoord - pos * OriginalSize.zw;
|
||||
|
||||
vec3 B = P( 0.,-1.);
|
||||
vec3 D = P(-1., 0.);
|
||||
vec3 E = P( 0., 0.);
|
||||
vec3 F = P( 1., 0.);
|
||||
vec3 H = P( 0., 1.);
|
||||
|
||||
vec4 info = floor(COMPAT_TEXTURE(Source, coord) * 255.0 + 0.5);
|
||||
|
||||
// info Mapping: x|y|
|
||||
// w|z|
|
||||
|
||||
vec4 blendResult = floor(mod(info, 4.0));
|
||||
vec4 doLineBlend = floor(mod(info / 4.0, 4.0));
|
||||
vec4 haveShallowLine = floor(mod(info / 16.0, 4.0));
|
||||
vec4 haveSteepLine = floor(mod(info / 64.0, 4.0));
|
||||
|
||||
vec3 res = E;
|
||||
|
||||
// Pixel Tap Mapping: -|-|-
|
||||
// -|E|F
|
||||
// -|H|-
|
||||
|
||||
if(blendResult.z > BLEND_NONE)
|
||||
{
|
||||
vec2 origin = vec2(0.0, 1.0 / sqrt(2.0));
|
||||
vec2 direction = vec2(1.0, -1.0);
|
||||
if(doLineBlend.z > 0.0)
|
||||
{
|
||||
origin = haveShallowLine.z > 0.0? vec2(0.0, 0.25) : vec2(0.0, 0.5);
|
||||
direction.x += haveShallowLine.z;
|
||||
direction.y -= haveSteepLine.z;
|
||||
}
|
||||
|
||||
vec3 blendPix = mix(H,F, step(DistYCbCr(E, F), DistYCbCr(E, H)));
|
||||
res = mix(res, blendPix, get_left_ratio(pos, origin, direction, scale));
|
||||
}
|
||||
|
||||
// Pixel Tap Mapping: -|-|-
|
||||
// D|E|-
|
||||
// -|H|-
|
||||
if(blendResult.w > BLEND_NONE)
|
||||
{
|
||||
vec2 origin = vec2(-1.0 / sqrt(2.0), 0.0);
|
||||
vec2 direction = vec2(1.0, 1.0);
|
||||
if(doLineBlend.w > 0.0)
|
||||
{
|
||||
origin = haveShallowLine.w > 0.0? vec2(-0.25, 0.0) : vec2(-0.5, 0.0);
|
||||
direction.y += haveShallowLine.w;
|
||||
direction.x += haveSteepLine.w;
|
||||
}
|
||||
|
||||
vec3 blendPix = mix(H,D, step(DistYCbCr(E, D), DistYCbCr(E, H)));
|
||||
res = mix(res, blendPix, get_left_ratio(pos, origin, direction, scale));
|
||||
}
|
||||
|
||||
// Pixel Tap Mapping: -|B|-
|
||||
// -|E|F
|
||||
// -|-|-
|
||||
if(blendResult.y > BLEND_NONE)
|
||||
{
|
||||
vec2 origin = vec2(1.0 / sqrt(2.0), 0.0);
|
||||
vec2 direction = vec2(-1.0, -1.0);
|
||||
|
||||
if(doLineBlend.y > 0.0)
|
||||
{
|
||||
origin = haveShallowLine.y > 0.0? vec2(0.25, 0.0) : vec2(0.5, 0.0);
|
||||
direction.y -= haveShallowLine.y;
|
||||
direction.x -= haveSteepLine.y;
|
||||
}
|
||||
|
||||
vec3 blendPix = mix(F,B, step(DistYCbCr(E, B), DistYCbCr(E, F)));
|
||||
res = mix(res, blendPix, get_left_ratio(pos, origin, direction, scale));
|
||||
}
|
||||
|
||||
// Pixel Tap Mapping: -|B|-
|
||||
// D|E|-
|
||||
// -|-|-
|
||||
if(blendResult.x > BLEND_NONE)
|
||||
{
|
||||
vec2 origin = vec2(0.0, -1.0 / sqrt(2.0));
|
||||
vec2 direction = vec2(-1.0, 1.0);
|
||||
if(doLineBlend.x > 0.0)
|
||||
{
|
||||
origin = haveShallowLine.x > 0.0? vec2(0.0, -0.25) : vec2(0.0, -0.5);
|
||||
direction.x -= haveShallowLine.x;
|
||||
direction.y += haveSteepLine.x;
|
||||
}
|
||||
|
||||
vec3 blendPix = mix(D,B, step(DistYCbCr(E, B), DistYCbCr(E, D)));
|
||||
res = mix(res, blendPix, get_left_ratio(pos, origin, direction, scale));
|
||||
}
|
||||
|
||||
FragColor = vec4(res, 1.0);
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user