Multisampling/jagged edges in Metal (iOS)

Viewed 3285

I'm currently trying to draw a graphic that will be animated using Metal in Swift. I have successfully drawn a single frame of my graphic. The graphic is simple, as you can see from this image. What I can't figure out is how to multisample the drawing. There seems to be few references on Metal in general, especially in regards to the Swift syntax.

self.metalLayer = CAMetalLayer()
self.metalLayer.device = self.device
self.metalLayer.pixelFormat = .BGRA8Unorm
self.metalLayer.framebufferOnly = true
self.metalLayer.frame = self.view.frame
self.view.layer.addSublayer(self.metalLayer)

self.renderer = SunRenderer(device: self.device, frame: self.view.frame)

let defaultLibrary = self.device.newDefaultLibrary()
let fragmentProgram = defaultLibrary!.newFunctionWithName("basic_fragment")
let vertexProgram = defaultLibrary!.newFunctionWithName("basic_vertex")

let pipelineStateDescriptor = MTLRenderPipelineDescriptor()
pipelineStateDescriptor.vertexFunction = vertexProgram
pipelineStateDescriptor.fragmentFunction = fragmentProgram
pipelineStateDescriptor.colorAttachments[0].pixelFormat = .BGRA8Unorm
pipelineStateDescriptor.colorAttachments[0].blendingEnabled = true

pipelineStateDescriptor.colorAttachments[0].rgbBlendOperation = MTLBlendOperation.Add
pipelineStateDescriptor.colorAttachments[0].alphaBlendOperation = MTLBlendOperation.Add
pipelineStateDescriptor.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactor.SourceAlpha
pipelineStateDescriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactor.SourceAlpha
pipelineStateDescriptor.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactor.OneMinusSourceAlpha
pipelineStateDescriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactor.OneMinusSourceAlpha

The question, how do I smooth these edges?

UPDATE:

So I have implemented a MultiSample texture and set the sampleCount to 4. I don't notice any difference so I suspect I did something wrong.

FINAL:

So, in the end, it does appear the multisampling works. Initially, I had vertices wrapping these "rays" with a 0 alpha. This is a trick to make smoother edges. With these vertices, multisampling didn't seem to improve the edges. When I reverted back to have 4 vertices per ray, the multi-sampling improved their edges.

let defaultLibrary = self.device.newDefaultLibrary()
let fragmentProgram = defaultLibrary!.newFunctionWithName("basic_fragment")
let vertexProgram = defaultLibrary!.newFunctionWithName("basic_vertex")
        
let pipelineStateDescriptor = MTLRenderPipelineDescriptor()
pipelineStateDescriptor.vertexFunction = vertexProgram
pipelineStateDescriptor.fragmentFunction = fragmentProgram
pipelineStateDescriptor.colorAttachments[0].pixelFormat = .BGRA8Unorm
pipelineStateDescriptor.colorAttachments[0].blendingEnabled = true
pipelineStateDescriptor.sampleCount = 4
        
pipelineStateDescriptor.colorAttachments[0].rgbBlendOperation =    MTLBlendOperation.Add
pipelineStateDescriptor.colorAttachments[0].alphaBlendOperation = MTLBlendOperation.Add
pipelineStateDescriptor.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactor.SourceAlpha
pipelineStateDescriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactor.SourceAlpha

pipelineStateDescriptor.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactor.OneMinusSourceAlpha
pipelineStateDescriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactor.OneMinusSourceAlpha

let desc = MTLTextureDescriptor()
desc.textureType = MTLTextureType.Type2DMultisample
desc.width = Int(self.view.frame.width)
desc.height = Int(self.view.frame.height)
desc.sampleCount = 4
desc.pixelFormat = .BGRA8Unorm
        
self.sampletex = self.device.newTextureWithDescriptor(desc)


// When rendering
let renderPassDescriptor = MTLRenderPassDescriptor()
renderPassDescriptor.colorAttachments[0].texture = sampletex
renderPassDescriptor.colorAttachments[0].resolveTexture = drawable.texture
renderPassDescriptor.colorAttachments[0].loadAction = .Clear
renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColor(red: 23/255.0, green: 26/255.0, blue: 31/255.0, alpha: 0.0)
renderPassDescriptor.colorAttachments[0].storeAction = .MultisampleResolve
    
    
let commandBuffer = commandQueue.commandBuffer()
    
let renderEncoder = commandBuffer.renderCommandEncoderWithDescriptor(renderPassDescriptor)
renderEncoder.setRenderPipelineState(pipelineState)
1 Answers
Related