製作3D模型是非常有趣的事,如果有興趣,可能一兩星期就能熟悉 Blender 操作,再參考模仿別人的作品,半年就能做出精美的3D模型,在未來,「3D動畫設計師」 在 AI 的輔助下,可能是非常好的職業。

完全用 RealityKit 製作的花瓶 (c)2025 Heman Lu

完全用 RealityKit 製作的花瓶 (c)2025 Heman Lu

若不想自己動手做模型,網路上也可找到不少現成的 USDZ 模型檔案,例如:

  1. Apple 原廠 AR Quick Look
  2. 美國太空總署 NASA
  3. 美國史密森學會(自然史博物館)
  4. 輝達NVIDIA USD Example Datasets (非常多素材)
  5. Poly Haven (免費3D模型與材質)
  6. SideFX Houdini 製作的免費模型(很逼真)
  7. 皮克斯 OpenUSD 官網
  8. Sketchfab(市集網站,需註冊)
  9. Turbosquid (市集網站,需註冊)

上列前三者都不需要註冊,直接就能下載 USDZ 模型。我們可以利用程式 URLSession 下載、暫存到檔案中,再用 RealityView 加到虛擬場景。

第5單元5-4b曾經用過一個檔案下載的函式,正好符合需求,稍微改一下,加到共享程式區:

// 6-7b 公享程式:檔案下載
// Revised by Heman, 2025/02/19
// Based on 5-4b AI模型(with CoreML), 2023/03/17
import Foundation

private enum 錯誤碼: Error {
    case 無法取得檔案路徑
    case 網址字串有誤
    case 其他錯誤
}

// 第6段
public func 檔案下載(_ 網址: String) async throws -> URL {
    guard let myURL = URL(string: 網址) else {
        throw 錯誤碼.網址字串有誤
    }
    let 檔案名稱 = myURL.lastPathComponent
    let 檔案管理員 = FileManager()
    guard let 目錄 = 檔案管理員.urls(
        for: .cachesDirectory,
        in: .userDomainMask).first else {
        throw 錯誤碼.無法取得檔案路徑
    }
    let 存檔路徑 = 目錄.path + "/" + 檔案名稱
    print("下載目標:\\(myURL)\\n存檔標的:\\(存檔路徑)")
    if 檔案管理員.fileExists(atPath: 存檔路徑) {
        print("檔案已下載過")
    } else {
        let (原始資料, 錯誤碼) = try await URLSession.shared.data(from: myURL)
        print("下載成功:\\(原始資料)", 錯誤碼)
        _ = 檔案管理員.createFile(atPath: 存檔路徑, contents: 原始資料)
    }
    let 回傳值 = 目錄.appendingPathComponent(檔案名稱)
    print("回傳模型位址:\\(回傳值)")
    return 回傳值
}

當時(5-4b)函式宣告是傳回 URL?,現在我們知道,throwing function 與 Optional 都是錯誤處理的方式,只要二選一即可,兩種並用就像疊床架屋,沒有必要,因此改傳回 URL: