我试图通过SceneKit和Model I/0在.obj 3d模型上应用.mtl文件纹理.
当我尝试在其上应用纹理的.jpg时,我的代码工作正常:
let url = NSBundle.mainBundle().URLForResource("chair", withExtension: "obj")
let asset = MDLAsset(URL: NSURL(string:url)!)
guard let object = asset.objectAtIndex(0) as? MDLMesh else {
//fatalError("Failed to get mesh from asset.")
return
}
if shouldApplyTexture == true {
var textureFileName = "chair.mtl"
// Create a material from the various textures
let scatteringFunction = MDLScatteringFunction()
let material = MDLMaterial(name: "baseMaterial", scatteringFunction: scatteringFunction)
material.setTextureProperties(textures: [
.BaseColor:textureFileName])
// Apply the texture to every submesh of the asset
for submesh in object.submeshes! {
if let …Run Code Online (Sandbox Code Playgroud) 
我无法真正找到如何在操作上添加参数,我该怎么办呢?上图是我使用的程序,Modelio ......
如何在Operation上添加参数?
我如何添加返回值?
当使用 MDLAsset(url:) 初始化程序(最终将模型放入 SceneKit)将 OBJ 加载到 MDLAsset 中时,该操作在 iOS14 上频繁且不一致地失败。此操作适用于以前 iOS 版本上的这些相同文件。我也观察到 iPadOS 上的错误,尽管可能不那么频繁。不确定它是否相关,但这些 OBJ 从服务器中提取并存储在本地。但是这个错误是在文件已经下载后发生的。有时同一个文件在随机工作之前会失败多次,反之亦然。
控制台输出似乎表明与 ModelIO XPC 服务通信失败。我尝试重新启动我的设备,但错误继续发生。控制台输出:
connection to com.apple.ModelIO.AssetLoader was interrupted
AssetLoader.loadURL errorHandler: Error Domain=NSCocoaErrorDomain Code=4097 "connection to service on pid 0 named com.apple.ModelIO.AssetLoader" UserInfo={NSDebugDescription=connection to service on pid 0 named com.apple.ModelIO.AssetLoader}
Couldn’t communicate with a helper application.
connection to com.apple.ModelIO.AssetLoader was interrupted
Run Code Online (Sandbox Code Playgroud)
有没有其他人在 iOS14 上遇到过这个问题?或者,是否有任何人在此期间尝试过的解决方法?据我所知,将 OBJ(从服务器下载)加载到 SceneKit 只能通过 ModelIO 完成,而无需自己编写 OBJ 解析器。
目标是重新创建此OBJ文件的照明:https : //poly.google.com/view/cKryD9VnDEZ
将OBJ文件加载到SceneKit中的代码(可以从上面的链接下载文件):
let modelPath = "model.obj"
let url = NSURL(string: modelPath)
let scene = SCNScene(named: modelPath)!
sceneView.autoenablesDefaultLighting = true
sceneView.allowsCameraControl = true
sceneView.scene = scene
sceneView.backgroundColor = UIColor.white
Run Code Online (Sandbox Code Playgroud)
到目前为止尝试过的选项:
1)默认的环境照明要比Google Poly照明更恶劣。移除环境照明会使一切变得太平坦。
2)使用四个定向灯:模型前面,后面,后面一个,上面一个。所有灯光都倾斜以指向模型。这是最好的,但仍然留下了一些阴影和更粗糙的区域,这些在Google Polymer上是看不到的。
3)在选项2中又增加了两个灯,这次在左右增加了灯。这个选项比选项2差,因为多余的灯光与四个现有的灯光组合在一起,并粉刷了模型。
建议后更新:
该代码现在实现了环境光和定向光。
由于某些原因,向摄像机节点(相对于场景根节点)添加定向光没有区别。
指示灯代码如下。
有两个问题:
1)在屏幕截图1中,胸部的右侧太亮并且没有边缘。胸部最左侧的脸太暗。光线最佳的脸位于中间。如何获得适合所有面部的照明(或更适合Google Poly照明)?
2)在屏幕截图2中,方向灯似乎无效。如何通过建议的一种环境光和一种定向光的架构来确保模型的背面与正面一样轻?
码:
// Create ambient light
let ambientLightNode = SCNNode()
ambientLightNode.light = SCNLight()
ambientLightNode.light!.type = .ambient
ambientLightNode.light!.color = UIColor(white: 0.50, alpha: 1.0)
// Add ambient light to scene
scene.rootNode.addChildNode(ambientLightNode)
// Create directional light
let …Run Code Online (Sandbox Code Playgroud) 对于 iOS 应用程序,我将一些 Objective-C 代码转换为 Swift。
Objective-C 代码使用具有以下签名的方法:
+ (nullable NSArray<MTKMesh*>*)newMeshesFromAsset:(nonnull MDLAsset *)asset
device:(nonnull id<MTLDevice>)device
sourceMeshes:(NSArray<MDLMesh*>* __nullable * __nullable)sourceMeshes
error:(NSError * __nullable * __nullable)error;
Run Code Online (Sandbox Code Playgroud)
它的名字如下:
NSArray<MTKMesh *> *mtkMeshes;
NSArray<MDLMesh *> *mdlMeshes;
mtkMeshes = [MTKMesh newMeshesFromAsset:asset
device:_device
sourceMeshes:&mdlMeshes
error:&error];
Run Code Online (Sandbox Code Playgroud)
我正在尝试将其转换为 Swift,但我认为我做错了,因为方法调用总是失败。
上述方法的 Swift 版本:
open class func newMeshes(from asset: MDLAsset, device: MTLDevice, sourceMeshes: AutoreleasingUnsafeMutablePointer<NSArray?>?) throws -> [MTKMesh]
Run Code Online (Sandbox Code Playgroud)
我如何使用它:
do {
var myPointer: AutoreleasingUnsafeMutablePointer<NSArray?>? = nil
myPointer = AutoreleasingUnsafeMutablePointer<NSArray?>.init(&modelIOMeshList)
metalMeshList = try MTKMesh.newMeshes(from:asset, device:device, sourceMeshes: myPointer)
} catch {
fatalError("Error: Can not …Run Code Online (Sandbox Code Playgroud) 我想用SceneKit建模器创建一个 3D 场景,然后将其读入我的Metal应用程序。我看到有SceneKit和ModelIOAPI来做到这一点,但我对如何组合在一起不清楚。
所以,我需要的是.scn文件路径-> MDL Mesh-> 几何 + 纹理。我不清楚如何将我的Metal着色器与SceneKit建模器中创建的材质同步。
我在我的 Xcode 项目中添加了一个 USDZ 文件。USDZ 文件在我的 Mac 上打开的 Xcode 项目中显示为正常,但是,当我尝试使用 modelIO 库通过代码加载它时,它会加载网格,但不会加载纹理。
在下面的快照中有我尝试加载的蜜蜂模型。在第二个中有蜜蜂和飞机,蜜蜂纹理没有渲染,而飞机纹理加载没有问题。我还将 USDZ 文件转换为 scn 文件并且它工作正常。我认为问题不在于文件,而是我使用的代码无法正确加载 USDZ 文件。我正在尝试通过代码加载一个 USDZ 文件,而我使用的库并不重要。如果您有其他建议,我愿意听取他们的意见。
我使用以下代码加载我的模型:
let fileName = “bee”
let ext = “usdz”
let asset = MDLAsset(url: Bundle.main.url(forResource:fileName, withExtension: ext)!)
let loadedScene = SCNScene(mdlAsset: asset)
for child in loadedScene.rootNode.childNodes {
child.geometry?.firstMaterial?.lightingModel = .physicallyBased
}
Run Code Online (Sandbox Code Playgroud)
这里有一些快照来演示我得到的结果: - 我的 Mac 上 Xcode 查看器的快照,成功显示了带有纹理的蜜蜂:
我在这里缺少什么将模型文件完全加载到我的场景中,包括纹理?