You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用p5.js实现Ping-Pong缓冲时纹理出现闪烁问题求助

涂抹(Smudge)效果闪烁问题排查

我正在用Shader和p5.js给纹理实现涂抹(smudge)效果,目前纹理能正常加载到Shader中,涂抹效果也能生效,但纹理每帧都会闪烁。我的思路是使用乒乓缓冲(ping-pong buffering),将另一个缓冲作为当前缓冲的纹理来保留效果,请问我哪里遗漏了?

p5.js 主代码

let container;
let img;
let recorder;
let buffers;
let flowField;
let options;
let isRecording = false;
let capturedImg;
let shaders = [];
let useBuffer0 = true; // 乒乓缓冲切换标志

const WIDTH = 1080;
const HEIGHT = 1350;
const BG_COLOR = "#F6F0E0";
const FRAME_RATE = 24;
const SHADER_PASSES = 2;

/*---------------预加载---------------*/
function preload() {
  container = document.getElementById("container");
  img = loadImage("./assets/images/colorImg.png");

  // 加载两个着色器通道
  shader0 = loadShader(
    "./assets/shaders/distortion/shader.vert",
    "./assets/shaders/distortion/smudge.frag"
  );
  shader1 = loadShader(
    "./assets/shaders/distortion/shader.vert",
    "./assets/shaders/distortion/smudge.frag"
  );
}

/*---------------初始化---------------*/
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);
}

/*---------------绘制循环---------------*/
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;
}

内容的提问来源于stack exchange,提问作者happycoder2121

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 14:17:15