使用@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,不仅多此一举,还可能加剧引用的绑定问题
给你几个具体的修复步骤:
砍掉冗余的实例属性和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} />; }检查dataTexture的创建逻辑
确认你在生成dataTexture的时候,没有不小心把组件的ref或者effect实例绑定到了texture的某个属性上(比如dataTexture.ref = effectRef这种操作),这是最容易触发循环引用的坑。如果需要动态更新纹理内容
要是后续你需要修改纹理的数据,直接操作dataTexture本身就好,Uniform会自动同步这个引用的变化:// 举个例子,在组件里更新纹理数据 dataTexture.image.data.set(newPixelData); dataTexture.needsUpdate = true;完全不用再去修改Uniform的value,shader会自动拿到更新后的纹理。
这样修改后,循环引用的链条就被打断了,那个JSON序列化错误应该就会消失啦!
内容来源于stack exchange
相关产品推荐
相关产品推荐

