Transparency Issues with Repeated Stamping of Textures on an Mtkview

transparency issues with repeated stamping of textures on an MTKView

Your blend factors need some work. By default, even with blending enabled, the output of your fragment shader replaces the current contents of the color buffer (note that I'm ignoring the depth buffer here, since that's probably irrelevant).

The blend equation you currently have is:

cdst′ = 1 * csrc + 0 * cdst

For classic source-over compositing, what you want is something more like:

cdst′ = αsrc * csrc + (1 - αsrc) * cdst

renderPipelineDescriptor.colorAttachments[0].sourceRGBBlendFactor = .sourceAlpha
renderPipelineDescriptor.colorAttachments[0].destinationRGBBlendFactor = .oneMinusSourceAlpha
renderPipelineDescriptor.colorAttachments[0].sourceAlphaBlendFactor = .sourceAlpha
renderPipelineDescriptor.colorAttachments[0].destinationAlphaBlendFactor = .oneMinusSourceAlpha

For your particular use case, you might instead want to use additive blending, where the new fragment value is simply added to what's already there:

cdst′ = 1 * csrc + 1 * cdst

renderPipelineDescriptor.colorAttachments[0].sourceRGBBlendFactor = .one
renderPipelineDescriptor.colorAttachments[0].destinationRGBBlendFactor = .one
renderPipelineDescriptor.colorAttachments[0].sourceAlphaBlendFactor = .one
renderPipelineDescriptor.colorAttachments[0].destinationAlphaBlendFactor = .one

Whether or not you actually want additive blending depends on the exact effect you're after. With values less than 1, it will create a sort of "accumulating" paint effect, but it will also saturate once the cumulative color values exceed 1, which may not be pleasing. On the other hand, additive blending is commutative, which means you don't have to care about the order in which you draw your brush strokes.

(In the preceding discussion, I've ignored premultiplied alpha, which you absolutely must account for when drawing to a non-opaque image. You can read all about the gnarly details here.)

MTKView Transparency

Thanks to Frank, the answer was to just set the clearColor property of the view itself, which I missed. I also removed most adjustments in the MTLRenderPipelineDescriptor, who's code is now:

    let pipelineStateDescriptor = MTLRenderPipelineDescriptor();
pipelineStateDescriptor.label = "Pipeline";
pipelineStateDescriptor.vertexFunction = vertexFunction;
pipelineStateDescriptor.fragmentFunction = fragmentFunction;
pipelineStateDescriptor.colorAttachments[0].pixelFormat =
mtkView.colorPixelFormat;

Also no changes necessary to MTLRenderPassDescriptor from currentRenderPassDescriptor.

EDIT: Also be sure to set isOpaque property of MTKView to false too.

MTKView frequently displaying scrambled MTLTextures

The type of distortion looks like a bytes-per-row alignment issue between CGImage and MTLTexture. You're probably only seeing this issue when your image is a certain size that falls outside of the bytes-per-row alignment requirement of your MTLDevice. If you really need to store the texture as a CGImage, ensure that you are using the bytesPerRow value of the CGImage when copying back to the texture.

Texture Brush (Drawing Application ) Using Metal

I think you need to draw the brush squares to a separate texture, initially cleared to transparent, without blending. Then draw that whole texture to your view with blending.

If you draw the brush squares directly to the view, then they will accumulate. After you draw square 1, it's part of the image. Metal can no longer distinguish it from anything else that was already there. So, when you draw square 2 overlapping it, it will blend with what's already there, including square 1.



Related Topics



Leave a reply



Submit