如何像 AR Quick Look 一样显示接地阴影?

问题描述 投票:0回答:1

在使用

QLPreviewController
显示 .USDZ 模型时,我得到了开箱即用的接地阴影。然而,当我在
ARView
中加载相同的模型时,就没有这样的阴影了。为什么它被隐藏并且可以显示它吗? 或者我必须创建自定义阴影吗?

enter image description here

swift arkit realitykit arquicklook
1个回答
0
投票

类VR AR模式

答案非常明显:由于

ARQuickLook
不允许您自定义场景中的任何内容(它是一个随时可用的解决方案),那么如果您想实现默认情况下在
ARQuickLook
中激活的所有内容(可以是它的碰撞形状、手势、接地阴影、播放动画等)在
ARView
RealityView
中你必须实现这个从头开始。

RealityKit 4.0 (iOS 18.0+) 允许您从接收第一个实体阴影的另一个实体的角度生成

grounding shadows
。在 RealityKit 的早期版本中,您必须为此使用定向灯或聚光灯。

import SwiftUI
import RealityKit

struct ContentView : View {
    var body: some View {
        ARViewContainer().ignoresSafeArea()
    }
}

struct ARViewContainer : UIViewRepresentable {
    let arView = ARView(frame: .zero)
    let anchor = AnchorEntity()
    
    init() {
        arView.environment.lighting.intensityExponent = 1.001
        arView.environment.background = .color(.white)
    }
    func makeUIView(context: Context) -> ARView {
        // Biplane's Entity
        let entity = try! Entity.load(named: "biplane")
        entity.position.y = 0.05
        anchor.addChild(entity)

        // Biplane's ModelEntity
        let model = entity.findEntity(named: "toy_biplane_bind") as! ModelEntity
        model.components[GroundingShadowComponent.self] = 
                                                 .init(castsShadow: true, 
                                                       receivesShadow: false)
        // Shadow plane
        let mesh = MeshResource.generatePlane(width: 0.5,
                                              depth: 0.5,
                                       cornerRadius: 0.25)
        let material = SimpleMaterial()
        let shadowPlane = ModelEntity(mesh: mesh, materials: [material])
        shadowPlane.components[GroundingShadowComponent.self] = 
                                                       .init(castsShadow: false, 
                                                             receivesShadow: true)
        anchor.addChild(shadowPlane)            
        arView.scene.anchors.append(anchor)
        return arView
    }
    func updateUIView(_ view: ARView, context: Context) { }
}

这是某种跟踪的“VR 模式”(摄像头馈送被 ARView 的白色 BG 遮挡)。


AR模式

对于 AR 模式,您可以使用

DirectionalLight
对象和捕捉阴影的非不透明材质,但由于某种原因
OcclusionMaterial
会导致表面“曝光过度”。我希望这个bug能够在未来的版本中得到修复。很可能有一些参数可以消除平面的“过度曝光的表面”效果,但我还没有找到。

struct ARViewContainer : UIViewRepresentable {
    let arView = ARView(frame: .zero)
    let anchor = AnchorEntity()

    func makeUIView(context: Context) -> ARView {
        // Biplane's Entity
        let entity = try! Entity.load(named: "biplane")
        entity.position.y = 0.05
        anchor.addChild(entity)
        
        // Light
        let sun = DirectionalLight()
        sun.shadow = .init()
        sun.light.intensity = 4000
        sun.light.color = .white
        sun.orientation = .init(angle: -.pi/2, axis: [1,0,0])
        anchor.addChild(sun)
        
        // Shadow plane
        let mesh = MeshResource.generatePlane(width: 0.5,
                                              depth: 0.5,
                                       cornerRadius: 0.25)

        let material = OcclusionMaterial(receivesDynamicLighting: true)  // !!!
        
        let shadowPlane = ModelEntity(mesh: mesh, materials: [material])
        anchor.addChild(shadowPlane)
        
        arView.scene.anchors.append(anchor)
        return arView
    }
    func updateUIView(_ view: ARView, context: Context) { }
}
© www.soinside.com 2019 - 2024. All rights reserved.