3

iOS 用の Metal アプリでは、単純なクワッドにアタッチされた半透明のテクスチャをレンダリングする必要があります。colorAttachment の rgb とアルファのブレンド係数が正しくわかりません。

私のセットアップ:

1) 不透明度 50% の Photoshop で作成された赤色の画像。透明度のある PNG として保存されます。画像はプロジェクトの Assets フォルダーに保存されます。

ここに画像の説明を入力

2)最初に を作成し、次に- CoreImage - フィールドを使用してイメージ データを抽出することで、メタルテクスチャを作成します。この画像は現在、事前に乗算された形式になっているため、従来の Porter-Duff 式を適用できます。それについては後で詳しく説明します。UIImage.cgImage

// 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 の「オーバー」式です。

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

4

1 に答える 1

1

解決策は、ウォーレンの提案によると、MTKTextureLoaderOptionSRGBオプションをに設定することでしたfalse

于 2016-10-20T20:24:22.183 に答える