Ни великолепная форма геометрии, ни ее изысканная текстура не делают 3D-модель реалистичной в сцене AR / VR. Это скорее свет с его тенями, который делает свою работу. В AR тени - ключевой компонент интеграции модели, потому что тени являются объектами заземления. Объекты без теней кажутся парящими в воздухе. А без надлежащей интенсивности и направления света зритель никогда не поверит, что модель принадлежит реальной сцене.
RealityKit неявно использует алгоритм оценки освещенности, который помогает нам автоматически освещать виртуальные модели в соответствии с условиями освещения в реальном мире. Но также мы можем явно добавлять источники света в нашу сцену, когда захотим.
В RealityKit есть четыре типа источников света, которые помогают нам осветить сцену: точечный свет, точечный свет, направленный свет и на основе изображения. свет (IBL). В отличие от SceneKit, в котором есть только классы для освещения - класс SCNLight с соответствующей структурой LightType, - RealityKit, по порядку чтобы предложить удобный и эффективный интерфейс программирования для разработчиков Swift, использует как классы для наследования (парадигма ООП), так и протоколы для композиции (парадигма POP).
RealityKit 2.0 имеет четыре класса и три протокола для создания уникальных условий освещения. Вы можете использовать их вместе или по отдельности, на ваше усмотрение.
publicclass
DirectionalLight: Entity, HasDirectionalLight publicclass
PointLight: Entity, HasPointLight publicclass
SpotLight: Entity, HasSpotLight public struct ImageBasedLight
Структура ImageBasedLight вложена в структуру Environment, которая находится внутри представления RealityKit. Основанный на изображении свет используется для освещения окружающей среды.
extension ARView { public struct Environment { public struct ImageBasedLight { public var resource: EnvironmentResource? public var intensityExponent: Float } } }
Следовательно, мы можем получить доступ к свойствам освещения окружающей среды, используя точечную нотацию Swift:
arView.environment.lighting.resource arView.environment.lighting.intensityExponent
Давайте узнаем, что такое источники света RealityKit и какие типы теней они создают. Мы протестируем все типы источников света в простой сцене, где активирован только источник света RealityKit по умолчанию (по умолчанию IBL).
Направленный свет
Направленный свет имитирует параллельные лучи, исходящие от далекой звезды - Солнца. Наиболее важным аспектом этого типа света является его ориентация. Положение направленного света неважно. Этот источник света создает тени карты глубины. Интенсивность направленного света измеряется в люмен на квадратный метр.
Важно: Если в сцене нет источников света, кроме направленного, поверхности, параллельные направлению световых лучей, будут черными .
Вот свойства DirectionalLight:
let directionalLight = DirectionalLight() directionalLight.light.color = .red directionalLight.light.intensity = 20000 directionalLight.light.isRealWorldProxy = true directionalLight.shadow?.maximumDistance = 10.0 directionalLight.shadow?.depthBias = 5.0 directionalLight.orientation = simd_quatf(angle: -.pi/1.5, axis: [0,1,0])
Точечный свет
Точечный свет - это всенаправленный свет, подобный электрической лампочке. Его положение имеет решающее значение, но ориентация не имеет значения. Этот тип источника света в настоящий момент не может генерировать тени, поэтому нет свойства экземпляра с именем shadow. Интенсивность точечного света измеряется в люменах.
Вот свойства PointLight:
let pointLight = PointLight() pointLight.light.color = .blue pointLight.light.intensity = 15000000 pointLight.light.attenuationRadius = 7.0 pointLight.position = [4,0,1]
Прожектор
Как следует из названия, SpotLight имитирует конический луч света, который вы много раз видели в театре, цирке или на концерте. Этот световой конус создает горячую точку, область между внутренним и внешним световыми конусами (также известную как полутень, которая определяет угол внутри светового конуса, при котором свет начинает переходить от полной силы к отсутствию освещения) и мягкие края тени. Если ваше устройство оснащено набором микросхем A12 или лучше, тип визуализируемых теней будет трассировка лучей (тени высокого качества), но более ранние версии наборов микросхем Apple ( A9, A10, A11) могут генерировать только тени с отображением глубины (поддельные проекции). Интенсивность прожектора измеряется в люменах.
Вот свойства SpotLight:
let spotLight = SpotLight() spotLight.light.color = .green spotLight.light.intensity = 2500000 spotLight.light.innerAngleInDegrees = 70 spotLight.light.outerAngleInDegrees = 120 spotLight.light.attenuationRadius = 9.0 spotLight.shadow = SpotLightComponent.Shadow() spotLight.position.y = 5.0 spotLight.orientation = simd_quatf(angle: -.pi/1.5, axis: [1,0,0])
Освещение на основе изображения
В RealityKit ваша сцена может быть освещена с помощью 32-битного изображения с расширенным динамическим диапазоном, которое может быть в HDR или OpenEXR формат файла. Освещение на основе изображения работает с положительными и отрицательными значениями. HDRI может содержать девять или более изображений с шагом 1/3 ступени, но для работы с HDRI вам потребуется как минимум три экспозиции.
RealityKit имеет HDR-освещение по умолчанию, и мы можем легко увеличить интенсивность этого света, остановив экспозицию следующим образом:
arView.environment.lighting.intensityExponent = 2
И, как я сказал ранее, интенсивность света HDR также может быть отрицательной. Мы могли бы уменьшить интенсивность окружающего света, прекратив его экспозицию:
arView.environment.lighting.intensityExponent = -2
Создание нестандартных источников света
Теперь, когда мы достаточно знаем о типах источников света RealityKit, давайте создадим нашу собственную установку источников света. Каждый класс должен наследовать от родительского класса Entity и соответствовать соответствующему протоколу.
Сначала мы создадим собственный направленный свет:
import ARKit import RealityKit class CustomDirectionalLight: Entity, HasDirectionalLight { required init() { super.init() self.light = DirectionalLightComponent(color: .red, intensity: 20000, isRealWorldProxy: true) self.shadow = DirectionalLightComponent.Shadow( maximumDistance: 10, depthBias: 5.0) self.orientation = simd_quatf(angle: -.pi/1.5, axis: [0,1,0]) } }
Затем точечный свет:
class CustomPointLight: Entity, HasPointLight { required init() { super.init() self.light = PointLightComponent(color: .blue, intensity: 15000000, attenuationRadius: 7.0) self.position = [4,0,1] } }
И, наконец, прожектор:
class CustomSpotLight: Entity, HasSpotLight { required init() { super.init() self.light = SpotLightComponent(color: .green, intensity: 2500000, innerAngleInDegrees: 70, outerAngleInDegrees: 120, attenuationRadius: 9.0) self.shadow = SpotLightComponent.Shadow() self.position.y = 5.0 self.orientation = simd_quatf(angle: -.pi/1.5, axis: [1,0,0]) } }
Теперь мы можем использовать эти типы источников света вместе в файле ViewController.swift:
class ViewController: UIViewController { @IBOutlet weak var arView: ARView! override func viewDidLoad() { super.viewDidLoad() // Lights let directLight = CustomDirectionalLight() let pointLight = CustomPointLight() let spotLight = CustomSpotLight() let lightAnchor = AnchorEntity(world: [0,0,-3]) lightAnchor.addChild(directLight) lightAnchor.addChild(pointLight) lightAnchor.addChild(spotLight) // Temple model from Reality Composer let sceneAnchor = try! Experience.loadTempleScene(). sceneAnchor.templeModel!.position.y = -0.6 sceneAnchor.templeModel!.scale = [4,4,4] // Plane primitive let plane: MeshResource = .generatePlane(width: 7.0, depth: 7.0) let material = SimpleMaterial(color: .darkGray, isMetallic: false) let entity = ModelEntity(mesh: plane, materials: [material]) entity.position.y = -0.6 sceneAnchor.addChild(entity) arView.scene.anchors.append(sceneAnchor) arView.scene.anchors.append(lightAnchor) } }
Вуаля!
Часто вам нужно осветить сцену собственным файлом HDR. Для этого просто добавьте ресурс среды в свой проект - создайте папку с именем «iskybox» и поместите HDR изображение внутри. Изображение должно быть картой окружающей среды в проекции широты и долготы. Перетащите папку в навигатор файлов проекта Xcode. В открывшейся раскрывающейся панели параметров выберите Создать ссылки на папки.
Затем вставьте эти строки кода в метод viewDidLoad ():
override func viewDidLoad() { super.viewDidLoad() arView.environment.lighting.resource = try! .load(named: "iskybox/city.hdr") arView.environment.lighting.intensityExponent = -1 // blah-blah... }
Однако, если вам не нужно освещение окружающей среды, вы можете отключить его, используя свойство типа disableAREnvironmentLighting из структуры RenderOptions. который соответствует протоколу OptionSet.
arView.renderOptions = [.disableAREnvironmentLighting, .disableMotionBlur]
P. S.
Несомненно, на данный момент SceneKit имеет более богатый арсенал типов освещения, а точнее в 2 раза больше. Вот их список:
• Ambient • Area • Directional • Environment HDR • Omni • Photometric IES • Probe • Spot
Но я уверен, что список светильников RealityKit тоже очень скоро вырастет.
Если вы хотите включить освещение, но не хотите перегружать процессор, обратите внимание на текстуры на основе теней.
Пожертвовать автору
addr1q9w70n62nu8p7f9ukfn66gzumm9d9uxwppkx7gk7vd7gy0ehfavj97gkncwm8t8l8l8x9e4adzmw2djh4y5gd9rmtewqr99zr3
На этом пока все.
Если эта публикация вам полезна, нажмите кнопку Хлопать и удерживайте ее. На Medium вы можете аплодировать до 50 за каждое сообщение.
Если у вас есть какие-либо вопросы, вы можете связаться со мной через StackOverflow.
До встречи!