iT邦幫忙

2024 iThome 鐵人賽

DAY 27
0
Mobile Development

從 SwiftUI 到 Apple Vision Pro - SwiftUI 從零開始系列 第 27

從 SwiftUI 到 Apple Vision Pro - SwiftUI 從零開始 Day27

  • 分享至 

  • xImage
  •  

Day27 3D貼圖

在上一個單元討論了如何自動生成3D物件,但是這個物件沒有顏色與表面,這個單元就來討論如何針對自動生成的3D物件上色。

首先,使用ModelEntity來生成一個3D物件:

let box = ModelEntity(mesh: .generateBox(width: 0.5, height: 0.5, depth: 0.5))

ModelEntity可以加入材料屬性:

let box = ModelEntity(
    mesh: .generateBox(size: 0.5, cornerRadius: 0),
    materials: [SimpleMaterial(color: .red, isMetallic: false)]
)

在這裡使用SimpleMaterial生成一個紅色的材料,另外isMetallic可以設定使否為金屬材質。

而除了設定顏色的材質之外,也可以使用貼圖方式,例如這裡準備了六張圖片,如圖:

https://ithelp.ithome.com.tw/upload/images/20240827/20162607AcoqHzV5d4.png

讀取這六張圖片:

guard
    let texture1 = try? TextureResource.load(named: "N1"),
    let texture2 = try? TextureResource.load(named: "N2"),
    let texture3 = try? TextureResource.load(named: "N3"),
    let texture4 = try? TextureResource.load(named: "N4"),
    let texture5 = try? TextureResource.load(named: "N5"),
    let texture6 = try? TextureResource.load(named: "N6")
else {
    fatalError("Unable to load texture.")
}

TextureResource是3D材質的圖片讀取方式。

然後將這六個TextureResource帶入給SimpleMaterial:

var material1 = SimpleMaterial()
var material2 = SimpleMaterial()
var material3 = SimpleMaterial()
var material4 = SimpleMaterial()
var material5 = SimpleMaterial()
var material6 = SimpleMaterial()
        
material1.color = .init(texture: .init(texture1))
material2.color = .init(texture: .init(texture2))
material3.color = .init(texture: .init(texture3))
material4.color = .init(texture: .init(texture4))
material5.color = .init(texture: .init(texture5))
material6.color = .init(texture: .init(texture6))
        
let box = Entity()
box.components.set(ModelComponent(
    mesh: .generateBox(width: 0.5, height: 0.5, depth: 0.5, splitFaces: true),
    materials: [material1, material2, material3, material4, material5, material6])
)

如此,這個立方體就會有六個面的貼圖,顯示如圖:

https://ithelp.ithome.com.tw/upload/images/20240827/20162607lFz5CWxcnc.png

完整程式碼:

@MainActor class Day27ViewModel: ObservableObject {
    
    private var contentEntity = Entity()
    
    func setupContentEntity() -> Entity {        
        guard
            let texture1 = try? TextureResource.load(named: "N1"),
            let texture2 = try? TextureResource.load(named: "N2"),
            let texture3 = try? TextureResource.load(named: "N3"),
            let texture4 = try? TextureResource.load(named: "N4"),
            let texture5 = try? TextureResource.load(named: "N5"),
            let texture6 = try? TextureResource.load(named: "N6")
        else {
            fatalError("Unable to load texture.")
        }
        
        var material1 = SimpleMaterial()
        var material2 = SimpleMaterial()
        var material3 = SimpleMaterial()
        var material4 = SimpleMaterial()
        var material5 = SimpleMaterial()
        var material6 = SimpleMaterial()
        
        material1.color = .init(texture: .init(texture1))
        material2.color = .init(texture: .init(texture2))
        material3.color = .init(texture: .init(texture3))
        material4.color = .init(texture: .init(texture4))
        material5.color = .init(texture: .init(texture5))
        material6.color = .init(texture: .init(texture6))
        
        let box = Entity()
        box.components.set(ModelComponent(
            mesh: .generateBox(width: 0.5, height: 0.5, depth: 0.5, splitFaces: true),
            materials: [material1, material2, material3, material4, material5, material6])
        )
        
        box.position = SIMD3(x: 0, y: 2, z: -1)
        
        contentEntity.addChild(box)
        
        return contentEntity
    }
}

從 SwiftUI 到 Apple Vision Pro - SwiftUI 從零開始 Day27 [完]


上一篇
從 SwiftUI 到 Apple Vision Pro - SwiftUI 從零開始 Day26
下一篇
從 SwiftUI 到 Apple Vision Pro - SwiftUI 從零開始 Day28
系列文
從 SwiftUI 到 Apple Vision Pro - SwiftUI 從零開始30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言