UE4 iOS Metal FrameBufferFetchMRT

Posted xoyojank

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UE4 iOS Metal FrameBufferFetchMRT相关的知识,希望对你有一定的参考价值。

最近在手机上尝试了一下把SceneColor改成R11G11B10, 使用FrameBufferFetch来读取深度.

android上可以使用framebuffer_fetch_depth_stencil, 但是ios上不支持DepthFetch.
所以就尝试使用MRT输出一个R16F的Depth, 需要依赖FramebufferFetchMRT的实现.
4.26中UE4已经增加了延迟渲染, FramebufferFetchMRT已经实现了vk和metal的, 所以很方便地就合并了过来, 用法是这样的:
fetch color : SubpassFetchRGBA_0()/SubpassFetchRGBA_1()/…
fetch float : SubpassFetchR_0()/SubpassFetchR_1()/…
这些宏会在Shader编译时被转换成平台相关的Shader, 然后我感觉我就掉进了一个坑.

代码写完后发现iOS上SubpassFetchR_1()怎么也不起作用(DepthFade的物体没了), 使用XCode GPU Frame Capture看了一下Shader, 结果发现gl_LastFragDataR_1竟然是绑定到了[[color(0)]]上?

继续把HLSL和DXC的代码dump出来, 没有发现问题, [[vk::input_attachment_index(1)]]里面的index是1


所以证明代码写得应该没有问题, 问题出在HLSL转换Metal Shader这一步. 猜测可能是没有[[color(0)]], [[vk::input_attachment_index(1)]]就给绑定到了[[color(0)]]上了?
于是尝试把DepthFetch的宏定义改成这个样子:

#define DepthbufferFetchES2() (SubpassFetchRGBA_0().w * 0 + SubpassFetchR_1())


可以看到生成的HLSL里已经有[[vk::input_attachment_index(0)]]了

Metal Shader这边终于正确地绑定到了[[color(1)]], 而且[[color(0)]]因为乘零的关系还被优化掉了.
撞大运式编程又解决了一个问题…虽然还是没找到根源@_@

确定了是spirv-cross 的锅, 4.26改了一下

以上是关于UE4 iOS Metal FrameBufferFetchMRT的主要内容,如果未能解决你的问题,请参考以下文章

iOS 上的 LibGDX FrameBuffer 怪癖

Metal(iOS)中的多重采样/锯齿状边缘

未找到 iOS Metal 默认库

为 iOS 模拟器目标构建时忽略 .metal 文件

在 iOS 上的 Metal 中未触发 addPresentedHandler

iOS Metal 计算管道比搜索任务的 CPU 实现慢