【问题标题】:In Metal what are the correct blendFactors for classic Porter-Duff "over" compositing?在 Metal 中,经典 Porter-Duff“过度”合成的正确 blendFactors 是什么?
【发布时间】:2017-03-02 09:58:06
【问题描述】:

在 iOS 的 Metal 应用程序中,我需要渲染附加到简单四边形的半透明纹理。我无法找出正确的 colorAttachment RGB 和 alpha 混合因子。

我的设置:

1) 在 Photoshop 中创建的红色图像,不透明度为 50%。保存为具有透明度的 PNG。图片存储在我的项目 Assets 文件夹中。

2) 我创建了一个 Metal 纹理,首先创建一个UIImage,然后使用.cgImage - CoreImage - 字段来提取图像数据。此图像现在采用 预乘 格式,因此可以应用经典的 Porter-Duff 公式。稍后会详细介绍。

// load hero texture
do {

    let textureLoader = MTKTextureLoader(device: device)

    guard let image = UIImage(named:"red_translucent") else {
        fatalError("Error: Can not create UIImage")
    }

    if (image.cgImage?.alphaInfo == .premultipliedLast) {
        print("texture uses premultiplied alpha. Rock.")
    }

    heroTexture = try textureLoader.newTexture(with: image.cgImage!, options: nil)
} catch {
    fatalError("Error: Can not load texture")
}

3) 这是我相当无聊的纹理片段着色器

fragment float4 textureFragmentShader(_Vertex_ vert [[ stage_in ]], texture2d<float> texas [[ texture(0) ]]) {

    constexpr sampler defaultSampler;

    float4 rgba = texas.sample(defaultSampler, vert.st).rgba;
    return rgba;
}

4) 这是我的 colorAttachment 混合因子设置,它是 Porter-Duff “over”公式:

descriptor.colorAttachments[ 0 ].isBlendingEnabled = true

descriptor.colorAttachments[ 0 ].rgbBlendOperation = .add
descriptor.colorAttachments[ 0 ].alphaBlendOperation = .add

descriptor.colorAttachments[ 0 ].sourceRGBBlendFactor = .one
descriptor.colorAttachments[ 0 ].sourceAlphaBlendFactor = .one

descriptor.colorAttachments[ 0 ].destinationRGBBlendFactor = .oneMinusSourceAlpha
descriptor.colorAttachments[ 0 ].destinationAlphaBlendFactor = .oneMinusSourceAlpha

5) 当我在白色背景上使用这种红色半透明纹理渲染四边形时,图像太暗了。不正确的渲染(右图)是 rgb = (182, 127, 127)。 Photoshop 中的正确图像是 rgb (255, 127, 127):

什么是正确的混合函数?

更新

如果人们想看看 Github 上的代码: https://github.com/turner/HelloMetal/tree/2_pass_render

【问题讨论】:

  • 我无法使用手动生成的纹理重现这一点。您是否使用getBytes 来检查纹理中的实际像素值?您还可以尝试在加载时传递MTKTextureLoaderOptionSRGB (= false) 选项,以确保您不会无意中获得 sRGB 纹理,如果源数据实际上不在 sRGB 空间中,该纹理可能会显得更暗。跨度>
  • 嗨,沃伦,我会试试的。该项目在 Github 上,如果你想看看:github.com/turner/HelloMetal/tree/2_pass_render。它是名为 2_pass_render 的分支。
  • 宾果游戏!禁用 sRGB 就可以了。好的。谢谢沃伦,

标签: ios macos texture-mapping metal porter-duff


【解决方案1】:

根据 Warren 的建议,解决方案是将 MTKTextureLoaderOptionSRGB 选项设置为 false

【讨论】:

    猜你喜欢
    • 2013-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-02
    • 1970-01-01
    • 2016-05-25
    • 1970-01-01
    • 2018-12-03
    相关资源
    最近更新 更多