#version 450 core
out vec4 FragCr;
uniform sampler2D OutputTextureUniform;
struct luma
{
float N, S, E, W, M;
float Min, Max, Contrast;
float NE, NW, SE, SW;
};
struct edge
{
bool Horz;
float StepSize;
};
in vec2 UV;
float ComputeBlendFactor(luma L)
{
float F = 2.0 * (L.N + L.E + L.S + L.W);
F += L.NE + L.NW + L.SE + L.SW;
F *= 1/12.0;
F = abs(F - L.M);
F = clamp(F / L.Contrast, 0, 1);
float B = smoothstep(0, 1, F);
return B*B*0.75;
}
edge ComputeEdge(in luma L)
{
edge E;
float HorzContrast =
abs(L.N + L.S - 2 * L.M) * 2 +
abs(L.NE + L.SE - 2 * L.E) +
abs(L.NW + L.SW - 2 * L.W);
float VertContrast =
abs(L.E + L.W - 2 * L.M) * 2 +
abs(L.NE + L.NW - 2 * L.N) +
abs(L.SE + L.SW - 2 * L.S);
E.Horz = HorzContrast >= VertContrast;
E.StepSize = E.Horz ? 1/1024.0 : 1/1024.0;
float pLuminance = E.Horz ? L.N : L.E;
float nLuminance = E.Horz ? L.S : L.W;
float pGradient = abs(pLuminance - L.M);
float nGradient = abs(nLuminance - L.M);
if (pGradient < nGradient) {
E.StepSize = -E.StepSize;
}
return E;
}
luma SampleLuma(vec2 UV)
{
const vec2 Offsets[8] = {
vec2(0, 1),
vec2(1, 0),
vec2(0, -1),
vec2(-1, 0),
vec2(1, 1),
vec2(-1, 1),
vec2(1, -1),
vec2(-1, -1),
};
const float Ts = 1/1024.0;
float M = texture(OutputTextureUniform, UV).g;
float N = texture(OutputTextureUniform, UV + Offsets[0]*Ts).g;
float E = texture(OutputTextureUniform, UV + Offsets[1]*Ts).g;
float S = texture(OutputTextureUniform, UV + Offsets[2]*Ts).g;
float W = texture(OutputTextureUniform, UV + Offsets[3]*Ts).g;
float NE = texture(OutputTextureUniform, UV + Offsets[4]*Ts).g;
float NW = texture(OutputTextureUniform, UV + Offsets[5]*Ts).g;
float SE = texture(OutputTextureUniform, UV + Offsets[6]*Ts).g;
float SW = texture(OutputTextureUniform, UV + Offsets[7]*Ts).g;
float Min = min(min(min(min(M, N), E), S), W);
float Max = max(max(max(max(M, N), E), S), W);
float Contrast = Max - Min;
return luma(N, S, E, W, M, Min, Max, Contrast, NE, NW, SE, SW);
}
void main()
{
FragCr = texture(OutputTextureUniform, UV);
if (FragCr.a != 1)
{
const float Q = 1/16.0;
const vec2 Offsets[8] = {
vec2(0, 1),
vec2(1, 0),
vec2(0, -1),
vec2(-1, 0),
vec2(1, 1),
vec2(-1, 1),
vec2(1, -1),
vec2(-1, -1),
};
vec4 A = texture(OutputTextureUniform, UV+Offsets[0]*Q);
vec4 B = texture(OutputTextureUniform, UV+Offsets[1]*Q);
vec4 C = texture(OutputTextureUniform, UV+Offsets[2]*Q);
vec4 D = texture(OutputTextureUniform, UV+Offsets[3]*Q);
vec4 E = texture(OutputTextureUniform, UV+Offsets[4]*Q);
vec4 F = texture(OutputTextureUniform, UV+Offsets[5]*Q);
vec4 G = texture(OutputTextureUniform, UV+Offsets[6]*Q);
vec4 H = texture(OutputTextureUniform, UV+Offsets[7]*Q);
vec4 K = A + B + C + D + E + F + G + H;
K *= 1/8.0;
K.a = 1.0;
FragCr = K.rgba;
}
}