Search code examples
iosmetal

Just make a Metal frag shader a transparent color?


I have a simple pipeline descriptor

 let p = MTLRenderPipelineDescriptor()
 ...
 p.colorAttachments[0].pixelFormat = .bgra8Unorm

The background is plain blue

 let bg = MTLClearColor(red: 0, green: 0, blue: 1, alpha: 1)

 let pass = MTLRenderPassDescriptor()
 pass.colorAttachments[0].loadAction = .clear
 pass.colorAttachments[0].clearColor = bg

I simply draw a poly on to it, say a red one:

fragment half4 fattie_fragment() {
    return half4(1,0,0, 1);
}

Or green ...

fragment half4 fattie_fragment() {
    return half4(0,1,0, 1);
}

What to do in Metal if you want the triangle color to be transparent?

fragment half4 fattie_fragment() {
    return half4(0,1,0, 0.275);
}

(Note - TBC I don't want the overall view to be transparent. Simply the shader, the drawn triangle.)


Solution

  • When you configure your render pipeline descriptor, enable blending and choose a suitable set of blend factors and operations. For example:

    let p = MTLRenderPipelineDescriptor()
    ...
    p.colorAttachments[0].isBlendingEnabled = true
    p.colorAttachments[0].rgbBlendOperation = .add
    p.colorAttachments[0].alphaBlendOperation = .add
    p.colorAttachments[0].sourceAlphaBlendFactor = .sourceAlpha
    p.colorAttachments[0].destinationAlphaBlendFactor = .oneMinusSourceAlpha
    p.colorAttachments[0].sourceRGBBlendFactor = .sourceAlpha
    p.colorAttachments[0].destinationRGBBlendFactor = .oneMinusSourceAlpha