Initial commit for first version of project
This commit is contained in:
63
GasTankAR/Views/TankAR/TankDepthFadeMaterial.swift
Normal file
63
GasTankAR/Views/TankAR/TankDepthFadeMaterial.swift
Normal file
@ -0,0 +1,63 @@
|
||||
//
|
||||
// TankDepthFadeMaterial.swift
|
||||
// GasTankAR
|
||||
//
|
||||
// Created by Dennis Nemec on 26.08.26.
|
||||
//
|
||||
|
||||
import RealityKit
|
||||
import Metal
|
||||
|
||||
/// Kapselt das Höhen-Fade-CustomMaterial für den unterirdischen Tank:
|
||||
/// verblasst die Opacity anhand der Welt-Höhe (Kopf opak, vergrabener Teil transparent).
|
||||
@MainActor
|
||||
enum TankDepthFadeMaterial {
|
||||
/// Fade-Band (Meter) unterhalb der Bodenkante, über das die Transparenz einsetzt.
|
||||
static let band: Float = 0.15
|
||||
/// Minimale Opacity des vergrabenen Teils.
|
||||
static let belowAlpha: Float = 0.3
|
||||
|
||||
private static let shader: CustomMaterial.SurfaceShader? = {
|
||||
guard let library = MTLCreateSystemDefaultDevice()?.makeDefaultLibrary() else { return nil }
|
||||
return CustomMaterial.SurfaceShader(named: "tankDepthFadeSurface", in: library)
|
||||
}()
|
||||
|
||||
/// Ersetzt die Materialien der Entity (rekursiv) durch das Fade-CustomMaterial.
|
||||
static func apply(to entity: Entity) {
|
||||
guard let shader else { return }
|
||||
forEachModelEntity(entity) { modelEntity in
|
||||
guard var component = modelEntity.model else { return }
|
||||
component.materials = component.materials.map { material in
|
||||
guard var custom = try? CustomMaterial(from: material, surfaceShader: shader) else {
|
||||
return material
|
||||
}
|
||||
custom.blending = .transparent(opacity: 1.0)
|
||||
custom.custom.value = SIMD4<Float>(0, band, belowAlpha, 0)
|
||||
return custom
|
||||
}
|
||||
modelEntity.model = component
|
||||
}
|
||||
}
|
||||
|
||||
/// Aktualisiert die Boden-Höhe (Welt-Y) in bereits angewandten Fade-Materialien.
|
||||
static func updateGroundY(_ groundY: Float, on entity: Entity) {
|
||||
forEachModelEntity(entity) { modelEntity in
|
||||
guard var component = modelEntity.model else { return }
|
||||
component.materials = component.materials.map { material in
|
||||
guard var custom = material as? CustomMaterial else { return material }
|
||||
custom.custom.value = SIMD4<Float>(groundY, band, belowAlpha, 0)
|
||||
return custom
|
||||
}
|
||||
modelEntity.model = component
|
||||
}
|
||||
}
|
||||
|
||||
private static func forEachModelEntity(_ entity: Entity, _ body: (ModelEntity) -> Void) {
|
||||
if let modelEntity = entity as? ModelEntity {
|
||||
body(modelEntity)
|
||||
}
|
||||
for child in entity.children {
|
||||
forEachModelEntity(child, body)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user