代码之家  ›  专栏  ›  技术社区  ›  George

透明的mtkview与它后面的窗口不能正确混合

  •  2
  • George  · 技术社区  · 7 年前

    我有一个简单的MacOS应用程序,它有一个mtkview——它只是一个窗口中的mtkview。片段明暗器始终执行以下操作:

    return float4(1, 0, 0, 0.01)
    

    这是1%α的红色。

    属于mtkview的cameratalayer是非不透明的,窗口也是如此:

    _mtkView.layer.opaque = NO;
    _mtkView.window.opaque = NO;
    _mtkView.window.backgroundColor = [NSColor clearColor];
    _mtkView.window.hasShadow = NO;
    

    当我把这个窗口放在另一个应用程序的窗口上时,我希望另一个应用程序的像素不会改变。相反,我看到黑色像素变红,白色像素基本不变。

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

    Screenshot showing the problem

    我本以为在三角形的左半部分会有一点点黑色,而不是鲜红色。

    如果我的片段明暗器更改为执行此操作:

    return float4(1, 0, 0, 0.001);
    

    然后它是完全透明的:来自其他窗口的像素完全不变。这让我觉得我在窗口服务器上碰到了一个测试不好的代码路径,但我希望我能做些什么来让它工作。

    我试过的

    • 更改nsthemeframe的外观(没有效果)
    • 打开PresentsWithTransaction(无效果)
    • GPU调试程序确认drawable具有预期值
    1 回复  |  直到 7 年前
        1
  •  1
  •   George    7 年前

    苹果写道:

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

    当rgb被alpha预乘时,则任何rgb组件都是> alpha组件通过硬件混合未定义。

    修改片段明暗器以返回(0.1、0、0、0.1),即 0.1α,全红产生预期结果。

    事实上,这解决了我的问题。相关承诺是 https://github.com/gnachman/iTerm2/commit/70a93885b1f67bda843ba546aca0eca67b750088 在这里,我修改了程序以绘制到屏幕外的纹理,然后将其复制到可绘制图形中,同时将红色、绿色和蓝色组件乘以alpha。

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

    推荐文章