我按照一个教程,看如何在金属中画一个三角形。我是初学金属的,问题是,三角形的边缘非常粗糙。就像光栅化器在偷工减料一样。它看起来很像素化,而且三角形边缘的像素比我的屏幕像素大得多。如果我正确使用光栅化,怎样才能把它光栅化得更平滑呢?
import Cocoa
import MetalKit
class ViewController: NSViewController {
var MetalView: MTKView {
return view as! MTKView
}
var Device: MTLDevice!
var CommandQue: MTLCommandQueue!
var PipelineState: MTLRenderPipelineState?
var VertexBuffer: MTLBuffer?
override func viewDidLoad() {
super.viewDidLoad()
MetalView.device = MTLCreateSystemDefaultDevice()
Device = MetalView.device
MetalView.clearColor = MTLClearColorMake(0, 1, 1, 1)
CommandQue = Device.makeCommandQueue()
let CommandBuffer = CommandQue.makeCommandBuffer()
let CommandEncoder = CommandBuffer!.makeRenderCommandEncoder(descriptor: MetalView.currentRenderPassDescriptor!)
let Library = Device.makeDefaultLibrary()
let VertexFunction = Library!.makeFunction(name: "VertexShader")
let FragmentFunction = Library!.makeFunction(name: "FragmentShader")
let PipelineDescriptor = MTLRenderPipelineDescriptor()
PipelineDescriptor.vertexFunction = VertexFunction
PipelineDescriptor.fragmentFunction = FragmentFunction
PipelineDescriptor.colorAttachments[0].pixelFormat = .bgra8Unorm
do {
PipelineState = try Device.makeRenderPipelineState(descriptor: PipelineDescriptor)
} catch let Error as NSError {
print("Error: \(Error.localizedDescription)")
}
let Vertices: [Float] = [0, 1, 0, -1, -1, 0, 1, -1, 0]
VertexBuffer = Device.makeBuffer(bytes: Vertices, length: Vertices.count*MemoryLayout<Float>.size, options: [])
CommandEncoder!.setRenderPipelineState(PipelineState!)
CommandEncoder!.setVertexBuffer(VertexBuffer, offset: 0, index: 0)
CommandEncoder!.drawPrimitives(type: .triangle, vertexStart: 0, vertexCount: Vertices.count)
CommandEncoder!.endEncoding()
CommandBuffer!.present(MetalView.currentDrawable!)
CommandBuffer!.commit()
}
}
不确定,但我认为 viewDidLoad
现在渲染还为时过早。视图在这里可能没有最终尺寸。
相反,只需在 viewDidLoad
(管道状态和缓冲区),把自己注册为 delegate
的 MTKView
然后实现这个回调函数。
func draw(in view: MTKView) {
// your drawing code here
}
每当你的视图被绘制到屏幕上时,这个函数就会被调用。
正如Frank所建议的那样,viewDidLoad不是发布绘制调用的地方。这样你就只渲染了一帧。
关于别名,这取决于你渲染的分辨率。但是有一些技术可以处理这个问题,比如 smoothstep()
在片段着色器或后处理抗锯齿,比如在更高的分辨率下渲染,然后降采样。
另外,在swift变量中使用camelCase,使用PascalCase好像是在类上调用静态。