【问题标题】:iOS metal resources - where to findiOS 金属资源 - 在哪里可以找到
【发布时间】:2021-01-30 16:38:30
【问题描述】:

我目前正在使用 Metal 编写一个大型 iOS 8 应用程序。由于缺乏重要的示例,事实证明它非常令人沮丧,而且事实(按设计)与 DirectX 和 OpenGL ES(我都知道)有点不同。

目前,我只能找到使用单个顶点/索引缓冲区然后在着色器中做一些花哨的东西的教程。我想看看如何管理具有不同顶点和着色器制服的多个对象绘制同一帧。

【问题讨论】:

  • 如果 Metal 仍然给您带来麻烦,您可以查看 MetalGL,它是 Metal 中 OpenGL ES API 的实现。它提供了 Metal 的许多性能优势,同时允许您继续使用熟悉的 OpenGL API。使用 OpenGL API 还有助于为您的应用保留平台可移植性。

标签: ios metal


【解决方案1】:

Here 是来自苹果的一个很好的示例,它展示了如何管理不同的对象和多个着色器。这只是一个项目,但也有一个WWDC session,苹果工程师解释了这个项目是如何工作的。

【讨论】:

    【解决方案2】:

    尝试一个用于 iOS 图像和视频处理的有用金属库,称为“MetalImage” 参考github:https://github.com/erickingxu/MetalImage.git

    【讨论】:

      【解决方案3】:

      Here 你会发现我做的一个实现,从不同的来源获取文档。

      我认为这是一个很好的起点。

      基本上你会在这个 Swift 项目中找到:

      • 3D 模型加载、纹理化和渲染。
      • 着色器:顶点、片段和内核。在内核中,我实现了 Loki 用于随机生成颜色。

      【讨论】:

        【解决方案4】:

        要修改RayWenderlich introductory metal tutorial 以将具有不同资源的多个对象绘制到同一帧中,您首先需要为每个对象创建一个单独的 MTLRenderPipelineState(定义着色器等)和 MTLBuffer(定义顶点/索引)。

        然后,您可以遍历 Render Command Encoder 中的对象并绑定唯一对象并在调用 endEncoding() 之前调用 drawPrimitives()

        -在“渲染三角形”部分的第 4 步中:

        let renderEncoderOpt = commandBuffer.renderCommandEncoderWithDescriptor(renderPassDescriptor)
        if let renderEncoder = renderEncoderOpt {
          renderEncoder.setRenderPipelineState(pipelineState)
          renderEncoder.setVertexBuffer(vertexBuffer, offset: 0, atIndex: 0)
          renderEncoder.drawPrimitives(.Triangle, vertexStart: 0, vertexCount: 3, instanceCount: 1)
          renderEncoder.endEncoding()
        }
        

        变成这样:

        let renderEncoderOpt = commandBuffer.renderCommandEncoderWithDescriptor(renderPassDescriptor)
            if let renderEncoder = renderEncoderOpt {
              for drawable in drawables {
                renderEncoder.setRenderPipelineState(drawable.pipelineState)
                renderEncoder.setVertexBuffer(drawable.vertexBuffer, offset: 0, atIndex: 0)
                renderEncoder.drawPrimitives(.Triangle, vertexStart: 0, vertexCount: drawable.vertexCount, instanceCount: 1)
              }
              renderEncoder.endEncoding()
        

        【讨论】:

        • 我已经试过你的例子了。您不能保证对 drawPrimitive 的调用将按照您调用它们的顺序执行。将任何统一信息发送到着色器(我这样做)时,这是一个问题。 AFAIK,如果你想确保正确执行,你必须为每次调用像素着色器创建一个单独的 renderEncoder。
        • 有趣。 . .我从来没有见过顺序改变。你有这方面的来源/例子吗?
        • 只需在循环中添加一个 setVertexBuffer 或 setFragmentBuffer 调用(每个对象使用不同的参数)。你会看到的。
        • DrawPrimitive 将按照您调用它们的顺序执行。您必须记住的是,在 GPU 完成之前,您的顶点缓冲区中的数据无法更改(这可能在 2 帧之后)。如果您更改每个对象的数据,您会看到不可预知的行为,看起来好像渲染顺序正在更改,但事实并非如此。您需要了解 CPU 和 GPU 如何并行工作才能完全理解 Metal。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多