58 lines
2.3 KiB
Swift
58 lines
2.3 KiB
Swift
//
|
|
// DirtTextureFactory.swift
|
|
// GasTankAR
|
|
//
|
|
// Created by Dennis Nemec on 28.08.26.
|
|
//
|
|
|
|
import RealityKit
|
|
import UIKit
|
|
|
|
/// Erzeugt prozedural eine kachelbare Erd-/Dreck-Textur (ohne Bild-Asset) für die Grubenwand,
|
|
/// damit sichtbar wird, dass sich der Tank unter der Erde befindet.
|
|
@MainActor
|
|
enum DirtTextureFactory {
|
|
/// Einmalig erzeugte, wiederverwendete Textur.
|
|
static let texture: TextureResource? = makeTexture()
|
|
|
|
private static func makeTexture() -> TextureResource? {
|
|
let size = CGSize(width: 256, height: 256)
|
|
let image = UIGraphicsImageRenderer(size: size).image { context in
|
|
let rect = CGRect(origin: .zero, size: size)
|
|
|
|
// Erd-Grundton.
|
|
UIColor(red: 0.42, green: 0.30, blue: 0.18, alpha: 1).setFill()
|
|
context.fill(rect)
|
|
|
|
// Größere Erdflecken / Steine für Struktur.
|
|
for _ in 0..<70 {
|
|
let diameter = CGFloat.random(in: 6...26)
|
|
let origin = CGPoint(x: .random(in: -10...size.width), y: .random(in: -10...size.height))
|
|
let brightness = CGFloat.random(in: -0.12...0.12)
|
|
UIColor(
|
|
red: max(0, min(1, 0.42 + brightness)),
|
|
green: max(0, min(1, 0.30 + brightness)),
|
|
blue: max(0, min(1, 0.18 + brightness)),
|
|
alpha: 1
|
|
).setFill()
|
|
context.cgContext.fillEllipse(in: CGRect(x: origin.x, y: origin.y, width: diameter, height: diameter))
|
|
}
|
|
|
|
// Feine Körnung (helle + dunkle Sprenkel).
|
|
for _ in 0..<2000 {
|
|
let point = CGPoint(x: .random(in: 0..<size.width), y: .random(in: 0..<size.height))
|
|
let diameter = CGFloat.random(in: 0.5...2.5)
|
|
let isDark = Bool.random()
|
|
let color = isDark
|
|
? UIColor(white: 0, alpha: .random(in: 0.05...0.2))
|
|
: UIColor(white: 1, alpha: .random(in: 0.03...0.12))
|
|
color.setFill()
|
|
context.cgContext.fillEllipse(in: CGRect(x: point.x, y: point.y, width: diameter, height: diameter))
|
|
}
|
|
}
|
|
|
|
guard let cgImage = image.cgImage else { return nil }
|
|
return try? TextureResource.generate(from: cgImage, options: .init(semantic: .color))
|
|
}
|
|
}
|