关于URP的HDR格式

Posted by 恶毒的狗 on January 7, 2021

一个Bug

昨天发现一个神奇的bug,Scene视图和Game视图下,体积光的强度居然有很大差异,如下图:

img

并且这个bug只在我勾选了 HDR 后才会出现。

仔细检查后发现,URP 管线下勾选 HDR 后,Scene相机Game相机ColorBuffer格式 居然是不同的,具体差别如下:

  • Scene Camera: ARGBHalf

img

  • Game Camera: RGB111110Float

img

所以体积光的计算不可以依赖 RenderTexture的A通道,否则这两种格式下,计算结果就会有差异。

如何设置URP的HDR格式

和标准管线不同的是,URP管线下我似乎没找到可以设置 HDR格式 的地方。

跟了一下代码,发现相关代码如下:

1
2
3
4
5
6
7
GraphicsFormat hdrFormat;
if (!needsAlpha && RenderingUtils.SupportsGraphicsFormat(GraphicsFormat.B10G11R11_UFloatPack32, FormatUsage.Linear | FormatUsage.Render))
    hdrFormat = GraphicsFormat.B10G11R11_UFloatPack32;
else if (RenderingUtils.SupportsGraphicsFormat(GraphicsFormat.R16G16B16A16_SFloat, FormatUsage.Linear | FormatUsage.Render))
    hdrFormat = GraphicsFormat.R16G16B16A16_SFloat;
else
    hdrFormat = SystemInfo.GetGraphicsFormat(DefaultFormat.HDR); // This might actually be a LDR format on old devices.

上述代码除了对纹理格式的支持判断以外,还有一个 needAlpha 的判断,如果需要 A通道,就用 ARGBHalf,否则,就用 R11G11B10

至于这个 needsAlpha 由下面代码传入:

1
bool needsAlphaChannel = Graphics.preserveFramebufferAlpha;

Graphics.preserveFramebufferAlpha 是只读的,不过查了一下文档,PlayerSettings 上也有这个设置:

img

所以 URP 想要切换 HDR格式ARGBHalf,需要设置这个选项?

不过我没试,毕竟每个通道 16位 从性能上来说并不是一个好的选择。

修正

所以,继续保持 URP 默认的 R11G11B10 格式,修改一下体积光的shader,不要依赖 A通道 就正常了:

img

好了,拜拜。