透明 MTKView 未与其后面的窗口正确混合

Geo*_*rge 4 macos cocoa metal

我有一个简单的 macOS 应用程序,它有一个 MTKView——它只是窗口内的一个 MTKView。片段着色器总是这样做:

return float4(1, 0, 0, 0.01)
Run Code Online (Sandbox Code Playgroud)

那是带有 1% alpha 的红色。

属于 MTKView 的 CAMetalLayer 是非不透明的,窗口也是如此:

_mtkView.layer.opaque = NO;
_mtkView.window.opaque = NO;
_mtkView.window.backgroundColor = [NSColor clearColor];
_mtkView.window.hasShadow = NO;
Run Code Online (Sandbox Code Playgroud)

当我将此窗口放在另一个应用程序的窗口上时,我希望另一个应用程序的像素保持不变。相反,我看到黑色像素变成红色,而白色像素大部分保持不变。

在下面的屏幕截图中,三角形的颜色为 float4(1,0,0,0.01),并且在另一个窗口中显示了一个半黑半白的图像:

显示问题的屏幕截图

我本以为三角形的左半部分是黑色,略带红色,而不是鲜红色。

如果我的片段着色器更改为执行以下操作:

return float4(1, 0, 0, 0.001);
Run Code Online (Sandbox Code Playgroud)

然后它是完全透明的:来自其他窗口的像素完全不变地显示出来。这让我觉得我在窗口服务器中遇到了未经充分测试的代码路径,但我希望我可以做一些事情来使其工作。

我尝试过的

  • 更改 NSThemeFrame 的外观(没有效果)
  • 开启presentsWithTransaction(无效果)
  • GPU 调试器确认可绘制对象具有预期值

Geo*_*rge 6

苹果写道:

\n\n
\n

CoreAnimation 合成器要求其所有输入都预先乘以 alpha。有关详细信息,请参阅以下参考资料:\n https://en.wikipedia.org/wiki/Alpha_compositing \n https://blogs.msdn.microsoft.com/shawnhar/2009/11/06/premultiplied-alpha/

\n\n

当 RGB 预乘 alpha 时,>\n alpha 分量的任何 RGB 分量都不会通过硬件\xe2\x80\x99s 混合进行定义。

\n\n

修改片段着色器以返回 (0.1, 0, 0, 0.1),即 \n \xe2\x80\x9c0.1 alpha, full red\xe2\x80\x9d 会产生预期结果。

\n
\n\n

确实,这解决了我的问题。相关的提交是https://github.com/gnachman/iTerm2/commit/70a93885b1f67bda843ba546aca0eca67b750088,我修改了程序以绘制到屏幕外纹理,然后将其复制到可绘制对象,同时将红色、绿色和蓝色分量乘以 alpha。

\n\n

由于某种我无法理解的原因,我的测试程序还需要转换为线性颜色空间。

\n