You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将SCNPlane设为透明背景且保留波纹动画?

解决ARKit中SCNPlane背景透明仅显示波纹动画的问题

嗨,我来帮你搞定这个问题!你现在的困境是直接调整材质透明度会把波纹动画也一起隐藏,其实核心是要让材质只识别UIView中有内容的部分(也就是波纹),而忽略透明背景。咱们可以通过这几步调整来实现你要的效果:

  • 第一步:把承载动画的UIView背景设为透明
    你之前把myUIView.backgroundColor设为了红色,这会让整个UIView有不透明的底色。改成.clear后,UIView本身就是完全透明的,只有你添加的波纹动画图层会有颜色。

  • 第二步:配置SCNMaterial的透明度模式
    默认的材质透明度会影响整个内容,咱们需要把材质的transparencyMode设置为.aOne,这样材质会根据内容的alpha通道来显示——只有UIView中alpha值不为0的部分(也就是波纹)会被渲染,透明背景会被忽略。同时可以开启isDoubleSided,避免从某些角度看不到波纹。

  • 第三步:确保波纹动画本身的背景透明
    如果你的波纹是用CAShapeLayer或者其他图层实现的,要保证这些图层的backgroundColor也是透明的,只给波纹路径设置颜色。如果是用序列帧图片,也要确保图片的背景是透明的PNG格式。

下面是修改后的代码,我标出来了关键调整点:

let location = tapGesture.location(in: self.sceneView) 
let results = self.sceneView.hitTest(location, types: .existingPlane) 
if !results.isEmpty{ 
    guard let result = results.first else{ return } 
    
    let myUIView = UIView(frame: CGRect(origin: .zero, size: CGSize(width: 300, height: 300))) 
    myUIView.backgroundColor = .clear // 关键:UIView背景设为透明
    
    // --- 这里添加你的波纹动画代码 ---
    // 示例:比如用CAShapeLayer创建波纹
    let rippleLayer = CAShapeLayer()
    rippleLayer.path = UIBezierPath(ovalIn: CGRect(x: 50, y: 50, width: 200, height: 200)).cgPath
    rippleLayer.strokeColor = UIColor.blue.cgColor
    rippleLayer.fillColor = UIColor.clear.cgColor // 波纹填充透明,只显示边框
    rippleLayer.lineWidth = 3
    myUIView.layer.addSublayer(rippleLayer)
    // 添加缩放动画
    let scaleAnim = CABasicAnimation(keyPath: "transform.scale")
    scaleAnim.fromValue = 1.0
    scaleAnim.toValue = 2.0
    scaleAnim.duration = 1.5
    scaleAnim.repeatCount = .infinity
    rippleLayer.add(scaleAnim, forKey: "rippleScale")
    // --- 波纹动画代码结束 ---
    
    let plane = SCNPlane(width: 1.0, height: 1.0) 
    let material = SCNMaterial()
    material.diffuse.contents = myUIView
    material.isDoubleSided = true // 可选:保证从任意角度可见
    material.transparencyMode = .aOne // 关键:基于内容alpha通道渲染
    plane.materials = [material] // 替换原firstMaterial的设置
    
    let planeViewNode = SCNNode(geometry: plane) 
    planeViewNode.eulerAngles.x = Float(-Double.pi / 2) 
    planeViewNode.position = SCNVector3(result.worldTransform.columns.3.x, result.worldTransform.columns.3.y, result.worldTransform.columns.3.z) 
    self.sceneView.scene.rootNode.addChildNode(planeViewNode) 
}

这样调整后,SCNPlane的背景会完全透明,只有波纹动画会显示在平面上,和你提到的BBC《文明》AR应用的效果一致。

内容的提问来源于stack exchange,提问作者Hari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 03:59:08