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

使用@react-three/postprocessing自定义R3F后处理效果时遭遇循环结构转JSON错误求助

@react-three/postprocessing自定义R3F后处理效果时遭遇循环结构转JSON错误求助

嗨,这个问题我之前帮朋友排查过类似的,来给你理一理!

你遇到的这个循环结构转JSON的错误,核心原因是出现了循环引用链:你的CustomPixelDistortionEffect实例持有了dataTexture的引用,而这个dataTexture又通过某个ref属性反向引用回了effect实例,形成了effect → dataTexture → ref → effect的闭环,当React或者相关库尝试序列化这个对象(比如devtools调试时)就会报错。

再具体看你的代码,有两个关键问题:

  • 你把dataTexture存在了effect的实例属性里,这完全没必要,因为你在constructor里已经把它传给THREE.Uniform了,Uniform本身会持有这个纹理的引用
  • 你额外加的update方法重复给Uniform赋值this.dataTexture,不仅多此一举,还可能加剧引用的绑定问题

给你几个具体的修复步骤:

  1. 砍掉冗余的实例属性和update方法
    直接移除this.dataTexture = dataTexture这行代码,以及整个update方法。修改后的Effect类应该是这样:

    class CustomPixelDistortionEffect extends Effect {
      constructor(dataTexture) {
        super("Pixelation", fragmentShader, {
          uniforms: new Map([["u_DataTexture", new THREE.Uniform(dataTexture)]])
        });
        // 删掉this.dataTexture = dataTexture;
      }
    
      // 删掉整个update方法
    }
    
    const Wrapped = wrapEffect(CustomPixelDistortionEffect);
    
    export function CustomPixelDistortion() {
      // 这里保留你创建/获取dataTexture的逻辑
      return <CustomPixelationEffect dataTexture={dataTexture} />;
    }
    
  2. 检查dataTexture的创建逻辑
    确认你在生成dataTexture的时候,没有不小心把组件的ref或者effect实例绑定到了texture的某个属性上(比如dataTexture.ref = effectRef这种操作),这是最容易触发循环引用的坑。

  3. 如果需要动态更新纹理内容
    要是后续你需要修改纹理的数据,直接操作dataTexture本身就好,Uniform会自动同步这个引用的变化:

    // 举个例子,在组件里更新纹理数据
    dataTexture.image.data.set(newPixelData);
    dataTexture.needsUpdate = true;
    

    完全不用再去修改Uniform的value,shader会自动拿到更新后的纹理。

这样修改后,循环引用的链条就被打断了,那个JSON序列化错误应该就会消失啦!

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 14:19:32