【发布时间】:2018-12-23 13:20:51
【问题描述】:
我有一个简单的 macOS 应用程序,它有一个 MTKView——它只是一个窗口内的 MTKView。片段着色器总是这样:
return float4(1, 0, 0, 0.01)
那是带有 1% alpha 的红色。
属于 MTKView 的 CAMetalLayer 是不透明的,窗口也是如此:
_mtkView.layer.opaque = NO;
_mtkView.window.opaque = NO;
_mtkView.window.backgroundColor = [NSColor clearColor];
_mtkView.window.hasShadow = NO;
当我将此窗口放在另一个应用程序的窗口上时,我希望其他应用程序的像素保持不变。相反,我看到黑色像素变成了红色,而白色像素几乎没有变化。
在下面的屏幕截图中,三角形的颜色为 float4(1,0,0,0.01),并且在另一个窗口中显示了一个半黑半白的图像:
我本以为三角形的左半边是黑色,略带红色,而不是鲜红色。
如果我的片段着色器被更改为这样做:
return float4(1, 0, 0, 0.001);
然后它是完全透明的:来自其他窗口的像素完全不变地显示出来。这让我觉得我在窗口服务器中遇到了一个未经充分测试的代码路径,但我希望我能做些什么来让它工作。
我尝试了什么
- 更改 NSThemeFrame 的外观(无效)
- 开启 PresentWithTransaction(无效)
- GPU 调试器确认可绘制对象具有预期值
【问题讨论】:
-
确保图层的
compositingFilter和backgroundFilters是nil。将视图的framebufferOnly设置为 false 会改变什么吗? -
compositingFilter 和 backgroundFilters 对于 CAMetalLayer 和它的超层都是 nil 和空的。在 CAMetalLayer 上设置 framebufferOnly=NO 无效。
-
作为一个实验,如果您将 Metal 视图包含在使用普通 Cocoa 绘图绘制半黑半白图像的 layer-back 视图中会发生什么?也就是说,消除窗口之间的合成,只验证视图层合成。同样,尝试不使用 Metal 的实验,仅使用透明填充并绘制大部分透明三角形的图层支持视图,然后看看它是如何合成的。
-
这是个好主意。它没有正确合成,并显示相同的症状。
-
…并且当使用具有非透明图层的图层托管视图时,它确实正确合成,其内容是具有透明三角形的 NSImage。