金属中的多采样/锯齿状边缘(iOS)

Jef*_*ker 8 ios swift metal

我正在尝试绘制一个将使用Swift中的Metal动画的图形.我已成功绘制了一帧图形.从这张图片中可以看出,图形很简单.我无法弄清楚的是如何MultiSample绘图.一般来说,对Metal的引用似乎很少,特别是在Swift语法方面.

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
Run Code Online (Sandbox Code Playgroud)

问题是,我如何平滑这些边缘?

更新:

所以我已经实现了一个MultiSample纹理,并将sampleCount设置为4.我没有注意到任何差异所以我怀疑我做错了什么.

最后:

所以最终确实出现了多次采样的工作原理.最初我有顶点用0 alpha包裹这些"光线".这是使边缘更平滑的技巧.使用这些顶点,多重采样似乎没有改善边缘.当我恢复为每条光线有4个顶点时,多次采样改善了它们的边缘.

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)
Run Code Online (Sandbox Code Playgroud)

war*_*enm 13

这简单明了MTKView(只需sampleCount在视图和管道描述符上设置所需数量的MSAA样本),但这里是滚动自己的步骤.

  1. 创建渲染管道状态时,将sampleCount渲染管道状态描述符设置为多重采样计数.

  2. 在启动时,每当层调整大小,创建一个多重采样纹理尺寸创建一个纹理描述符,其等于图层的绘制尺寸textureTypeMTLTextureType2DMultisample,其sampleCount是你的多重采样数.如果您正在使用深度和/或模板缓冲区,请在其描述符上设置这些属性.

  3. 渲染时,将MSAA纹理设置为texture渲染过程描述符的主要颜色附件,并将当前可绘制的纹理设置为resolveTexture.

  4. 设置storeAction颜色附件的位置,MTLStoreActionMultisampleResolve以便在传递结束时将MSAA纹理解析为渲染缓冲区.

  5. 像往常一样画画和呈现.

  • 请注意,在第 2 步中,您还必须将 MSAA 纹理的 `storageMode` 设置为 `MTLStorageModePrivate`。理想情况下,您还应该将 `usage` 设置为 `MTLTextureUsageRenderTarget`。 (2认同)