如何在场景套件中使用"HEVC with Alpha channel"视频?



在WWDC 2019上,苹果宣布目前正在iOS中使用Alpha处理HEVC,并表示它可以在SceneKit中使用。

我已经努力了好几个小时,但没有任何运气。

我的目标是将视频用作SCNNode平面上的纹理,并在视频透明的地方使该平面透明。

我在这个xcode项目中使用了苹果公司提供的带有Alpha的HEVC视频(带有2个木偶的视频(。

我正在iOS 13.2的真实设备上使用XCode 11.2进行开发。

我尝试了不同的方法。

方法1。使用AVPlayer作为SCNNode材质的漫反射+透明内容

let videoURL = Bundle.main.url(forResource: “puppets_with_alpha_hevc“, withExtension: "mov", subdirectory: "Assets.scnassets");
let player = AVPlayer(url: videoURL! as URL)
let material = SCNMaterial()
material.diffuse.contents = player
material.transparent.contents = player
plane?.geometry?.materials = [material];
player.play();

结果:视频使用黑色像素而不是透明像素进行渲染。

方法2。将AVPlayer嵌入到SKVideoNode中,然后将SKVideoNode嵌入到SKScene中,并将SKScene用作我的SCNNode的材质的漫反射+材质内容

这似乎是在SceneKit中将视频显示为素材的常见方式。此外,在苹果公司提供的关于如何渲染"具有alpha的HEVC视频"的示例中,他们使用了SKVideoNode(但不在SceneKit上下文中(。

let videoNode = SKVideoNode(avPlayer: player)
let spritescene = SKScene(size: CGSize(width: 360, height: 480))
let spriteKitScene = SKScene(size: CGSize(width: 360.0 / 2.0, height: 480.0 / 2.0))
spriteKitScene.scaleMode = .aspectFit
videoNode.position = CGPoint(x: spriteKitScene.size.width / 2.0, y: spriteKitScene.size.height / 2.0)
videoNode.size = spriteKitScene.size
spriteKitScene.addChild(videoNode)
let material = SCNMaterial()
material.diffuse.contents = spriteKitScene
material.transparent.contents = spriteKitScene
plane?.geometry?.materials = [material];

结果:获得此崩溃:

validateFunctionArguments:3357:断言失败`Fragment函数(FastSingle_FragFunc(:在的索引0处缺少采样器绑定u_texture_sampler[0]。'

注意:当我使用没有alpha通道的常规HEVC视频时,我不会出现此错误。

方法3。使用材质着色器将alpha值从视频复制到材质的透明贴图

let material = SCNMaterial()
material.diffuse.contents = player
material.shaderModifiers = [
SCNShaderModifierEntryPoint.surface :  "_surface.transparent.a = _surface.diffuse.a;"
];
plane?.geometry?.materials = [material];

结果:视频使用黑色像素而不是透明像素进行渲染。阿尔法信息似乎不在_surface.diff.a

方法4。将着色器用于SKScene而不是AVPlayer

结果:与方法2的错误相同。

有人知道怎么做吗?

更新:2020年1月7日,星期二

我在iOS 13.3和XCode 11.3上尝试了不同的方法。=>结果相同。

我刚刚向苹果公司报告了这个错误,谢谢你的链接@mlanguages。

更新:2020年3月24日,星期二

iOS 13.4的发布解决了这个问题。

在SceneKit中直接考虑具有透明度的HEVC视频,而不必干扰材质的透明内容或着色器。

第一段代码应该可以工作(无需设置transparent材质属性(。如果你在macOS SceneKit游戏模板中进行以下更改,你会得到正确的结果,但它不适用于iOS SceneKit的游戏模板。

// retrieve the ship node
let ship = scene.rootNode.childNode(withName: "ship", recursively: true)!
let videoURL = Bundle.main.url(forResource: "puppets_with_alpha_hevc", withExtension: "mov", subdirectory: "art.scnassets");
let player = AVPlayer(url: videoURL! as URL)
let material = SCNMaterial()
material.diffuse.contents = player
player.play();
ship.enumerateHierarchy { (node, _) in
if let geometry = node.geometry {
geometry.materials = [material];
}
}

在这种情况下,人们可能想为iOS版本提交一个bug以进行修复。

最新更新