使用 Metal 对 SceneKit 渲染进行抗锯齿处理

2024-01-03

我是金属新手。我正在使用 Metal 渲染 SceneKit 场景这个苹果示例代码 https://developer.apple.com/documentation/avfoundation/media_playback_and_selection/using_hevc_video_with_alpha。太长了;它称为SCNRenderer's render函数并传入命令缓冲区。我正在为大苏尔编译。

它可以工作,但不能消除锯齿。我尝试了几种方法来实现它,正如您在下面的更新中看到的那样。

没有金属,我只需设置isJitteringEnabled to true在 SCNRenderer 上,我得到了漂亮(且缓慢)的 96 遍渲染。如果我尝试使用 Metal 执行此操作,则会出现奇怪的像素格式不匹配的情况,因此我怀疑两者不兼容。

据我所知,对于 Metal,实现抗锯齿的最简单方法是在渲染管道中启用多重采样(我知道该怎么做) -and使用多重采样纹理(MTLTextureType.type2DMultisample). 这部分答案 https://developer.apple.com/forums/thread/667558?answerId=648944022#648944022支持我的假设。

这就是问题所在。当我从以下位置获取纹理时,我不知道如何更改纹理类型CVMetalTextureCache and CVMetalTextureCacheCreateTextureFromImage。这似乎是 Core Video 的 Metal 支持的限制?

My full 来源在这里 https://github.com/mortenjust/hevc-with-alpha/blob/main/HEVC-Videos-With-Alpha-AssetWriting/HEVC-Videos-With-Alpha-AssetWriting/AppDelegate.swift#L47

就是这样。这篇文章的其余部分是关于我尝试过的东西的更多细节。

(我认为使用着色器可能可以实现这一点。我也愿意接受该解决方案,但我不知道从哪里开始。这个例子 https://metashapes.com/blog/anti-aliasing-shaders/不编译,并且这个例子 https://developer.apple.com/forums/thread/25443适用于 GSLS)


我的像素缓冲区 atts 看起来像这样

        let pixelbufferAttributes = [
            kCVPixelBufferPixelFormatTypeKey : kCVPixelFormatType_32BGRA,
            kCVPixelBufferWidthKey: exportSettings.width,
            kCVPixelBufferHeightKey : exportSettings.height,
        kCVPixelBufferMetalCompatibilityKey: true] as [String: Any]

对于每一帧,它从池中创建一个新的像素缓冲区,将其包装在缓存中的金属纹理中,如下所示

        let pixelFormat = MTLPixelFormat.bgra8Unorm_srgb
        var optionalMetalTexture: CVMetalTexture?
        err = CVMetalTextureCacheCreateTextureFromImage(
            kCFAllocatorDefault,
            metalTextureCache, // object prop
            pixelBuffer,
            nil, // texture attributes
            pixelFormat,
            exportSettings.width,
            exportSettings.height,
            0, // planeIndex
            &optionalMetalTexture)
        guard err == noErr, let metalTexture = optionalMetalTexture else {
            fatalError("Failed to create metal texture wrapper from pixel bufffer \(err)")
        }

尝试:更改纹理描述符

因为我是从创建我的金属纹理CVPixelbuffer with CVMetalTextureCacheCreateTextureFromImage,我不知道如何设置它的属性并使其成为多样本。

尝试:尝试H264

没有改变任何东西。还尝试仅更改 Alpha 质量,使用带有 Alpha 的 HEVC,但没有任何变化。

尝试:启用多重采样

我能够让我的管道识别出我想要多重采样,但由于没有为多重采样设置纹理(更准确地说是 MTLTexture 类型),它崩溃了.2DMultisample (docs https://developer.apple.com/documentation/metal/mtltexturetype/type2dmultisample)

尝试:复制MTLTexture由核心视频创建

我尝试使用MTLBlitCommandEncoder将 Core Video 提供的纹理复制到我使用正确属性设置的纹理中。但它崩溃告诉我属性不匹配。

我开始觉得这个问题没有解决办法吗?


启用多重采样是正确的想法。 以下补丁显示了如何启用它。

--- a/HEVC-Videos-With-Alpha-AssetWriting/HEVC-Videos-With-Alpha-AssetWriting/AppDelegate.swift
+++ b/HEVC-Videos-With-Alpha-AssetWriting/HEVC-Videos-With-Alpha-AssetWriting/AppDelegate.swift
@@ -32,6 +32,8 @@ class AppDelegate: NSObject, NSApplicationDelegate, SCNSceneRendererDelegate {
     let renderer = SCNRenderer(device: nil, options: nil)
     var lampMaterials: SCNNode!
     var metalTextureCache: CVMetalTextureCache!
+    let msaaSampleCount = 1
+    var metalMultisampledTexture: MTLTexture!
     
     // Export
     var frameCounter = 0
@@ -61,6 +63,18 @@ class AppDelegate: NSObject, NSApplicationDelegate, SCNSceneRendererDelegate {
             fatalError("Cannot create metal texture cache: \(err)")
         }
         metalTextureCache = optionalMetalTextureCache
+        
+        if (msaaSampleCount > 1) {
+            let textureDescriptor = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: MTLPixelFormat.bgra8Unorm_srgb,
+                                                                             width: ExportSettings.width,
+                                                                             height: ExportSettings.height,
+                                                                             mipmapped: false)
+            textureDescriptor.usage = .renderTarget
+            textureDescriptor.storageMode = .private
+            textureDescriptor.textureType = .type2DMultisample
+            textureDescriptor.sampleCount = msaaSampleCount
+            metalMultisampledTexture = renderer.device!.makeTexture(descriptor: textureDescriptor)
+        }
     }
     
     /// Render next frame and call the frame completion handler
@@ -106,7 +120,14 @@ class AppDelegate: NSObject, NSApplicationDelegate, SCNSceneRendererDelegate {
         let renderPassDescriptor = MTLRenderPassDescriptor()
         renderPassDescriptor.colorAttachments[0].loadAction = .clear
         renderPassDescriptor.colorAttachments[0].clearColor = clearColor
-        renderPassDescriptor.colorAttachments[0].texture = CVMetalTextureGetTexture(metalTexture)
+        if (msaaSampleCount > 1) {
+            renderPassDescriptor.colorAttachments[0].texture = metalMultisampledTexture
+            renderPassDescriptor.colorAttachments[0].resolveTexture = CVMetalTextureGetTexture(metalTexture)
+            renderPassDescriptor.colorAttachments[0].storeAction = .multisampleResolve
+        }
+        else {
+            renderPassDescriptor.colorAttachments[0].texture = CVMetalTextureGetTexture(metalTexture)
+        }
         renderer.render(atTime: currentPresentationTime.seconds,
                         viewport: ExportSettings.viewport,
                         commandBuffer: commandBuffer,

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Metal 对 SceneKit 渲染进行抗锯齿处理 的相关文章

  • 具有多重采样的金属离屏绘图

    如何将图元渲染到离屏纹理中 而不是直接渲染到屏幕中 我有一组三角形和相应的颜色 我只想像在屏幕上一样绘制它们 但是绘制到屏幕外纹理中 我可以将其保存到文件中 有人可以给我看一个代码示例吗 好吧 我自己意识到了 这段代码完成了这项工作 唯一的
  • JavaFX 偶发渲染问题 - 按钮/控件消失

    我有一个 Java JavaFX 应用程序部署为 Windows 和 Mac 的本机安装 目前捆绑的运行时间为 8 121 您可以在此处找到安装程序和 Java 代码 乔治下载 http www george andante no down
  • 测量服务器请求后 JSF 视图的呈现时间

    我想测量 JSF 应用程序的渲染时间 由于我的权力原因 应用程序无法填充日志 因此 我的问题是 有什么方法可以在使用任何浏览器执行包括后端 服务器 调用的特定操作后测量应用程序的渲染时间 到目前为止 在使用 Chrome 开发者工具后 我发
  • Chrome SVG 网络字体在选择输入中出现奇怪的字符

    Windows 8 上的 Chrome 26 0 1410 64m 在渲染 WebFonts 时出现问题 这是一个已知问题 解决方案是首先提供字体的 svg 版本而不是 woff 版本 它修复了抗锯齿并使字体看起来再次漂亮 此方法的缺点是选
  • 在 Metal Shading Language 中创建全局可访问的常量缓冲区

    我有一个关于 Metal 中的常量缓冲区的问题 假设我有类似的东西 list of includes goes here using namespace metal struct ConstantBuffer float ANY VALUE
  • 自定义 Symfony2 中选择/实体字段的呈现

    我想要一个
  • 难以从 iPhone X 上的 2D 区域获取面部标志点的深度(SceneKit/ARKit 应用程序)

    我正在使用 iPhone X 上的前置摄像头运行面部标志检测 并且正在努力获取面部标志的 3D 点 VNFaceLandmarkRegion2D 仅提供图像坐标 X Y 我一直在尝试使用ARSCNView hitTest or ARFram
  • iOS 14/Xcode 12.0.1 更新后 UIPickerView 渲染不正确

    有人注意到应用程序 UIPickerViews 中的文本渲染不正确 第一个字符被截断吗 我在多个设备上的应用程序的所有 UIPickerViews 中看到了这一点 在大多数情况下 您可以看到第一个字符的几个像素 我尝试过从手机中删除派生数据
  • 将 SceneKit 对象放置在 SCNCamera 当前方向的前面

    我想在用户点击屏幕时创建一个新的 SceneKit 节点 并让它以设定的距离直接出现在相机前面 为了测试 这将是一个 SCNText 读取 您点击此处 它还应该与视线成直角 即 面向 相机 所以 鉴于self camera orientat
  • 高效地将 Swift Array 复制到 iOS Metal 的内存缓冲区

    我正在使用 Apple 的新 Metal 框架编写 iOS 应用程序 我有一个 Matrix4 对象数组 请参阅Ray Wenderlich 的教程 http www raywenderlich com 81399 ios 8 metal
  • SceneKit 修改 3D 对象并导出文件

    在我的应用程序中 我使用 SceneKit Framework 在 SCNView 中显示 3D 对象 并导出修改后的文件 并进行一些小的更改 如颜色 温度等 但在将其导出到文档文件夹后 我得到了原始文件 在这里我可以显示 3D 对象并对其
  • 如何旋转 SCNBox

    我正在尝试旋转SCNBox我创建使用swipe gestures 例如 当我向右滑动时 该框应旋转 90 度Y axis当我向左滑动时为 90degs 为了实现这一点 我一直在使用节点的SCNAction rotateByX方法来执行旋转动
  • 更新属性包装器(如 @StateObject)会影响不使用该属性的其他视图渲染

    当使用与视图更新关联的不同属性包装器时 一处的更改会影响不使用该属性的视图的呈现 struct ContentView View StateObject var viewModel MyViewModel State var thirdTi
  • 如何获取相机相对于其方向的 SCNVector3 位置 ARKit Swift

    我试图在相机前面附加一个对象 但问题是它始终与初始相机方向相关 我如何调整 获取SCNVector3即使相机的方向是向上还是向下 将物体放在前面的位置 我现在就是这样做的 let ballShape SCNSphere radius 0 0
  • 在球体表面SceneKit上写入文本?

    我想知道是否有一种方法可以在 SceneKit 中沿着球体对象的表面写入文本 我知道如果我有图像 我可以在表面上放置纹理并实现这种效果 但我想知道是否可以在球体表面以某种方式动态添加文本 任何想法 EDIT 这有效 let layer CA
  • 测量渲染时间的工具

    是否有工具可以测量页面上元素的实际渲染时间 我指的不是资源的下载时间 而是浏览器渲染某些内容所花费的实际时间 我知道这个时间会根据客户端计算机上的因素而有所不同 但对于了解渲染引擎需要一段时间加载的内容仍然非常方便 我想这应该是一个有用的实
  • 在哪里指定图像尺寸以实现最快渲染:在 HTML 中还是在 CSS 中?

    我了解到 明确指定图像尺寸是最佳实践 然后 浏览器可以在仍然下载图像本身的同时布局页面 从而缩短 感知的 页面渲染时间 这是真的 如果是这样 在 HTML 或 CSS 中指定尺寸是否有区别 HTML img src width 200 he
  • SceneKit unproject Z 文档解释?

    我正在经历一些 SceneKit 概念 而我试图在脑海中巩固的一个概念是 unprojectPoint 我知道该函数将获取 2D 中的一个点并返回 3D 中的一个点 因此具有正确的 Z 值 当我阅读文档时 我读到了以下内容 method u
  • 如何改善 ARKit 3.0 中的人物遮挡

    我们正在开发一个使用 ARKit 中的人物遮挡的演示应用程序 因为我们想在最终场景中添加视频 所以我们使用SCNPlanes 使用 a 渲染视频SCNBillboardConstraint以确保他们面向正确的方向 这些视频也是部分透明的 使
  • Metallib:读取模块时出错:无效的位码签名

    我有以下 Filter metal 文件 include

随机推荐