我是金属新手。我正在使用 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 提供的纹理复制到我使用正确属性设置的纹理中。但它崩溃告诉我属性不匹配。
我开始觉得这个问题没有解决办法吗?