1#version 150 2 3/* 4 NEDI Shader - pass1 5 6// This file is a part of MPDN Extensions. 7// https://github.com/zachsaw/MPDN_Extensions 8// 9// This library is free software; you can redistribute it and/or 10// modify it under the terms of the GNU Lesser General Public 11// License as published by the Free Software Foundation; either 12// version 3.0 of the License, or (at your option) any later version. 13// 14// This library is distributed in the hope that it will be useful, 15// but WITHOUT ANY WARRANTY; without even the implied warranty of 16// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17// Lesser General Public License for more details. 18// 19// You should have received a copy of the GNU Lesser General Public 20// License along with this library. 21// 22 23 Sources ported from this discussion thread: 24 25 http://forum.doom9.org/showthread.php?t=170727 26 27 Ported by Hyllian - 2015. 28*/ 29 30#define saturate(c) clamp(c, 0.0, 1.0) 31#define lerp(c) mix(c) 32#define mul(a,b) (b*a) 33#define fmod(c) mod(c) 34#define frac(c) fract(c) 35#define tex2D(a,b) COMPAT_TEXTURE(a,b) 36#define float2 vec2 37#define float3 vec3 38#define float4 vec4 39#define int2 ivec2 40#define int3 ivec3 41#define int4 ivec4 42#define bool2 bvec2 43#define bool3 bvec3 44#define bool4 bvec4 45#define float2x2 mat2x2 46#define float2x3 mat2x3 47#define float3x3 mat3x3 48#define float4x4 mat4x4 49#define float4x2 mat4x2 50 51#define s0 Source 52#define FIX(c) (c * 1.00001) 53 54#define NEDI_WEIGHT2 4.0 55#define NEDI_N2 24.0 56#define NEDI_E2 0.0 57#define NEDI_OFFSET2 0.0 58 59#define ITERATIONS 3 60#define WGT 2. 61 62#define width (SourceSize.x) 63#define height (SourceSize.y) 64 65#define px (1.0 * (SourceSize.z)) 66#define py (0.4999 * (SourceSize.w)) 67 68#define offset NEDI_OFFSET2 69 70#define Value(xy) (tex2D(s0,tex+float2(px,py)*(xy)).rgb)//-float4(0,0.4999,0.4999,0)) 71 72#define Get(xy) (dot(Value(xy),float3(.2126, .7152, .0722))+offset) 73#define Get4(xy) (float2(Get(xy+WGT*dir[0])+Get(xy+WGT*dir[1]),Get(xy+WGT*dir[2])+Get(xy+WGT*dir[3]))) 74 75#define sqr(x) (dot(x,x)) 76#define I (float2x2(1.,0.,0.,1.)) 77 78#if defined(VERTEX) 79 80#if __VERSION__ >= 130 81#define COMPAT_VARYING out 82#define COMPAT_ATTRIBUTE in 83#define COMPAT_TEXTURE texture 84#else 85#define COMPAT_VARYING varying 86#define COMPAT_ATTRIBUTE attribute 87#define COMPAT_TEXTURE texture2D 88#endif 89 90#ifdef GL_ES 91#define COMPAT_PRECISION mediump 92#else 93#define COMPAT_PRECISION 94#endif 95 96COMPAT_ATTRIBUTE vec4 VertexCoord; 97COMPAT_ATTRIBUTE vec4 COLOR; 98COMPAT_ATTRIBUTE vec4 TexCoord; 99COMPAT_VARYING vec4 COL0; 100COMPAT_VARYING vec4 TEX0; 101 102vec4 _oPosition1; 103uniform mat4 MVPMatrix; 104uniform COMPAT_PRECISION int FrameDirection; 105uniform COMPAT_PRECISION int FrameCount; 106uniform COMPAT_PRECISION vec2 OutputSize; 107uniform COMPAT_PRECISION vec2 TextureSize; 108uniform COMPAT_PRECISION vec2 InputSize; 109 110// compatibility #defines 111#define vTexCoord TEX0.xy 112#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize 113#define OutSize vec4(OutputSize, 1.0 / OutputSize) 114 115void main() 116{ 117 gl_Position = MVPMatrix * VertexCoord; 118 TEX0.xy = TexCoord.xy * 1.0001; 119} 120 121#elif defined(FRAGMENT) 122 123#ifdef GL_ES 124#ifdef GL_FRAGMENT_PRECISION_HIGH 125precision highp float; 126#else 127precision mediump float; 128#endif 129#define COMPAT_PRECISION mediump 130#else 131#define COMPAT_PRECISION 132#endif 133 134#if __VERSION__ >= 130 135#define COMPAT_VARYING in 136#define COMPAT_TEXTURE texture 137out COMPAT_PRECISION vec4 FragColor; 138#else 139#define COMPAT_VARYING varying 140#define FragColor gl_FragColor 141#define COMPAT_TEXTURE texture2D 142#endif 143 144uniform COMPAT_PRECISION int FrameDirection; 145uniform COMPAT_PRECISION int FrameCount; 146uniform COMPAT_PRECISION vec2 OutputSize; 147uniform COMPAT_PRECISION vec2 TextureSize; 148uniform COMPAT_PRECISION vec2 InputSize; 149uniform sampler2D Texture; 150COMPAT_VARYING vec4 TEX0; 151 152// compatibility #defines 153#define Source Texture 154#define vTexCoord TEX0.xy 155 156#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize 157#define OutSize vec4(OutputSize, 1.0 / OutputSize) 158 159//Cramer's method 160float2 solve(float2x2 A,float2 b) 161{ 162 return float2(determinant(float2x2(b,A[1])),determinant(float2x2(A[0],b)))/determinant(A); 163} 164 165void main() 166{ 167 float2 tex = vTexCoord; 168 169 float4 c0 = tex2D(s0,tex); 170 171 //Skip pixels on wrong grid 172 if ((frac(tex.x*width/2.0)<0.5)&&(frac(tex.y*height)<0.5) || (frac(tex.x*width/2.0)>0.5)&&(frac(tex.y*height)>0.5)) 173 { 174 FragColor = c0; 175 } 176 else 177 { 178 179 //Define window and directions 180 vec2 dir1 = vec2(-1., 0.); 181 vec2 dir2 = vec2( 1., 0.); 182 vec2 dir3 = vec2( 0., 1.); 183 vec2 dir4 = vec2( 0.,-1.); 184 float2 dir[4] = vec2[](dir1, dir2, dir3, dir4); 185 186 mat4x2 wind1 = mat4x2(-1.,0.,1.,0.,0.,1.,0.,-1.); 187 mat4x2 wind2 = mat4x2(-1.,0.,1.,0.,0.,1.,0.,-1.); 188 mat4x2 wind3 = mat4x2(-2.,-1.,2.,1.,-1.,2.,1.,-2.); 189 mat4x2 wind4 = mat4x2(-3.,-2.,3.,2.,-2.,3.,2.,-3.); 190 mat4x2 wind5 = mat4x2(-2.,1.,2.,-1.,1.,2.,-1.,-2.); 191 mat4x2 wind6 = mat4x2(-3.,2.,3.,-2.,2.,3.,-2.,-3.); 192 mat4x2 wind7 = mat4x2(-4.,-1.,4.,1.,-1.,4.,1.,-4.); 193 mat4x2 wind8 = mat4x2(-4.,1.,4.,-1.,1.,4.,-1.,-4.); 194 float4x2 wind[7] = mat4x2[](wind1, wind2, wind3, wind4, wind5, wind6, wind7); 195 196/* 197 wind[1] wind[2] 198-3 199-2 dir wind[0] 2 1 200-1 4 4 4 4 201 0 1 2 1 2 202 1 3 3 3 3 203 2 1 2 204 3 205*/ 206 207/* 208 wind[1] wind[2] 209-3 3 1 210-2 dir wind[0] 211-1 1 4 1 3 1 3 212 0 213 1 3 2 2 4 4 2 214 2 215 3 2 4 216*/ 217 218 //Initialization 219 float2x2 R = float2x2(0.0); 220 float2 r = float2(0.0); 221 222 float m[7] = float[](NEDI_WEIGHT2, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0); 223 224 //Calculate (local) autocorrelation coefficients 225 for (int k = 0; k<ITERATIONS; k+= 1){ 226 float4 y = float4(Get(wind[k][0]),Get(wind[k][1]),Get(wind[k][2]),Get(wind[k][3])); 227 float4x2 C = float4x2(Get4(wind[k][0]),Get4(wind[k][1]),Get4(wind[k][2]),Get4(wind[k][3])); 228 R += mul(transpose(C),m[k]*C); 229 r += mul(y,m[k]*C); 230 } 231 232 //Normalize 233 float n = NEDI_N2; 234 R /= n; r /= n; 235 236 //Calculate a = R^-1 . r 237 float e = NEDI_E2; 238 float2 a = solve(R+e*e*I,r+e*e/2.0); 239 240 //Nomalize 'a' (prevents overshoot) 241 a = .25 + float2(.4999,-.4999)*clamp(a[0]-a[1],-1.0,1.0); 242 243 //Calculate result 244 float2x3 x = float2x3(Value(dir[0])+Value(dir[1]),Value(dir[2])+Value(dir[3])) * float2x2(a,a); 245 float3 c = float3(x[0].xyz); 246 247 FragColor = float4(c, 1.0);//+float4(0,0.49999,0.49999,0); 248 } 249} 250#endif 251