在2019年的WWDC开发者大会上,苹果宣布iOS现在支持HEVC带有Alpha通道,并表示这可以在SceneKit中使用。
我已经尝试了几个小时,但是没有成功。
我的目标是将视频作为SCNNode平面的纹理,并使该平面在视频透明部分也透明。
我使用了苹果在这个xcode项目(2个木偶的视频)中提供的带有HEVC Alpha通道的视频。
我正在使用XCode 11.2在一个运行iOS 13.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:3577: 断言失败 `Fragment Function(FastSingle_FragFunc): 缺少索引为0的sampler绑定,用于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.diffuse.a中。
方法4.使用着色器与SKScene而不是AVPlayer
结果:与方法2相同的错误。
有人知道如何解决这个问题吗?
更新:2020年1月7日
我尝试了不同的方法,使用iOS 13.3和XCode 11.3。 => 相同的结果。
我刚刚向苹果报告了这个问题,感谢@mnuages提供的链接。
更新:2020年3月24日
iOS 13.4发布后,该问题得到了解决。
具有透明度的HEVC视频可以直接在SceneKit中处理,无需操纵材质的透明内容或使用着色器。
SKScene
/SKVideoNode
崩溃似乎只会在场景中仅有视频的情况下出现。我在从苹果的示例代码中简单地删除桥梁背景图像后遇到了这个崩溃。 - Giles