UPD1:
I added the line below right after defining vec2 uv. this solved flipping. But now, it’s clear that pixel sorting doesn’t work properly, THRESHOLD value of 1.0 shouldn’t sort pixels and it indeed isn’t, while value of 0.0 should make smooth transition from dark pixels to bright, but it’s not. Where am I wrong? Why doesn’t it fully sort pixels?
uv.y=1.0-uv.y;
Translated shader from here
OLD:
It seems almost working, but every even frame output picture is flipped vertically. Please help me understand what’s causing the issue.
Of course I could draw only every other frame, but it’s just not right.
if(frameCount%2==0){
image(pg, 0, 0,width,height);
}
Here’s program code.
import processing.video.*;
Capture video;
PShader sh;
PGraphics pg;
void setup() {
surface.setLocation(0, 0);
size(640, 480, P3D);
pg = createGraphics(width, height, P3D);
sh = loadShader("frag.glsl", "vert.glsl");
sh.set("iResolution", float(width), float(height));
printArray(Capture.list());
video = new Capture(this, Capture.list()[0]);
video.start();
textureMode(NORMAL);
noStroke();
pg.shader(sh);
}
void draw() {
sh.set("iFrame", frameCount);
sh.set("texture0", video);
sh.set("texture1", pg.get());
pg.beginDraw();
pg.noStroke();
drawQuad(pg);
pg.endDraw();
image(pg, 0, 0);
}
void keyPressed() {
println(keyCode);
switch(keyCode) {
default:
break;
}
}
void captureEvent(Capture video) {
video.read();
}
void drawQuad(PGraphics pgraphics) {
pgraphics.beginShape(QUAD);
pgraphics.vertex(0, 0, 0, 0);
pgraphics.vertex(width, 0, 1, 0);
pgraphics.vertex(width, height, 1, 1);
pgraphics.vertex(0, height, 0, 1);
pgraphics.endShape();
}
Here’s fragment shader code
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif
uniform vec2 iResolution;
uniform int iFrame;
uniform sampler2D texture0;
uniform sampler2D texture1;
varying vec4 vertColor;
varying vec4 vertTexCoord;
#define THRESHOLD 0.0 // 0.0 means full sorting
// grayscale average of the colors
float gscale (vec3 c) { return (c.r+c.g+c.b)/3.; }
void main(){
// uvs
vec2 uv = gl_FragCoord.xy / iResolution.xy;
uv.y=1.0-uv.y;
if (iFrame < 10) {
gl_FragColor = texture(texture0, uv);
return;
}
// the frame number parity, -1 is odd 1 is even
float fParity = mod(float(iFrame), 2.) * 2. - 1.;
// we differentiate every 1/2 pixel on the horizontal axis, will be -1 or 1
float vp = mod(floor(uv.x * iResolution.x), 2.0) * 2. - 1.;
vec2 dir = vec2(-1, 0);
dir*= fParity * vp;
dir/= iResolution.xy;
// we sort
vec4 curr = texture(texture1, uv);
vec4 comp = texture(texture1, uv + dir);
float gCurr = gscale(curr.rgb);
float gComp = gscale(comp.rgb);
// gl_FragColor = vec4(gCurr);
// we prevent the sort from happening on the borders
if (uv.x + dir.x <= 0.0 || uv.x + dir.x >= 1.0) {
gl_FragColor = curr;
return;
}
// the direction of the displacement defines the order of the comparaison
if (dir.x < 0.0) {
if (gCurr > THRESHOLD && gComp > gCurr) {
gl_FragColor = comp;
return;
} else {
gl_FragColor = curr;
return;
}
}
else {
if (gComp > THRESHOLD && gCurr >= gComp) {
gl_FragColor = comp;
return;
} else {
gl_FragColor = curr;
return;
}
}
}