Я новичок в металле. Я визуализирую сцену SceneKit с помощью Metal, используя этот пример кода Apple. TL; DR; он вызывает функцию SCNRenderer's
render
и передает буфер команд. Я собираю для Биг Сур.
Работает, но не сглаживается. Я пробовал несколько способов добиться этого, как вы можете видеть в обновлениях ниже.
Без Металла я бы просто установил isJitteringEnabled
в true
на SCNRenderer, и я получил бы красивые (и медленные) 96-проходные рендеры. Если я попытаюсь сделать это с помощью Metal, я получу странное несоответствие формата пикселей, поэтому я подозреваю, что они просто несовместимы.
С помощью Metal, насколько я могу судить, самый простой способ добиться сглаживания - включить множественную выборку в конвейере рендеринга (я знаю, как это сделать) - и использовать текстуру множественной выборки (MTLTextureType.type2DMultisample
). Этот частичный ответ подтверждает мое предположение.
И вот в чем проблема. Я не знаю, как изменить тип текстуры, когда я получаю текстуру от CVMetalTextureCache
и CVMetalTextureCacheCreateTextureFromImage
. Кажется, это ограничение в поддержке Metal в Core Video?
Мой полный источник здесь
Вот и все. Остальная часть этого поста - это более подробная информация о том, что я пробовал.
(Я думаю, что это возможно с помощью шейдера. Я тоже открыт для этого решения, но не знаю, с чего начать. Этот пример не компилируется, и этот пример предназначен для GSLS)
Мои пиксельные буферы выглядят так
let pixelbufferAttributes = [
kCVPixelBufferPixelFormatTypeKey : kCVPixelFormatType_32BGRA,
kCVPixelBufferWidthKey: exportSettings.width,
kCVPixelBufferHeightKey : exportSettings.height,
kCVPixelBufferMetalCompatibilityKey: true] as [String: Any]
Для каждого кадра он создает новый буфер пикселей из пула, обертывает его текстурой Metal из кеша, как это
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
с CVMetalTextureCacheCreateTextureFromImage
, я не могу понять, как установить ее атрибуты и сделать это мультисэмплом.
Попытка: попробуйте H264
Ничего не менял. Также попытался изменить только качество альфа, с HEVC с альфа, но без изменений.
Попытка: включить множественную выборку
Мне удалось заставить свой конвейер понять, что мне нужна множественная выборка, но он вылетает из-за того, что текстура не настроена для мультисэмплинга (точнее, MTLTexture типа .2DMultisample
(docs)
Попытка: скопировать MTLTexture
, созданный Core Video
Я попытался использовать MTLBlitCommandEncoder
, чтобы скопировать текстуру, которую мне дал Core Video, в текстуру, которую я настроил с правильными атрибутами. Но он вылетает, говоря мне, что атрибуты не совпадают.
Я начинаю думать, что здесь нет решения?