粗糙的金属光栅化

问题描述 投票:0回答:1

我按照一个教程,看如何在金属中画一个三角形。我是初学金属的,问题是,三角形的边缘非常粗糙。就像光栅化器在偷工减料一样。它看起来很像素化,而且三角形边缘的像素比我的屏幕像素大得多。如果我正确使用光栅化,怎样才能把它光栅化得更平滑呢?

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()
    }
}
swift macos 2d metal
1个回答
1
投票

不确定,但我认为 viewDidLoad 现在渲染还为时过早。视图在这里可能没有最终尺寸。

相反,只需在 viewDidLoad (管道状态和缓冲区),把自己注册为 delegateMTKView 然后实现这个回调函数。

func draw(in view: MTKView) {
    // your drawing code here
}

每当你的视图被绘制到屏幕上时,这个函数就会被调用。


0
投票

正如Frank所建议的那样,viewDidLoad不是发布绘制调用的地方。这样你就只渲染了一帧。

关于别名,这取决于你渲染的分辨率。但是有一些技术可以处理这个问题,比如 smoothstep()在片段着色器或后处理抗锯齿,比如在更高的分辨率下渲染,然后降采样。

另外,在swift变量中使用camelCase,使用PascalCase好像是在类上调用静态。

© www.soinside.com 2019 - 2024. All rights reserved.