Reputation: 75
I'm trying to implement a smudge effect on a texture using shaders and p5.js. I can see that the texture is being loaded into the shader and I can see the smudging, but my texture is flickering on each frame. The idea was to use two buffers and pass the other buffer as the buffer's texture to persist the result (ping-pong). Am I missing something? Here's the code:
let container;
let img;
let recorder;
let buffers;
let flowField;
let options;
let isRecording = false;
let capturedImg;
let shaders = [];
let useBuffer0 = true; // flag to swap ping–pong buffers
const WIDTH = 1080;
const HEIGHT = 1350;
const BG_COLOR = "#F6F0E0";
const FRAME_RATE = 24;
const SHADER_PASSES = 2;
/*---------------PRELOAD---------------*/
function preload() {
container = document.getElementById("container");
img = loadImage("./assets/images/colorImg.png");
// Load two shader passes
shader0 = loadShader(
"./assets/shaders/distortion/shader.vert",
"./assets/shaders/distortion/smudge.frag"
);
shader1 = loadShader(
"./assets/shaders/distortion/shader.vert",
"./assets/shaders/distortion/smudge.frag"
);
}
/*---------------SETUP---------------*/
function setup() {
createCanvas(WIDTH, HEIGHT);
options = WebUtils.getCookies();
frameRate(FRAME_RATE);
background(BG_COLOR);
recorder = new CanvasRecorder(canvas);
textureBuffer = createGraphics(WIDTH, HEIGHT);
shadderBuffer0 = createGraphics(WIDTH, HEIGHT, WEBGL);
shaderBuffer1 = createGraphics(WIDTH, HEIGHT, WEBGL);
textureBuffer.background(img);
shadderBuffer0.shader(shader0);
shader0.setUniform('texture0', img);
shader0.setUniform('resolution', [width, height]);
shader0.setUniform('time', millis() / 1000.0);
shader0.setUniform('mouse', [mouseX, height - mouseY]);
shadderBuffer0.rect(0, 0, width, height);
}
/*---------------DRAW---------------*/
function draw() {
const buffer = useBuffer0 ? shadderBuffer0 : shaderBuffer1;
const otherBuffer = useBuffer0 ? shaderBuffer1 : shadderBuffer0;
const shader = useBuffer0 ? shader0 : shader1;
buffer.shader(shader)
shader.setUniform('texture0', otherBuffer);
shader.setUniform('resolution', [width, height]);
shader.setUniform('time', millis() / 1000.0);
shader.setUniform('mouse', [mouseX, height - mouseY]);
buffer.rect(0, 0, width, height);
useBuffer0 = !useBuffer0;
image(buffer, 0, 0);
}
smudge.frag:
#ifdef GL_ES
precision mediump float;
#endif
uniform vec2 resolution;
uniform vec2 mouse;
uniform sampler2D texture0;
void main() {
vec2 uv = gl_FragCoord.xy / resolution;
vec2 center = mouse / resolution;
vec2 delta = uv - center;
float dist = length(delta);
float radius = 0.07;
float strength = 0.5;
if(dist < radius) {
float factor = (radius - dist) / radius;
float angle = factor * strength * 3.14159;
float s = sin(angle);
float c = cos(angle);
mat2 rot = mat2(c, -s, s, c);
delta = rot * delta;
}
uv = center + delta;
gl_FragColor = texture2D(texture0, uv);
}
shader.vert:
attribute vec3 aPosition;
attribute vec2 aTexCoord;
varying vec2 vTexCoord;
void main() {
vTexCoord = aTexCoord;
vec4 positionVec4 = vec4(aPosition, 1.0);
positionVec4.xy = positionVec4.xy * 2.0 - 1.0;
gl_Position = positionVec4;
}
Upvotes: 0
Views: 27
Reputation: 1
Try this:
void main() {
vec2 uv = gl_FragCoord.xy / resolution;
uv.y = 1.0 - uv.y;
Upvotes: 0