[At WWDC 2019, Apple announced that it was now handling HEVC with Alpha in iOS,并声明可以在SceneKit中使用它。
我已经尝试了好几个小时才能做到这一点,没有任何运气。
我的目标是将视频用作SCNNode平面上的纹理,并在视频透明的地方使该平面透明。
我使用HEVC和Apple在this xcode project中提供的Alpha视频(带有2个木偶的视频)。
[我正在使用iOS 13.2在真实设备上使用XCode 11.2开发]
我尝试了不同的方法。
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();
结果:视频以黑色像素而不是透明像素呈现。
这似乎是在SceneKit中将视频显示为素材的一种常见方法。另外,在the example provided by apple中,有关如何使用“ 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:失败的断言片段函数(FastSingle_FragFunc):缺少在索引0处的采样器绑定u_texture_sampler [0]。'
注意:使用不带Alpha通道的常规HEVC视频时,不会出现此错误。
let material = SCNMaterial()
material.diffuse.contents = player
material.shaderModifiers = [
SCNShaderModifierEntryPoint.surface : "_surface.transparent.a = _surface.diffuse.a;"
];
plane?.geometry?.materials = [material];
结果:视频以黑色像素而不是透明像素呈现。 Alpha信息似乎不在_ surface.diffuse.a
中结果:与方法2相同的错误。
有人知道如何进行这项工作吗?
我在iOS 13.3和XCode 11.3中尝试了不同的方法。=>结果相同。
我刚刚将错误报告给了Apple,感谢@mnuages的链接。
此问题已在iOS 13.4发行版中修复。
HEVC具有透明性的视频会在SceneKit中立即得到考虑,而无需弄乱材质的透明内容或着色器。
第一个代码段应该起作用(无需设置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];
}
}
这种情况下,可能需要file a bug来修复iOS版本。