-
Notifications
You must be signed in to change notification settings - Fork 72
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
754 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
precision highp float; | ||
precision mediump sampler2D; | ||
uniform sampler2D RawBuffer; | ||
uniform sampler2D GradBuffer; | ||
#define QUAD 0 | ||
#define demosw (1.0/10000.0) | ||
#define EPS (0.01) | ||
#define size1 (1.2) | ||
#define MSIZE1 3 | ||
#define KSIZE ((MSIZE1-1)/2) | ||
#define GRADSIZE 1.5 | ||
#define FUSEMIN 0.0 | ||
#define FUSEMAX 1.0 | ||
#define FUSESHIFT -0.1 | ||
#define FUSEMPY 1.4 | ||
#define NOISEO 0.0 | ||
#define NOISES 0.0 | ||
#define PI 3.1415926535897932384626433832795 | ||
out float Output; | ||
|
||
// Helper function to get Bayer sample | ||
float getBayerSample(ivec2 pos) { | ||
return texelFetch(RawBuffer, pos, 0).r; | ||
} | ||
|
||
float normpdf(in float x, in float sigma){return 0.39894*exp(-0.5*x*x/(sigma*sigma))/sigma;} | ||
void main() { | ||
ivec2 xy = ivec2(gl_FragCoord.xy); | ||
int fact1 = xy.x%2; | ||
int fact2 = xy.y%2; | ||
float outp = 0.0; | ||
if(fact1+fact2 != 1){ | ||
float outp = 0.0; | ||
float weight = 0.0; | ||
float green[4]; | ||
green[0] = getBayerSample(ivec2(xy+ivec2(0, -1))) + (getBayerSample(xy) - getBayerSample(xy + ivec2(0,-2)))/2.0 + (getBayerSample(xy + ivec2(0,-3)) - 2.0 * getBayerSample(xy + ivec2(0,-1)) + getBayerSample(xy + ivec2(0,1)))/8.0; | ||
green[1] = getBayerSample(ivec2(xy+ivec2(-1, 0))) + (getBayerSample(xy) - getBayerSample(xy + ivec2(-2,0)))/2.0 + (getBayerSample(xy + ivec2(-3,0)) - 2.0 * getBayerSample(xy + ivec2(-1,0)) + getBayerSample(xy + ivec2(1,0)))/8.0; | ||
green[2] = getBayerSample(ivec2(xy+ivec2(1, 0))) + (getBayerSample(xy) - getBayerSample(xy + ivec2(2,0)))/2.0 + (getBayerSample(xy + ivec2(-1,0)) - 2.0 * getBayerSample(xy + ivec2(1,0)) + getBayerSample(xy + ivec2(3,0)))/8.0; | ||
green[3] = getBayerSample(ivec2(xy+ivec2(0, 1))) + (getBayerSample(xy) - getBayerSample(xy + ivec2(0,2)))/2.0 + (getBayerSample(xy + ivec2(0,-1)) - 2.0 * getBayerSample(xy + ivec2(0,1)) + getBayerSample(xy + ivec2(0,3)))/8.0; | ||
float grad[4]; | ||
vec2 initialGrad = texelFetch(GradBuffer, ivec2(xy), 0).rg; | ||
grad[0] = initialGrad.g*initialGrad.g; | ||
grad[1] = initialGrad.r*initialGrad.r; | ||
grad[2] = initialGrad.r*initialGrad.r; | ||
grad[3] = initialGrad.g*initialGrad.g; | ||
for (int i =1;i<=2;i++){ | ||
if (i == 0) continue; | ||
float t = texelFetch(GradBuffer, ivec2(xy+ivec2(0, -i)), 0).g; | ||
grad[0] += t*t; | ||
t = texelFetch(GradBuffer, ivec2(xy+ivec2(-i, 0)), 0).r; | ||
grad[1] += t*t; | ||
t = texelFetch(GradBuffer, ivec2(xy+ivec2(i, 0)), 0).r; | ||
grad[2] += t*t; | ||
t = texelFetch(GradBuffer, ivec2(xy+ivec2(0, i)), 0).g; | ||
grad[3] += t*t; | ||
} | ||
grad[0] = 1.0/sqrt(grad[0]+demosw); | ||
grad[1] = 1.0/sqrt(grad[1]+demosw); | ||
grad[2] = 1.0/sqrt(grad[2]+demosw); | ||
grad[3] = 1.0/sqrt(grad[3]+demosw); | ||
|
||
vec2 HV = vec2(demosw); | ||
float weights = 0.00001; | ||
for (int j =-2;j<=2;j++) | ||
{ | ||
float k0 = normpdf(float(j), GRADSIZE); | ||
for (int i =-2;i<=2;i++){ | ||
if((i%2) + (j%2) != 1) continue; | ||
float k = normpdf(float(i), GRADSIZE)*k0; | ||
vec2 div = texelFetch(GradBuffer, ivec2(xy+ivec2(i, j)), 0).rg; | ||
HV += div*k; | ||
weights+=k; | ||
} | ||
} | ||
float MIN = min(min(green[0],green[1]),min(green[2],green[3])); | ||
float MAX = max(max(green[0],green[1]),max(green[2],green[3])); | ||
float dmax = 1.0 - MAX; | ||
float W; | ||
if(dmax < MIN){ | ||
W = dmax/MAX; | ||
} else { | ||
W = MIN/MAX; | ||
} | ||
float avr = (green[0]+green[1]+green[2]+green[3])/4.0; | ||
//float N = sqrt(avr*NOISES + NOISEO)/5.0; | ||
//W=W*W; | ||
//W=sqrt(W); | ||
//float badGR = (abs(HV.r-HV.g)*5.0)/((HV.r+HV.g)); | ||
HV/=weights; | ||
//if(abs(HV.r) > N || abs(HV.g) > N){ | ||
//float angle = atan(dxy.y,dxy.x)+PI; | ||
vec2 dxy2 = vec2((HV.x+HV.y)/2.0,(HV.y-HV.x)/2.0); | ||
float avrg = (green[0]*grad[0]+green[1]*grad[1]+green[2]*grad[2]+green[3]*grad[3])/(grad[0]+grad[1]+grad[2]+grad[3]); | ||
grad[0] = 1.0/sqrt(HV.x*HV.x+abs(green[0]-avrg)+demosw); | ||
grad[1] = 1.0/sqrt(HV.y*HV.y+abs(green[1]-avrg)+demosw); | ||
grad[2] = 1.0/sqrt(HV.y*HV.y+abs(green[2]-avrg)+demosw); | ||
grad[3] = 1.0/sqrt(HV.x*HV.x+abs(green[3]-avrg)+demosw); | ||
|
||
//Output = (green[0]*grad[0] +green[1]*grad[1] + green[2]*grad[2]+ green[3]*grad[3])/(grad[0]+grad[1]+grad[2]+grad[3]); | ||
float outp2 = 0.0; | ||
|
||
if (HV.y > HV.x){ | ||
Output = (green[1]*grad[1] + green[2]*grad[2])/(grad[1]+grad[2]); | ||
//Output = (green[1] + green[2])/(2.0); | ||
} else { | ||
Output = (green[0]*grad[0] + green[3]*grad[3])/(grad[0]+grad[3]); | ||
//Output = (green[0] + green[3])/(2.0); | ||
} | ||
//Output = mix(outp2,Output,0.5 - 0.5*abs(HV.y-HV.x)); | ||
/*} else { | ||
Output = avr; | ||
}*/ | ||
|
||
|
||
W = mix(FUSEMIN,FUSEMAX,clamp((W+FUSESHIFT)*FUSEMPY,0.0,1.0)); | ||
//Output = mix(Output,(green[0]*grad[0] + green[1]*grad[1]+ green[2]*grad[2] + green[3]*grad[3])/(grad[0]+grad[1]+grad[2]+grad[3]),W); | ||
|
||
|
||
/*} else { | ||
Output = green[0]*grad[0] + green[1]*grad[1]+ green[2]*grad[2] + green[3]*grad[3]; | ||
Output/=grad[0]+grad[1]+grad[2]+grad[3]; | ||
}*/ | ||
} | ||
else { | ||
Output = float(texelFetch(RawBuffer, (xy), 0).x); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
precision highp float; | ||
precision highp sampler2D; | ||
uniform sampler2D bayerTexture; | ||
#define alpha 3.75 | ||
#define THRESHOLD 1.9 | ||
#define L 3 | ||
out vec3 Output; | ||
uniform int yOffset; | ||
|
||
// Helper function to get Bayer sample | ||
float getBayerSample(ivec2 pos) { | ||
return texelFetch(bayerTexture, pos, 0).r; | ||
} | ||
|
||
// Helper function to determine Bayer pattern at a given position | ||
// 0: R, 1: G (at red row), 2: G (at blue row), 3: B | ||
int getBayerPattern(ivec2 pos) { | ||
int x = (pos.x) % 2; | ||
int y = (pos.y) % 2; | ||
return (y << 1) | x; | ||
} | ||
|
||
float dxy(ivec2 pos, int direction) { | ||
int pattern = getBayerPattern(pos); | ||
float useGreen = (pattern == 1 || pattern == 2) ? 1.0 : -1.0; | ||
if (direction == 0) { | ||
return abs((4.0 * getBayerSample(pos) - 3.0 * getBayerSample(pos + ivec2(1,0)) - 3.0 * getBayerSample(pos + ivec2(-1,0)) + getBayerSample(pos + ivec2(-2,0)) + getBayerSample(pos + ivec2(2,0)))/6.0); | ||
//return (2.0 * getBayerSample(pos) - getBayerSample(pos + ivec2(1,0)) - getBayerSample(pos + ivec2(-1,0)))/2.0; | ||
} else { | ||
return abs((4.0 * getBayerSample(pos) - 3.0 * getBayerSample(pos + ivec2(0,1)) - 3.0 * getBayerSample(pos + ivec2(0,-1)) + getBayerSample(pos + ivec2(0,-2)) + getBayerSample(pos + ivec2(0,2)))/6.0); | ||
//return (2.0 * getBayerSample(pos) - getBayerSample(pos + ivec2(0,1)) - getBayerSample(pos + ivec2(0,-1)))/2.0; | ||
} | ||
} | ||
|
||
float dt(ivec2 pos, int direction) { | ||
float c = dxy(pos, direction); | ||
if (direction == 0) { | ||
float c2 = dxy(pos + ivec2(2, 0), direction); | ||
float c1 = dxy(pos + ivec2(1, 0), direction); | ||
return (abs(c - c1) + abs(c1 - c2))/2.0; | ||
} else { | ||
float c2 = dxy(pos + ivec2(0, 2), direction); | ||
float c1 = dxy(pos + ivec2(0, 1), direction); | ||
return (abs(c - c1) + abs(c1 - c2))/2.0; | ||
} | ||
} | ||
|
||
float dxy2(ivec2 pos, int direction) { | ||
float c = getBayerSample(pos); | ||
float c1; | ||
float c2; | ||
float c3; | ||
if (direction == 0){ | ||
c1 = getBayerSample(pos + ivec2(2,0)); | ||
c2 = getBayerSample(pos + ivec2(-1,0)); | ||
c3 = getBayerSample(pos + ivec2(1,0)); | ||
} else { | ||
c1 = getBayerSample(pos + ivec2(0,2)); | ||
c2 = getBayerSample(pos + ivec2(0,-1)); | ||
c3 = getBayerSample(pos + ivec2(0,1)); | ||
} | ||
return (abs(c - c1) + abs(c2 - c3)) / 2.0 + alpha * dt(pos,direction); | ||
} | ||
|
||
float IG(ivec2 pos, int direction) { | ||
int pattern = getBayerPattern(pos); | ||
float useGreen = (pattern == 1 || pattern == 2) ? -1.0 : 1.0; | ||
float useInv = 1.0 - useGreen; | ||
if (direction == 0) { | ||
return 2.0 * dxy2(pos,0) + dxy2(pos + ivec2(0,-1),0) + dxy2(pos + ivec2(0,1),0); | ||
} else { | ||
return 2.0 * dxy2(pos,1) + dxy2(pos + ivec2(-1,0),1) + dxy2(pos + ivec2(1,0),1); | ||
} | ||
} | ||
|
||
|
||
// Green plane interpolation | ||
vec3 interpolateGreen(ivec2 pos) { | ||
int pattern = getBayerPattern(pos); | ||
if (pattern == 1 || pattern == 2) return vec3(getBayerSample(pos),0.0,0.0); // Already green | ||
|
||
float igE = IG(pos,1); | ||
float igS = IG(pos,0); | ||
float igW = IG(pos + ivec2(2,0),1); | ||
float igN = IG(pos + ivec2(0,2),0); | ||
|
||
float wE = 1.0 / (igE + 0.0001); | ||
float wS = 1.0 / (igS + 0.0001); | ||
float wW = 1.0 / (igW + 0.0001); | ||
float wN = 1.0 / (igN + 0.0001); | ||
// Pass 1 | ||
float gE = getBayerSample(pos + ivec2(0,1)) + (getBayerSample(pos) - getBayerSample(pos + ivec2(0,2)))/2.0 + (getBayerSample(pos + ivec2(0,-1)) - 2.0 * getBayerSample(pos + ivec2(0,1)) + getBayerSample(pos + ivec2(0,3)))/8.0; | ||
float gW = getBayerSample(pos + ivec2(0,-1)) + (getBayerSample(pos) - getBayerSample(pos + ivec2(0,-2)))/2.0 + (getBayerSample(pos + ivec2(0,-3)) - 2.0 * getBayerSample(pos + ivec2(0,-1)) + getBayerSample(pos + ivec2(0,1)))/8.0; | ||
float gN = getBayerSample(pos + ivec2(-1,0)) + (getBayerSample(pos) - getBayerSample(pos + ivec2(-2,0)))/2.0 + (getBayerSample(pos + ivec2(-3,0)) - 2.0 * getBayerSample(pos + ivec2(-1,0)) + getBayerSample(pos + ivec2(1,0)))/8.0; | ||
float gS = getBayerSample(pos + ivec2(1,0)) + (getBayerSample(pos) - getBayerSample(pos + ivec2(2,0)))/2.0 + (getBayerSample(pos + ivec2(-1,0)) - 2.0 * getBayerSample(pos + ivec2(1,0)) + getBayerSample(pos + ivec2(3,0)))/8.0; | ||
|
||
float gh = (gE * wE + gW * wW)/(wE + wW + 0.0001); | ||
float gv = (gN * wN + gS * wS)/(wN + wS + 0.0001); | ||
float gd = (gE * wE + gW * wW + gN * wN + gS * wS)/(wE + wW + wN + wS + 0.0001); | ||
|
||
float dh = igE + igW; | ||
float dv = igN + igS; | ||
|
||
float E = max(dh/dv, dv/dh); | ||
|
||
if (E < THRESHOLD) { | ||
return vec3(-1.0, gh, gv); | ||
} else { | ||
if (dh > dv) { | ||
return vec3(gv, gh, gv); | ||
} else { | ||
return vec3(gh, gh, gv); | ||
} | ||
} | ||
/*if (dh > dv) { | ||
return vec3(gv, gh, gv); | ||
//return vec3(gv, gh, gv); | ||
} else { | ||
return vec3(gh, gh, gv); | ||
//return vec3(gh, gh, gv); | ||
}*/ | ||
|
||
return vec3(0.0); | ||
} | ||
|
||
|
||
void main() { | ||
ivec2 pos = ivec2(gl_FragCoord.xy); | ||
pos+=ivec2(0,yOffset); | ||
|
||
// Step 1: Green plane interpolation | ||
vec3 initialGreen = interpolateGreen(pos); | ||
Output = initialGreen; | ||
} |
Oops, something went wrong.