问题标签 [metalkit]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
ios - Metal / UIKit 与 .presentsWithTransaction 同步
Apple 文档CAMetalLayer
声明该属性为presentsWithTransaction
:
一个布尔值,用于确定图层是否使用核心动画事务呈现其内容
由于我正在使用 UIKit 来驱动一些金属动画(类似于 Apple 在此WWDC 2012 会话中为 OpenGL 建议的方法),我假设这是启用它的正确时间。我有一个金属“背景”视图,上面覆盖着一些 UIKit 组件(它们也是动画),所以这听起来很像适用的用例:
默认情况下 [
.presentsWithTransaction
] 为 false:CAMetalLayer
尽可能快地将渲染过程的输出显示到显示器,并且与任何 Core Animation 事务异步。但是,如果您的游戏或应用程序结合了 Metal 和 Core Animation 内容,则不能保证您的 Metal 内容将与您的 Core Animation 内容在同一帧中到达。例如,如果您的应用程序在您的顶部绘制 UIKit 内容(例如带有目标位置和时间的标签)CAMetalLayer
并且两个域需要同步,这可能是一个问题。
当然,如果没有启用该设置,滚动会显得生涩。presentsWithTransaction
启用后,我取得了一些有限的成功,但我在启用设置的情况下尝试的两条路线都不是完美的。
我尝试的第一种方法遵循文档中的说明presentsWithTransaction
。因此,在我的内部,MTKViewDelegate
我有以下方法:
这大部分工作正常 - 但完全离开设置也是如此。它有在某些点不同步的趋势,导致通过UIScrollView
例如驱动滚动动画的特征性颤抖。的整个想法presentsWithTransaction
是为了避免这种情况,所以也许我在这里做错了什么。
第二种方法利用addScheduledHandler
命令缓冲区:
这种方法似乎保持同步,但会导致一些可怕的 CPU 挂起(2 秒或更长时间),尤其是当应用程序在后台后变为活动状态时。
有什么办法可以两全其美?
编辑:2018 年 12 月 9 日: 虽然上面描述的第一种方法似乎是优先的,但如果主线程上的 CPU 使用率出现峰值,它仍然会导致频繁的去同步——这在大多数情况下是不可避免的。
当绘制循环变得缺乏可绘制对象时,您可以判断何时发生这种情况。这会产生连锁效应,这意味着下一帧的可绘制对象也会被延迟。在 Metal Instruments 面板中,这会导致一系列“线程阻塞等待下一个可绘制”警告。
在上面的设计中,由于 Metal 在等待可绘制对象时被阻塞 - 主线程也是如此。现在,触摸事件变得延迟,导致平移手势出现明显的断断续续模式——即使应用程序理论上仍以 60 fps 的速度运行,阻塞似乎会影响报告触摸事件的节奏——从而导致抖动效果。
随后的 CPU 峰值可能会使事情恢复正常,应用程序将开始正常运行。
编辑:2018 年 12 月 10 日: 这是一个演示该问题的小示例项目。创建一个新的 Xcode 项目,复制并粘贴两个 swift 文件的内容(为金属着色器文件添加一个新文件)并在设备上运行:
https://gist.github.com/tcldr/ee7640ccd97e5d8810af4c34cf960284
swift - 什么会导致重复调用 MetalKit MTKView 的 draw() 函数时出现延迟
我正在使用适用于 macOS 10.13 的 swift 4.0 MetalKit API 设计一个 Cocoa 应用程序。我在这里报告的所有内容都是在我的 2015 MBPro 上完成的。
我已经成功实现了一个 MTKView,它可以很好地呈现具有低顶点数的简单几何图形(立方体、三角形等)。我实现了一个基于鼠标拖动的相机,它可以旋转、扫视和放大。这是我旋转立方体时 xcode FPS 调试屏幕的屏幕截图:
但是,当我尝试加载仅包含约 1500 个顶点的数据集(每个顶点存储为 7 x 32 位浮点数......即:总共 42 kB)时,我开始在 FPS 中遇到非常糟糕的延迟。我将在下面展示代码实现。这是一个屏幕截图(请注意,在此图像上,视图仅包含一些顶点,这些顶点被渲染为大点):
这是我的实现:
1) viewDidLoad() :
2) 为 Cube 顶点加载 MTLBuffer :
3) 为数据集顶点加载 MTLBuffer。请注意,我明确将此缓冲区的存储模式声明为私有,以确保 GPU 有效访问数据,因为一旦加载缓冲区,CPU 就不需要访问数据。另外,请注意,我只加载了实际数据集中 1/100 的顶点,因为当我尝试完全加载它时,我机器上的整个操作系统开始滞后(只有 4.2 MB 的数据)。
4) 最后,这里是渲染循环。同样,这是使用 MetalKit。
好的,这些是我试图找出导致滞后的原因的步骤,请记住滞后效应与数据集顶点缓冲区的大小成正比:
我最初认为这是由于 GPU 无法足够快地访问内存,因为它处于共享存储模式 -> 我将数据集 MTLBuffer 更改为私有存储模式。这并没有解决问题。
然后我认为问题是由于 CPU 在我的 render() 函数中花费了太多时间。这可能是由于 BufferProvider 的问题,或者可能是因为 CPU 试图以某种方式每帧重新处理/重新加载数据集顶点缓冲区 -> 为了检查这一点,我在 xcode 的 Instruments 中使用了 Time Profiler。不幸的是,问题似乎是应用程序很少调用这个渲染方法(换句话说,MTKView 的 draw() 方法)。以下是一些截图:
- 大约 10 秒的峰值是加载多维数据集时
- ~25-35 秒之间的峰值是加载数据集时
- 这张图片 (^) 显示了加载多维数据集后大约 10-20 秒之间的活动。这是 FPS 大约为 60 的时候。您可以看到,在这 10 秒内,主线程在 render() 函数中花费了大约 53 毫秒。
- 这张图片 (^) 显示了大约 40-50 秒之间的活动,就在加载数据集之后。这是 FPS < 10 的情况。您可以看到,在这 10 秒内,主线程在 render() 函数中花费了大约 4 毫秒。如您所见,通常在此函数中调用的方法都没有被调用(即:我们可以看到仅在加载多维数据集时调用的方法,上一个图像)。值得注意的是,当我加载数据集时,时间分析器的计时器开始跳转(即:它停止几秒钟,然后跳转到当前时间......重复)。
所以这就是我所在的地方。问题似乎是 CPU 不知何故被这些 42 kB 的数据超载......递归。我还用 xcode 的 Instruments 中的分配器进行了测试。据我所知,没有内存泄漏的迹象(您可能已经注意到其中很多对我来说是新的)。
抱歉,这篇文章令人费解,我希望它不会太难理解。预先感谢大家的帮助。
编辑:
这是我的着色器,以防你想看到它们:
ios - 在 MTKView 中如何获取 3D (x,y,z) 中给定点的像素信息(RGB 和 Alpha 值)?
好的,我们已经在 a 中绘制了几个东西MTKView
我们可以使用 Metal、MetalKit 函数移动和转动它们,但是我们无法获得 3D (x,y,z) 中给定点的像素信息。我们搜索了几个小时,但找不到任何解决方案。
xcode8 - SceneKit PBR - 真实感
是否可以使用 SceneKit 获得与 Unreal Engine 4 相同水平的照片级真实感?在 SceneKit 或 Metal2 上有哪些照片写实的例子?
ios - 在 MTKView 上渲染 MTLTexture 没有保持纵横比
我有一个 1080x1920 像素的纹理。而且我正在尝试以MTKView
不同的纵横比渲染它。(即 iPad/iPhone X 全屏)。
这就是我渲染纹理的方式MTKView
:
我希望.scaleAspectFill
在 a上渲染纹理UIView
并且我正在尝试学习Metal
,所以我不确定我应该在哪里寻找这个(.metal
文件、管道、视图本身、编码器等)
谢谢!
编辑:这是着色器代码:
swift - [[stage_in]]、MTLVertexDescriptor 和 MTKMesh 之间的连接
之间有什么联系:
[[stage_in]]
在金属着色器中使用- 使用
MTLVertexDescriptor
- 使用
MTKMesh
例如
[[stage_in]]
不使用就可以使用MTLVertexDescriptor
吗?- 是否可以在不使用的
MTLVertexDescriptor
情况下使用MTKMesh
,但可以使用基于自定义结构的数据结构的数组?比如struct Vertex {...}, Array<Vertex>
? MTKMesh
不使用就可以使用MTLVertexDescriptor
吗?例如使用相同的基于结构的数据结构?
我没有在互联网上找到这些信息,而且金属着色语言规范甚至不包括“描述符”或“网格”这两个词。
ios - Swift 中的跨平台代码共享
我有一个从 Xcode 9 / New Project / Cross Platform Game App 创建的应用程序,目标:macOS 和 iOS。
我编写了以下简单函数来从数据资产加载文本。
我对以下事情感到困惑:
- 此功能仅在我导入 UIKit 或 AppKit 时才有效。
- 但是以某种方式导入 MetalKit 而不是 UIKIt 或 AppKit 使其工作。这真的让我很困惑。这应该与 MetalKit 无关。
我为 iOS 和 macOS 之间的代码共享找到的大多数答案都建议在文件/填充的开头进行某种条件导入。
我浏览了WWDC 2014 Session 233: Sharing code between iOS and OS X的幻灯片,它明确表示我们不应该在 Swift 中做 shimming。
另一方面,我不明白我们应该做什么来代替匀场。上面提到的为 5 行函数创建和编译共享框架的非常复杂的过程不可能是正确的方向。
在 2018 年(Swift 4、Xcode 9、iOS 11、macOS 10.13),将这样一个微不足道的跨平台代码添加到应用程序的推荐方法是什么?
MetalKit 的魔力是什么,它可以在没有垫片的情况下工作?它在内部填充吗?
xcode8 - Xcode Model I/O - 从 Marmoset 导入自定义着色器
Apple Model I/o 文档的手风琴:
块报价
您可以使用此框架从流行的创作工具和游戏引擎支持的各种行业标准文件格式导入和导出资产。
块报价
和
块报价
描述真实的渲染参数。MDLPhysicallyPlausibleScatteringFunction 类(描述与网格关联的 MDLMaterial 对象的表面外观的多种方法之一)定义了使用流行电影和高端游戏引擎中相同的基于物理的着色系统的表面的预期渲染。MDLPhotometricLight 和 MDLPhysicallyPlausibleLight 类描述了用于渲染的真实光照属性,并且 MDLCamera 类还支持基于物理的渲染参数。
块报价
那么,是否可以导入在 Marmoset 中创建的自定义 PBR 着色器?
如果是,我该怎么做?
谢谢
image-processing - 使用 Swift 4 在 Metal Compute Kernel 中传递参数
在 CPU 方面,我有一个要传递给计算内核的结构:
在运行内核之前,我将数据传递给 MTLComputeCommandEncoder:
选项 1(直接):
选项 2(间接通过 MTLBuffer):
如果结构中存在“dummy”变量,则任一选项都可以正常工作,但如果“dummy”变量不存在则失败。代码调用失败:
出现错误:
在金属内核方面,以下是相关的代码片段:
尝试将 3x3 矩阵传递给另一个计算内核时,我也遇到了类似的问题。它抱怨提供了 36 个字节,但预期为 48 个。
有人对这个问题有任何想法吗?