使用光线投射时如何重新着色所有模型的零件?

Posted

技术标签:

【中文标题】使用光线投射时如何重新着色所有模型的零件?【英文标题】:How to recolor all model's parts when using raycasting? 【发布时间】:2022-01-03 13:07:29 【问题描述】:

我在来自 Reality Composer 的 arView 中有一个 fanfare.reality 模型。我通过entity(at:location) 进行光线投射并启用命中对象的ModelDebugOptionsComponent(visualizationMode: .lightingDiffuse),这会使对象的外观变为灰色。但是,我发现只有喇叭本身变成灰色,而喇叭上方的旗帜根本没有改变。

我通过LoadAsync() 加载 fanfare.reality 并打印返回值如下。原因是flag、star和fanfare本身被分成了3个ModelEntity。在 RealityKit 中,raycast 搜索带有CollisionComponent 的实体。只有可以添加到带有ModelComponent 的实体。

因此,我的问题是,当我在屏幕上点击模型(通过光线投射)时,如何将整个现实模型变为灰色(大张旗鼓+旗帜+星号)。

【问题讨论】:

【参考方案1】:

分离零件模型方法

您可以轻松检索所有 3 个模型。但是您必须指定整个长层次路径:

let scene = try! Experience.loadFanfare()

// Fanfare – .children[0].children[0]
let fanfare = scene.children[0] ..... children[0].children[0] as! ModelEntity
fanfare.model?.materials[0] = UnlitMaterial(color: .darkGray)
    
// Flag – .children[1].children[0]
let flag = scene.children[0] ..... children[1].children[0] as! ModelEntity
flag.model?.materials[0] = UnlitMaterial(color: .darkGray)

// Star – .children[2].children[0]
let star = scene.children[0] ..... children[2].children[0] as! ModelEntity
star.model?.materials[0] = UnlitMaterial(color: .darkGray)

.rcproject.reality.usdz 文件中检索模型实体时,我看不出有什么不同。根据打印的图表,所有三个模型实体都位于同一层次结构级别,它们是同一实体的后代。 if statement 中的条件可以设置为最简单的形式——如果射线击中 collision shape 或 fanfare 或 (||) flag 或 (||) star,则所有三个模型必须重新着色。

单模型方法

通过光线投射与 3D 模型交互的最佳解决方案是单模型方法。单一模型是没有单独部分的实体 3D 对象——所有部分都组合成一个整体模型。在 UV 编辑器中,单模型的纹理始终为 mapped。可以在 Maya 或 Blender 等 3D 创作应用程序中制作单模型。


附言

所有经验丰富的 AR 开发人员都知道 哇! AR 体验 不是关于代码,而是关于 3D 内容。您明白,如果您的 3D 模型由许多部分组成,那么简单的解决方案就没有“灵丹妙药”。 在使用代码时,制作精良的 AR 模型的成功率是 75%

【讨论】:

哦!问题是我有很多现实模型,例如crown.realitycard.reality 等。我想以通用方式加载和处理它们。所以我选择使用LoadAsync(URL)而不是Experience.loadFanfare()。此外,我只能检索被射线击中的modelEntityfanfare flagstar 之一)。根据您的方法,我必须找到命中modelEntity(例如大张旗鼓)的父(scene),然后检索其他modelEntity(例如标志,星号)。我理解正确吗? 是的。当模型数量为 1 或 2 时,您提到的方法可以正常工作。但是,如果我有超过 3 个 .reality 模型并且用户可以将它们放置在 arView 中任意次数。首先,我必须为每个.reality 模型进行硬编码。例如,如果用户放置一个fanfare.reality,我必须硬编码以获得fanfare.reality 的几个modelEntityfanfareflagstar)。如果card.reality,得到几个modelEntitycoverbookmark等)的card.reality。如果crown.reality,得到它的headbody。如果有 10 个或更多模型,这是相当多的工作。 因此,问题是当射线击中flag时,我无法提前在同一个.reality模型中获得另一个ModelEntity(fanfare,star),如何通过flag 检索另一个ModelEntity(fanfare, star) 并使它们变为灰色?有没有很好的解决方案? 宝贵意见

以上是关于使用光线投射时如何重新着色所有模型的零件?的主要内容,如果未能解决你的问题,请参考以下文章

2D高度图上的基本(假)光线投射

threejs - 重新定位后使用控制器在 AR 中进行光线投射

如何为光线投射生成相机光线

自定义着色器不接收光线

GLSL 计算着色器闪烁块/正方形伪影

使用光线投射的对象拾取