【iOS ARKit】光照效果--光源

光照

     在现实世界中,光扮演了极其重要的角色,没有光万物将失去色彩,没有光世界将一片漆黑。在3D数字世界中亦是如此,3D数字世界本质上是一个使用数学精确描述的真实世界复本,光照计算是影响这个数字世界可信度的极其重要的因素。

光源

     顾名思义,光源即是光的来源,常见的光源有阳光、月光、星光、灯光等。光的本质其实很复杂,它是一种电磁辐射但却有波粒二象性(我们不会深入研究光学,那将是一件非常复杂且枯燥的工作,在计算机图形学中,只需要了解一些简单的光学属性并应用)。在实时渲染时,通常把光源当成一个没有体积的点,用工表示由其发射光线的方向,使用辐照度(Irradiance)量化光照强度。对平行光而言,它的辐照度可以通过计算在垂直于L 的单位面积上单位时间内穿过的能量衡量。在图形学中考虑光照,我们只要想象光源会向空间中发射带有能量的光子,然后这些光子会与物体表面发生作用(反射、折射和吸收),最后的结果是我们看到物体的颜色和各种纹理。

RealityKit 中的光源

    iOS Reality Kit 支持3种光源类型:平行光(DirectionalLight)、点光(PointLigbt)、聚光(SpotLight),分别同于模拟太阳光、普通灯泡类灯光、手电筒类灯光,组合使用这3种光源类型可以实现绝大部分光照效果道染需求。实际上,RealityRit还支持环境光,但 RealityKit 中的环境光照并不直接来自光源,而是使用IBL(Image Based Lighting,基于图像的光照)技术从背景图像中提取。

     RealityKit 采用IBL 技术的初衷是增强3D虚拟元素的真实感,使用该技术可以从提供的环境资源貼因中提取环境信息及光照信息。环境资源贴图定义了AR环境中的大概颜色及明暗信息,利用这些信息,RealityKit 可以将其用于环境反射以增强虚拟元素的真实感和可信度。

    使用环境资源贴图首先需要新建一个以.skybox为后辍的文件夹,并在该文件夹中放置使用的环境资源文件。环净资源贴图文件需为等距杜状投影环境图(经纬投影图)。將该文件实拖入 Xeode 工程文年写藏窗口中,在弹出的“选项”对 框中选择文件实引用(不要使用组),这样在工程编译译时 Xcode会自动打包该文件夹中所有的资源。

     Reality Kit 环境资源贴图类型支持常见图像格式,如.png 和.jpg 格式图像文件,但获得表现力更丰富:颜色更饱满的照明和反射效果,建议使用.exr或,bdr 格式图像,这两种格式支持高动态范围,用于环境反射效果更出色。

    在 RealityKit 中使用环境资源贴图只需要将贴图文件赋给 ARView. environment. background 属性,由干环境资源贴图放在特定的文件夹中,RealityKit 也提供了简洁的贴图加载方式,大大地简化了开发者的工作,典型代码如代码如下所示。

arView.environment.background = .skybox(try! EnvironmentResource.load(named: "Space"))
  • 平行光

     平行光用于模拟在远处发射的光照效果,在Reality Kit中,使用平行光的代码如下:

//
//  DirectionalLightView.swift
//  ARKitDeamo
//
//  Created by Zhaoquan on 2023/1/7.
//import SwiftUI
import RealityKit
import ARKitstruct DirectionalLightView : View {var body: some View {return ARViewContainer11().edgesIgnoringSafeArea(.all)}
}struct ARViewContainer11: UIViewRepresentable {func makeUIView(context: Context) -> ARView {let arView = ARView(frame: .zero)let config = ARWorldTrackingConfiguration()config.planeDetection = .horizontalconfig.worldAlignment = .gravityarView.session.run(config, options:[ ])arView.session.delegate = arViewarView.createPlane11()return arView}func updateUIView(_ uiView: ARView, context: Context) {}
}var boxMesh = MeshResource.generateBox(size: 0.1)
var boxMaterial = SimpleMaterial(color:.white,isMetallic: false)
var boxEntity11 = ModelEntity(mesh:boxMesh,materials:[boxMaterial])var planeMesh11 = MeshResource.generatePlane(width: 0.3,depth: 0.3)
var planeMaterial11 = SimpleMaterial(color:.white,isMetallic: false)
var planeEntity11 = ModelEntity(mesh:planeMesh11,materials:[planeMaterial11])extension ARView {func createPlane11(){let planeAnchor = AnchorEntity(plane:.horizontal,classification: .any,minimumBounds: [0.3,0.3])planeAnchor.addChild(boxEntity11)var tf = boxEntity11.transformtf.translation = SIMD3(tf.translation.x,tf.translation.y + 0.06,tf.translation.z)boxEntity11.move(to: tf, relativeTo: nil)planeAnchor.addChild(planeEntity11)//添加平行光源let directionalLight = DirectionalLight()//光照强度directionalLight.light.intensity = 50000//光照颜色directionalLight.light.color = UIColor.reddirectionalLight.light.isRealWorldProxy = falsedirectionalLight.look(at: [0, 0, 0], from: [0.01, 1, 0.01], relativeTo: nil)planeAnchor.addChild(directionalLight)self.scene.addAnchor(planeAnchor)}
}#if DEBUG
struct DirectionalLightView_Previews : PreviewProvider {static var previews: some View {ARViewContainer11()}
}
#endif

      对平行光而言,光源位置并不重要,重要的是光照方向,在实际开发中,经常使用平行光的look()方法设置光照方向。

  • 点光

    点光从光源位置向所有方向发射光线,当光线沿各方向传播时会出现衰减,在RealityKit 中使用 attenuationRadius 参数表示光线最大有效距离,即超出该距离后的物体无法被光源照射。使用点光时,不仅要指定光源位置,还需要指定衰减半径,典型的点光使用代码如代码如下。

//
//  PointLightView.swift
//  ARKitDeamo
//
//  Created by Zhaoquan on 2023/1/7.
//import SwiftUI
import RealityKit
import ARKitstruct PointLightView : View {var body: some View {return ARViewContainer12().edgesIgnoringSafeArea(.all)}
}struct ARViewContainer12: UIViewRepresentable {func makeUIView(context: Context) -> ARView {let arView = ARView(frame: .zero)let config = ARWorldTrackingConfiguration()config.planeDetection = .horizontalconfig.worldAlignment = .gravityarView.session.run(config, options:[ ])arView.session.delegate = arViewarView.createPlane12()return arView}func updateUIView(_ uiView: ARView, context: Context) {}
}extension ARView {func createPlane12(){let planeAnchor = AnchorEntity(plane:.horizontal,classification: .any,minimumBounds: [0.3,0.3])let planeMesh = MeshResource.generatePlane(width: 0.8,depth: 0.8)let planeMaterial = SimpleMaterial(color:.white,isMetallic: false)let planeEntity = ModelEntity(mesh:planeMesh,materials:[planeMaterial])planeAnchor.addChild(planeEntity)let boxMesh = MeshResource.generateBox(size: 0.1)let boxMaterial = SimpleMaterial(color:.white,isMetallic: false)let boxEntity = ModelEntity(mesh:boxMesh,materials:[boxMaterial])planeAnchor.addChild(boxEntity)//添加点光源let l = PointLight()l.light = PointLightComponent(color: .green, intensity: 5000, attenuationRadius: 0.5)l.position = [planeEntity.position.x , planeEntity.position.y + 0.5,planeEntity.position.z+0.2]l.move(to: l.transform, relativeTo: nil)let lightAnchor = AnchorEntity(world: l.position)lightAnchor.components.set(l.light)self.scene.addAnchor(lightAnchor)self.scene.addAnchor(planeAnchor)}
}#if DEBUG
struct PointLightView_Previews : PreviewProvider {static var previews: some View {ARViewContainer12()}
}
#endif
  • 聚光     

      聚光沿圆锥体发射光线,类似于手电筒的发光效果,其光线在传播时也会出现衰减,同时,在使用光需要指定圆锥角(innerAngleInDegrees)、聚光方向角(outerAngleInDegrees) 和光照方向,典型的聚光使用代码如下所示。

//
//  SpotLightView.swift
//  ARKitDeamo
//
//  Created by Zhaoquan on 2023/1/7.
//import SwiftUI
import RealityKit
import ARKitstruct SpotLightView : View {var body: some View {return ARViewContainer12().edgesIgnoringSafeArea(.all)}
}struct ARViewContainer13: UIViewRepresentable {func makeUIView(context: Context) -> ARView {let arView = ARView(frame: .zero)let config = ARWorldTrackingConfiguration()config.planeDetection = .horizontalconfig.worldAlignment = .gravityarView.session.run(config, options:[ ])arView.session.delegate = arViewarView.createPlane13()return arView}func updateUIView(_ uiView: ARView, context: Context) {}
}
/*
class SpotLight: Entity, HasSpotLight {required init() {super.init()self.light = SpotLightComponent(color: .yellow,intensity: 50000, innerAngleInDegrees: 60,outerAngleInDegrees: 130,attenuationRadius: 5)}
}*/var planeMesh13 = MeshResource.generatePlane(width: 0.8,depth: 0.8)
var planeMaterial13 = SimpleMaterial(color:.white,isMetallic: false)
var planeEntity13 = ModelEntity(mesh:planeMesh13,materials:[planeMaterial13])extension ARView : ARSessionDelegate{func createPlane13(){let planeAnchor = AnchorEntity(plane:.horizontal,classification: .any,minimumBounds: [0.3,0.3])planeAnchor.addChild(planeEntity13)let l = SpotLight()l.light = SpotLightComponent(color: .yellow, intensity: 5000, innerAngleInDegrees: 5, outerAngleInDegrees: 80, attenuationRadius: 2)l.position = [planeEntity13.position.x , planeEntity13.position.y + 0.1,planeEntity13.position.z+0.5]l.move(to: l.transform, relativeTo: nil)let lightAnchor = AnchorEntity(world: l.position)l.look(at: planeEntity13.position, from: l.position, relativeTo: nil)lightAnchor.components.set(l.light)self.scene.addAnchor(lightAnchor)self.scene.addAnchor(planeAnchor)}
}#if DEBUG
struct SpotLightView_Previews : PreviewProvider {static var previews: some View {ARViewContainer13()}
}
#endif

      利用光照可以在数字世界中模拟真实物体的照明效果,营造真实可信的虛实融合场景,但光照计算是一頂对资源消耗比较大的任务,场最中光源设置得越多,对性能消耗就越大,为提商应用性能,需要控制场果中的光源数量,或者使用顶渲染的纹理贴图替代实时光照计算。RealityKit 中各光源类型对资源消耗排序为:聚光>点光>平行光>环境光,聚光对性能消耗最大,需谨慎使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/656003.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

迷你型洗衣机好用吗?迷你内裤洗衣机排名前十名推荐

随着大家工作的压力越来越大,下了班之后只能想躺平,在洗完澡之后看着还需要手洗的内衣裤真的很头疼。有些小伙伴还有会攒几天再丢进去洗衣机里面一起,而且这样子是非常不好的,用过的内衣裤长时间不清洗容易滋生细菌,而…

Redis学习——高级篇④

Redis学习——高级篇④ Redis7高级之Redis与Mysql数据双写一致性工程案例(四) 4.1 MySQL主从复制原理4.2 canal 工作原理4.3 mySQL->canal->redis 双写一致性1.环境2.配置Mysql3.配置canal4. Canal客户端(Java编写&#xff0…

【力扣经典面试题】27. 移除元素

题目描述: 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。 不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑…

JavaScript-for循环的执行顺序

1.目标 掌握for执行顺序 2.实现思路 使用for循环输出0-到5 3.代码实现 Document 4.总结 for执行顺序 1.执行 var i 0 变量初始化 条件判断 是否成立 成立 执行循环体 不成立 退出for循环

TypeScript(五) 条件语句

1. 条件语句 1.1. 描述 条件语句用于基于不同的条件来执行不同的动作。   条件语句是通过一条或多条语句的执行结果(true或false)来决定后面执行的代码块。 1.2. 常使用的条件语句 (1)if语句 - 只有当指定条件为true时&#…

STL_list

一、有关list的介绍 list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素。Ii…

Docker容器引擎(6)

目录 一.什么是consul 解决什么问题? consul的模式: 二.consul 部署 consul服务器: 查看版本: 设置代理,在后台启动 consul 服务端: 进行后台启动: 查看集群信息: 访问页面…

云计算底层技术奥秘、磁盘技术揭秘、虚拟化管理、公有云概述

云计算基础 实验图例 虚拟化平台安装 创建虚拟机 1、创建虚拟机 2cpu,4G内存(默认用户名: root 密码: a) 2、验证 ecs 是否支持虚拟化 [rootecs ~]# grep -Po "vmx|svm" /proc/cpuinfovmx... ...[rootecs ~]# lsmod |grep kvm…

Linux 网络分析 Wireshark

这篇记录一些 Wireshark 的使用操作,有兴趣的建议看看 《Wireshark网络分析就这么简单》 写的很好,有趣能看进去。 Wireshare 是一个常用的并且很强大网络包分析软件,可以抓包也可以导入tcpdump的导出数据分析。pcap 这个后缀的文件可以用 wi…

【算法专题】前缀和(附图解、代码)

📑前言 本文主要是前缀和的文章,如果有什么需要改进的地方还请大佬指出⛺️ 🎬作者简介:大家好,我是青衿🥇 ☁️博客首页:CSDN主页放风讲故事 🌄每日一句:努力一点&…

Orion-14B-Chat-Plugin本地部署的解决方案

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

WebSocket 整合 记录用法

WebSocket 介绍 WebSocket 是基于tcp的一种新的网络协议,可以让浏览器 和 服务器进行通信,然后区别于http需要三次握手,websocket只用一次握手,就可以创建持久性的连接,并进行双向数据传输 Http和WebSocket的区别 Http是短连接,WebSocket’是长连接Http通信是单向的,基于请求…

互联网加竞赛 基于深度学习的人脸表情识别

文章目录 0 前言1 技术介绍1.1 技术概括1.2 目前表情识别实现技术 2 实现效果3 深度学习表情识别实现过程3.1 网络架构3.2 数据3.3 实现流程3.4 部分实现代码 4 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 基于深度学习的人脸表情识别 该项目较…

HiveSQL题——排序函数(row_number/rank/dense_rank)

一、窗口函数的知识点 1.1 窗户函数的定义 窗口函数可以拆分为【窗口函数】。窗口函数官网指路: LanguageManual WindowingAndAnalytics - Apache Hive - Apache Software Foundationhttps://cwiki.apache.org/confluence/display/Hive/LanguageManual%20Windowin…

【Algorithms 4】算法(第4版)学习笔记 01 - 1.5 案例研究:union-find算法

文章目录 前言参考目录学习笔记1:动态连通性2:UF 实现 1:快速查找 quick-find2.1:demo 演示 12.2:demo 演示 22.3:quick-find 代码实现3:UF 实现 2:快速合并 quick-union3.1&#xf…

【Java 数据结构】二叉树

二叉树 1. 树型结构(了解)1.1 概念1.2 概念(重要)1.3 树的表示形式(了解)1.4 树的应用 2. 二叉树(重点)2.1 概念2.2 两种特殊的二叉树2.3 二叉树的性质2.4 二叉树的存储2.5 二叉树的…

【人工智能课程】计算机科学博士作业二

使用TensorFlow1.x版本来实现手势识别任务中,并用图像增强的方式改进,基准训练准确率0.92,测试准确率0.77,改进后,训练准确率0.97,测试准确率0.88。 1 导入包 import math import warnings warnings.filt…

【力扣经典面试题】80. 删除有序数组中的重复项 II

题目 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。 不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。 说明&…

SpringBoot---创建项目

介绍 此项目SpringBoot使用的是2.6.1版本,由于这个项目使用的是maven聚合方式创建的,所以第二步是我在聚合方式下需要添加的依赖,完整的pom.xml内容放到了最下面。 第一步:创建Maven项目 这个里什么也不勾选,直接点…

JDK Locale的妙用:探索多语言和地区设置的强大功能

文章目录 前言应用场景国际化(Internationalization)格式化(Formatting)日期格式化数字格式化金额格式化百分比形式格式化 获取Locale信息 前言 JDK(Java Development Kit)的Locale类用于表示特定的地理、…