public enum Fog { public enum Mode { case distance case depth } public enum RangeType { case linear case smooth } public enum FactorType { case exp case exp2 } case none case range(colour: Colour, mode: Mode, type: RangeType, start: Float, end: Float) case factor(colour: Colour, mode: Mode, type: FactorType, density: Float) } public enum Light { case directional(colour: Colour, direction: Vec3f) case point(colour: Colour, position: Vec3f, intensity: Float) } public struct Environment { public var fog: Fog = .none public var ambient: Colour = .black public var lights: [Light] = .init() public init() {} public init(fog: Fog, ambient: Colour, lights: [Light]) { self.fog = fog self.ambient = ambient self.lights = lights } } public extension Environment { enum FogFalloff { case range(type: Fog.RangeType, start: Float, end: Float) case factor(type: Fog.FactorType, density: Float) } mutating func setFog(colour: Colour, mode: Fog.Mode, falloff: FogFalloff) { fog = switch falloff { case .range(let type, let start, let end): .range(colour: colour, mode: mode, type: type, start: start, end: end) case .factor(let type, let density): .factor(colour: colour, mode: mode, type: type, density: density) } } mutating func addAmbientLight(colour: Colour) { ambient = colour } mutating func addDirectionalLight(direction: Vec3f, colour: Colour) { lights.append(.directional(colour: colour, direction: direction)) } mutating func addPointLight(position: Vec3f, colour: Colour, intensity: Float) { lights.append(.point(colour: colour, position: position, intensity: intensity)) } }