Растеризация Rough Metal - PullRequest
0 голосов
/ 05 мая 2020

Я следил за учебником, чтобы узнать, как нарисовать треугольник в Metal. Я начинаю заниматься металлом, и проблема в том, что у треугольника очень острые края. Это как если бы растеризатор срезал углы. Он выглядит пиксельным, а пиксели краев треугольника намного больше, чем пиксели моего экрана. Как мне сделать растеризацию более гладкой, если я правильно использую растеризацию?

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()
    }
}

Ответы [ 2 ]

1 голос
/ 05 мая 2020

Не уверен, но думаю, что viewDidLoad слишком рано для рендеринга. Здесь у представления может не быть своего окончательного размера.

Вместо этого выполните только код инициализации в viewDidLoad (состояние конвейера и буферы), зарегистрируйтесь как delegate из MTKView, а затем реализуйте это функция обратного вызова:

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

Это вызывается каждый раз, когда вы просматриваете отрисовку на экране.

0 голосов
/ 05 мая 2020

Как предположил Фрэнк, viewDidLoad - не место для вызова отрисовки. Таким образом вы визуализируете только 1 кадр. обработка сглаживания, такая как рендеринг с более высоким разрешением, а затем понижающая дискретизация.

Кроме того, в быстрых переменных используется camelCase, использование PascalCase похоже на вызов статики для классов.

...