Three.js使用EffectComposer时sRGBEncoding设置不生效
Three.js EffectComposer 后处理sRGB编码不生效问题修复
问题现象
后处理场景整体发灰、颜色饱和度不足,手动给WebGLRenderTarget设置sRGBEncoding后无改善:
核心原因
后处理的所有渲染计算必须在线性颜色空间完成,只有最终输出到显示设备的最后一步才需要做sRGB编码转换。直接给EffectComposer传入带sRGBEncoding的渲染目标,会导致颜色在管线中被错误重复编码,反而无法得到正确的显示效果。
修复步骤
- 移除所有后处理流程中用到的中间WebGLRenderTarget的
sRGBEncoding配置,统一使用THREE.LinearEncoding,保证后处理计算全程在线性空间运行。 - 非特殊离屏渲染需求不要手动给EffectComposer传入自定义renderTarget,优先使用EffectComposer内部自动管理的渲染目标即可。
- 在所有后处理Pass的末尾添加官方
OutputPass,由该Pass统一完成最终的sRGB编码、色调映射转换,这是编码转换的唯一正确位置。
修正后代码
1. 渲染目标配置(需自定义离屏目标时参考)
const renderTarget = new THREE.WebGLRenderTarget( sizes.width, sizes.height, { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat, encoding: THREE.LinearEncoding // 后处理用渲染目标必须用线性编码 } )
2. EffectComposer 初始化与Pass配置
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js' import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js' import { OutputPass } from 'three/examples/jsm/postprocessing/OutputPass.js' const effectComposer = new EffectComposer(renderer, renderTarget); effectComposer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); effectComposer.setSize(sizes.width, sizes.height) // 基础场景渲染Pass const renderPass = new RenderPass(scene, camera) effectComposer.addPass(renderPass) // 此处插入其他自定义后处理Pass,例如泛光、抗锯齿Pass等 // 所有Pass末尾添加输出Pass,负责最终颜色空间转换 const outputPass = new OutputPass() effectComposer.addPass(outputPass)
版本兼容说明
若使用Three.js r148以前版本,没有独立的
OutputPass,可将最后一个后处理Pass的renderToScreen属性设为true,同时保证渲染器配置正确:// r150以前版本配置 renderer.outputEncoding = THREE.sRGBEncoding // r150及以后版本encoding相关API已替换为colorSpace,使用以下配置 // renderer.outputColorSpace = THREE.SRGBColorSpace
内容的提问来源于stack exchange,提问作者ajay sharma
相关产品推荐
相关产品推荐

