164 lines
6 KiB
Text
164 lines
6 KiB
Text
|
//
|
||
|
// This program is free software: you can redistribute it and/or modify
|
||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||
|
// the Free Software Foundation, either version 3 of the License, or
|
||
|
// (at your option) any later version.
|
||
|
//
|
||
|
// This program is distributed in the hope that it will be useful,
|
||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
// GNU Lesser General Public License for more details.
|
||
|
//
|
||
|
// You should have received a copy of the GNU Lesser General Public License
|
||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
|
||
|
//!DESC Super-xBR (step1, luma)
|
||
|
//!HOOK LUMA
|
||
|
//!BIND HOOKED
|
||
|
//!WIDTH 2 HOOKED.w *
|
||
|
//!HEIGHT 2 HOOKED.h *
|
||
|
//!OFFSET -0.500000 -0.500000
|
||
|
float superxbr() {
|
||
|
float i[4*4];
|
||
|
float res;
|
||
|
#define i(x,y) i[(x)*4+(y)]
|
||
|
#define luma(x, y) i((x), (y))
|
||
|
#define GET_SAMPLE(pos) HOOKED_texOff(pos)[0]
|
||
|
#define SAMPLE4_MUL(sample4, w) dot((sample4), (w))
|
||
|
vec2 dir = fract(HOOKED_pos * HOOKED_size) - 0.5;
|
||
|
dir = transpose(HOOKED_rot) * dir;
|
||
|
vec2 dist = HOOKED_size * min(HOOKED_pos, vec2(1.0) - HOOKED_pos);
|
||
|
if (dir.x * dir.y < 0.0 && dist.x > 1.0 && dist.y > 1.0)
|
||
|
return 0.0;
|
||
|
if (dir.x < 0.0 || dir.y < 0.0 || dist.x < 1.0 || dist.y < 1.0)
|
||
|
return GET_SAMPLE(-dir);
|
||
|
#define IDX(x, y) vec2(float(x)-1.25, float(y)-1.25)
|
||
|
for (int x = 0; x < 4; x++)
|
||
|
for (int y = 0; y < 4; y++) {
|
||
|
i(x,y) = GET_SAMPLE(IDX(x,y));
|
||
|
}
|
||
|
{ // step
|
||
|
vec4 d1 = vec4( i(0,0), i(1,1), i(2,2), i(3,3) );
|
||
|
vec4 d2 = vec4( i(0,3), i(1,2), i(2,1), i(3,0) );
|
||
|
vec4 h1 = vec4( i(0,1), i(1,1), i(2,1), i(3,1) );
|
||
|
vec4 h2 = vec4( i(0,2), i(1,2), i(2,2), i(3,2) );
|
||
|
vec4 v1 = vec4( i(1,0), i(1,1), i(1,2), i(1,3) );
|
||
|
vec4 v2 = vec4( i(2,0), i(2,1), i(2,2), i(2,3) );
|
||
|
float dw = 0.129633;
|
||
|
float ow = 0.175068;
|
||
|
vec4 dk = vec4(-dw, dw+0.5, dw+0.5, -dw);
|
||
|
vec4 ok = vec4(-ow, ow+0.5, ow+0.5, -ow);
|
||
|
float d1c = SAMPLE4_MUL(d1, dk);
|
||
|
float d2c = SAMPLE4_MUL(d2, dk);
|
||
|
float vc = SAMPLE4_MUL(v1+v2, ok)/2.0;
|
||
|
float hc = SAMPLE4_MUL(h1+h2, ok)/2.0;
|
||
|
float d_edge = 0.0;
|
||
|
d_edge += -1.0 * abs(luma(2,0) - luma(0,2));
|
||
|
d_edge -= -1.0 * abs(luma(3,2) - luma(1,0));
|
||
|
d_edge += 1.0 * abs(luma(1,1) - luma(0,2));
|
||
|
d_edge -= 1.0 * abs(luma(2,1) - luma(1,0));
|
||
|
d_edge += 1.0 * abs(luma(2,0) - luma(1,1));
|
||
|
d_edge -= 1.0 * abs(luma(3,2) - luma(2,1));
|
||
|
d_edge += 2.0 * abs(luma(2,1) - luma(1,2));
|
||
|
d_edge -= 2.0 * abs(luma(2,2) - luma(1,1));
|
||
|
d_edge += -1.0 * abs(luma(3,1) - luma(1,3));
|
||
|
d_edge -= -1.0 * abs(luma(2,3) - luma(0,1));
|
||
|
d_edge += 1.0 * abs(luma(2,2) - luma(1,3));
|
||
|
d_edge -= 1.0 * abs(luma(1,2) - luma(0,1));
|
||
|
d_edge += 1.0 * abs(luma(3,1) - luma(2,2));
|
||
|
d_edge -= 1.0 * abs(luma(2,3) - luma(1,2));
|
||
|
float o_edge = 0.0;
|
||
|
o_edge += 1.0 * abs(luma(1,0) - luma(1,1));
|
||
|
o_edge -= 1.0 * abs(luma(0,1) - luma(1,1));
|
||
|
o_edge += 2.0 * abs(luma(1,1) - luma(1,2));
|
||
|
o_edge -= 2.0 * abs(luma(1,1) - luma(2,1));
|
||
|
o_edge += 1.0 * abs(luma(1,2) - luma(1,3));
|
||
|
o_edge -= 1.0 * abs(luma(2,1) - luma(3,1));
|
||
|
o_edge += 1.0 * abs(luma(2,0) - luma(2,1));
|
||
|
o_edge -= 1.0 * abs(luma(0,2) - luma(1,2));
|
||
|
o_edge += 2.0 * abs(luma(2,1) - luma(2,2));
|
||
|
o_edge -= 2.0 * abs(luma(1,2) - luma(2,2));
|
||
|
o_edge += 1.0 * abs(luma(2,2) - luma(2,3));
|
||
|
o_edge -= 1.0 * abs(luma(2,2) - luma(3,2));
|
||
|
float str = smoothstep(0.0, 0.600000 + 1e-6, abs(d_edge));
|
||
|
res = mix(mix(d2c, d1c, step(0.0, d_edge)),
|
||
|
mix(hc, vc, step(0.0, o_edge)), 1.0 - str);
|
||
|
float lo = min(min( i(1,1), i(2,1) ), min( i(1,2), i(2,2) ));
|
||
|
float hi = max(max( i(1,1), i(2,1) ), max( i(1,2), i(2,2) ));
|
||
|
res = clamp(res, lo, hi);
|
||
|
} // step
|
||
|
return res;
|
||
|
} // superxbr
|
||
|
vec4 hook() {
|
||
|
return vec4(superxbr(), 0.0, 0.0, 0.0);
|
||
|
}
|
||
|
//!DESC Super-xBR (step2, luma)
|
||
|
//!HOOK LUMA
|
||
|
//!BIND HOOKED
|
||
|
float superxbr() {
|
||
|
float i[4*4];
|
||
|
float res;
|
||
|
#define i(x,y) i[(x)*4+(y)]
|
||
|
#define luma(x, y) i((x), (y))
|
||
|
#define GET_SAMPLE(pos) HOOKED_texOff(pos)[0]
|
||
|
#define SAMPLE4_MUL(sample4, w) dot((sample4), (w))
|
||
|
vec2 dir = fract(HOOKED_pos * HOOKED_size / 2.0) - 0.5;
|
||
|
if (dir.x * dir.y > 0.0)
|
||
|
return GET_SAMPLE(0);
|
||
|
#define IDX(x, y) vec2(x+y-3,y-x)
|
||
|
for (int x = 0; x < 4; x++)
|
||
|
for (int y = 0; y < 4; y++) {
|
||
|
i(x,y) = GET_SAMPLE(IDX(x,y));
|
||
|
}
|
||
|
{ // step
|
||
|
vec4 d1 = vec4( i(0,0), i(1,1), i(2,2), i(3,3) );
|
||
|
vec4 d2 = vec4( i(0,3), i(1,2), i(2,1), i(3,0) );
|
||
|
vec4 h1 = vec4( i(0,1), i(1,1), i(2,1), i(3,1) );
|
||
|
vec4 h2 = vec4( i(0,2), i(1,2), i(2,2), i(3,2) );
|
||
|
vec4 v1 = vec4( i(1,0), i(1,1), i(1,2), i(1,3) );
|
||
|
vec4 v2 = vec4( i(2,0), i(2,1), i(2,2), i(2,3) );
|
||
|
float dw = 0.175068;
|
||
|
float ow = 0.129633;
|
||
|
vec4 dk = vec4(-dw, dw+0.5, dw+0.5, -dw);
|
||
|
vec4 ok = vec4(-ow, ow+0.5, ow+0.5, -ow);
|
||
|
float d1c = SAMPLE4_MUL(d1, dk);
|
||
|
float d2c = SAMPLE4_MUL(d2, dk);
|
||
|
float vc = SAMPLE4_MUL(v1+v2, ok)/2.0;
|
||
|
float hc = SAMPLE4_MUL(h1+h2, ok)/2.0;
|
||
|
float d_edge = 0.0;
|
||
|
d_edge += 1.0 * abs(luma(1,1) - luma(0,2));
|
||
|
d_edge -= 1.0 * abs(luma(2,1) - luma(1,0));
|
||
|
d_edge += 1.0 * abs(luma(2,0) - luma(1,1));
|
||
|
d_edge -= 1.0 * abs(luma(3,2) - luma(2,1));
|
||
|
d_edge += 4.0 * abs(luma(2,1) - luma(1,2));
|
||
|
d_edge -= 4.0 * abs(luma(2,2) - luma(1,1));
|
||
|
d_edge += 1.0 * abs(luma(2,2) - luma(1,3));
|
||
|
d_edge -= 1.0 * abs(luma(1,2) - luma(0,1));
|
||
|
d_edge += 1.0 * abs(luma(3,1) - luma(2,2));
|
||
|
d_edge -= 1.0 * abs(luma(2,3) - luma(1,2));
|
||
|
float o_edge = 0.0;
|
||
|
o_edge += 1.0 * abs(luma(1,0) - luma(1,1));
|
||
|
o_edge -= 1.0 * abs(luma(0,1) - luma(1,1));
|
||
|
o_edge += 4.0 * abs(luma(1,1) - luma(1,2));
|
||
|
o_edge -= 4.0 * abs(luma(1,1) - luma(2,1));
|
||
|
o_edge += 1.0 * abs(luma(1,2) - luma(1,3));
|
||
|
o_edge -= 1.0 * abs(luma(2,1) - luma(3,1));
|
||
|
o_edge += 1.0 * abs(luma(2,0) - luma(2,1));
|
||
|
o_edge -= 1.0 * abs(luma(0,2) - luma(1,2));
|
||
|
o_edge += 4.0 * abs(luma(2,1) - luma(2,2));
|
||
|
o_edge -= 4.0 * abs(luma(1,2) - luma(2,2));
|
||
|
o_edge += 1.0 * abs(luma(2,2) - luma(2,3));
|
||
|
o_edge -= 1.0 * abs(luma(2,2) - luma(3,2));
|
||
|
float str = smoothstep(0.0, 0.600000 + 1e-6, abs(d_edge));
|
||
|
res = mix(mix(d2c, d1c, step(0.0, d_edge)),
|
||
|
mix(hc, vc, step(0.0, o_edge)), 1.0 - str);
|
||
|
float lo = min(min( i(1,1), i(2,1) ), min( i(1,2), i(2,2) ));
|
||
|
float hi = max(max( i(1,1), i(2,1) ), max( i(1,2), i(2,2) ));
|
||
|
res = clamp(res, lo, hi);
|
||
|
} // step
|
||
|
return res;
|
||
|
} // superxbr
|
||
|
vec4 hook() {
|
||
|
return vec4(superxbr(), 0.0, 0.0, 0.0);
|
||
|
}
|