我目前正在尝试绘制一个将使用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
问题是,如何平滑这些边缘?
更新:
所以我实现了一个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)
答案 0 :(得分:13)
这对MTKView
来说简单得多(只需将sampleCount
设置为视图和管道描述符上所需的MSAA样本数量,但以下是滚动自己的步骤。
创建渲染管道状态时,将渲染管道状态描述符的sampleCount
设置为多重采样计数。
在启动时,每当图层调整大小时,通过创建textureType
为MTLTextureType2DMultisample
且其sampleCount
的纹理描述符,创建尺寸等于图层可绘制尺寸的多重采样纹理是你的多重采样计数。如果您使用的是深度和/或模板缓冲区,请在描述符上设置这些属性。
渲染时,将MSAA纹理设置为渲染过程描述符的主要颜色附件的texture
,并将当前可绘制的纹理设置为resolveTexture
。
将颜色附件的storeAction
设置为MTLStoreActionMultisampleResolve
,以便在传递结束时将MSAA纹理解析为渲染缓冲区。
像往常一样画画并呈现。