AR/MR实时光照阴影开发教程

news2025/6/4 15:09:07

一、效果演示

1、PICO4 Ultra MR 发光的球

2、AR实时光照

二、实现原理

        PICO4 Ultra MR开发时,通过空间网格能力扫描周围环境,然后将扫描到的环境网格材质替换为一个透明材质并停止扫描;基于Google ARCore XR Plugin和ARFoundation进行安卓手机的AR开发,通过扫描周围环境进行平面识别,然后将扫描到的平面的材质替换为一个透明材质并停止扫描。此处透明材质可以接收光照和阴影。

三、实现过程

        本教程使用Unity版本为2022.3LTS,渲染管线为URP,Built-In同样可用。

1、创建透明材质

        透明材质着色器来源于Meta的MRUK Sample,点击此处进入其Github页。

        克隆项目至本地,用Unity国际版本打开项目,需要复制着色器及三个依赖文件至计算机本地路径下。

(1)着色器资源准备

        找到下图所示Packages路径下的着色器,右键在资源管理器中打开,复制至本地文件夹下。

        找到下图所示Packages路径下的EnvironmentDepth文件夹,右键在资源管理器中打开,将EnvironmentOcclusion.cginc、URP中的EnvironmentOcclusionURP.hlsl和BiRP中的EnvironmentOcclusionBiRP.cginc复制至本地文件夹下。

        资源复制完成明细如下图所示。

(2)项目导入着色器

        将复制出的着色器及其依赖资源文件拖动至Unity项目合适路径下。此时,着色器会报错。

        此报错为资源引用路径所致,双击打开HighlightsAndShadows着色器脚本进行修改。

        1)找到以下引用:

        修改为:

#include "EnvironmentOcclusionURP.hlsl" //occl

        2)找到以下引用:

        修改为:

#include "EnvironmentOcclusionBiRP.cginc" //occl

注意:此引用有两处,都需修改

        修改完着色器脚本后,其依赖文件也会因资源引用路径而报错。

        双击打开EnvironmentOcclusionBiRP文件进行修改。

        找到以下引用:

        修改为:

#include "EnvironmentOcclusion.cginc"

        双击打开EnvironmentOcclusionURP文件进行修改。

        找到以下引用:

        修改为:

#include "EnvironmentOcclusion.cginc"

(3)创建材质

        按照以上修改完相关文件后,便可以使用HighlightsAndShadows着色器。有两种方式可以将此着色器应用于项目材质。

1)通过着色器直接创建材质

        选中HighlightsAndShadows着色器,鼠标右键-->Create--> Material。

2)材质引用着色器

        选中项目材质,在Shader设置中,选择Meta/MRUK/Scene/HighlightsAndShadows。

(4)材质效果

        可以将材质应用于Plane物体,查看光影效果。

2、PICO4 Ultra MR 发光的球实现

        此处需要使用空间网格,具体配置不再详述,参见:PICO4 Ultra MR开发 空间网格扫描 模型导出及预览或者PICO官网空间网格

(1)材质替换及停止扫描

        需要在扫描完成后,将网格材质替换为HighlightsAndShadows材质。首先需要找到所有网格对象,扫描生成的网格一般会作为挂载PXR_SpatialMeshManager脚本的物体的子物体,所以只需以此查找网格对象即可。具体代码如下:

public Transform spatialMeshParent;  //空间网格生成的父物体,即挂载PXR_SpatialMeshManager脚本的物体
public Material meshMaterial;        //接收光照和阴影的材质

private MeshRenderer[] spatialMeshes;//空间网格上的MeshRenderer数组
private XRMeshSubsystem meshSubsystem;//网格子系统


void Start()
{
    meshSubsystem = XRGeneralSettings.Instance.Manager.ActiveLoaderAs<PXR_Loader>().meshSubsystem;
}

void Update()
{
    if (Controller.UXR_GetKeyDown(0, XR_KeyCode.APP))
    {
        spatialMeshes = spatialMeshParent.GetComponentsInChildren<MeshRenderer>();

        foreach(MeshRenderer renderer in spatialMeshes)
        {
            renderer.material = meshMaterial;
        }

        //停止扫描网格
        meshSubsystem.Stop();
    }
}

(2)灯光设置

        创建一个点光源作为小球的子物体,并置于小球中心处。

(3)小球弹跳

        若使小球不会穿过墙面并可以在地面上弹跳,需要给网格预制件添加MeshCollider组件并赋予物理材质,物理材质设置合适弹性参数;小球上则需添加SpereCollider组件和Rigidbody组件,同样设置物理材质。

3、AR实时光照实现

        基于ARFoundation进行手机AR开发,若为安卓手机,额外导入Google ARCore XR Plugin,若为苹果手机,额外导入Apple ARKit XR Plugin。

(1)AR环境搭建

        创建XR Origin,并删除场景里的MainCamera物体。

        按照下图所示设置并添加组件。

        其中,ARPlaneManager的PlanePrefab需要手动创建并制作为预制件,赋予此处。

        创建ARSession。

(2)材质替换及停止扫描

        完整代码如下。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;

public class ARDanceManager : MonoBehaviour
{
    public Material transparentMat;         //接收光照和阴影的材质
    public GameObject dancerPrefab;         //虚拟人物预制件
    public ARRaycastManager raycastManager; //射线碰撞检测器
    public ARPlaneManager m_ARPlaneManager; //平面生成器

    private List<ARRaycastHit> hits;
    private GameObject dancerObject = null;
    private bool hasSpawned = false;

    // Start is called before the first frame update
    void Start()
    {
        hits = new List<ARRaycastHit>();
    }

    // Update is called once per frame
    void Update()
    {
        if (dancerObject == null)
        {
            if (Input.touchCount == 0)
                return;
        }

        if (!hasSpawned)
        {
            var touch = Input.GetTouch(0);
            if (raycastManager.Raycast(touch.position, hits, TrackableType.PlaneWithinPolygon | TrackableType.PlaneWithinBounds))
            {
                var hitPose = hits[0].pose;
                if (dancerObject == null)//没有虚拟物体则生成
                {
                    dancerObject = Instantiate(dancerPrefab, hitPose.position, /*hitPose.rotation*/dancerPrefab.transform.rotation);
                    dancerObject.name = "Dancer";
                    m_ARPlaneManager.enabled = false;
                    SetAllPlanesTransparent();
                }
                else                      //有虚拟物体将虚拟物体锚定到射线碰撞点处
                {
                    dancerObject.transform.position = hitPose.position;
                }
            }
            hasSpawned = true;
        }
    }

    //设置渲染的平面为透明
    void SetAllPlanesTransparent()
    {
        foreach (var plane in m_ARPlaneManager.trackables)
        {
            plane.gameObject.GetComponent<MeshRenderer>().material = transparentMat;
            plane.gameObject.GetComponent<LineRenderer>().material = transparentMat;
        }
    }
}

        以上脚本挂载于场景物体,赋值相应变量即可。

四、视频教程

        视频教程参见:

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

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

相关文章

【汽车电子入门】一文了解LIN总线

前言&#xff1a;LIN&#xff08;Local Interconnect Network&#xff09;总线&#xff0c;也就是局域互联网的意思&#xff0c;它的出现晚于CAN总线&#xff0c;于20世纪90年代末被摩托罗拉、宝马、奥迪、戴姆勒、大众以及沃尔沃等多家公司联合开发&#xff0c;其目的是提供一…

【笔记】为 Python 项目安装图像处理与科学计算依赖(MINGW64 环境)

&#x1f4dd; 为 Python 项目安装图像处理与科学计算依赖&#xff08;MINGW64 环境&#xff09; &#x1f3af; 安装目的说明 本次安装是为了在 MSYS2 的 MINGW64 工具链环境中&#xff0c;搭建一个完整的 Python 图像处理和科学计算开发环境。 主要目的是支持以下类型的 Pyth…

智能守护电网安全:探秘输电线路测温装置的科技力量

在现代电力网络的庞大版图中&#xff0c;输电线路如同一条条 “电力血管”&#xff0c;日夜不息地输送着能量。然而&#xff0c;随着电网负荷不断增加&#xff0c;长期暴露在户外的线路&#xff0c;其线夹与导线在电流热效应影响下&#xff0c;极易出现温度异常。每年因线路过热…

【Hot 100】118. 杨辉三角

目录 引言杨辉三角我的解题代码优化优化说明 &#x1f64b;‍♂️ 作者&#xff1a;海码007&#x1f4dc; 专栏&#xff1a;算法专栏&#x1f4a5; 标题&#xff1a;【Hot 100】118. 杨辉三角❣️ 寄语&#xff1a;书到用时方恨少&#xff0c;事非经过不知难&#xff01; 引言 …

useMemo useCallback 自定义hook

useMemo & useCallback & 自定义hook useMemo 仅当依赖项发生变化的时候&#xff0c;才去重新计算&#xff1b;其他状态变化时则不去做不必要的计算。 useCallback 缓存函数。但是使用注意&#x1f4e2; &#xff0c;useCallback没有特别明显的优化。 *合适的场景——父…

ffmpeg 的视频格式转换 c# win10

1&#xff0c;下载ffmpeg &#xff0c;并设置环境变量。 ffmpeghttps://www.gyan.dev/ffmpeg/builds/ 2.新建.net 9.0 winform using System; using System.Diagnostics; using System.Text; using System.Windows.Forms;namespace WinFormsApp11 {public partial class Fo…

【irregular swap】An Examination of Fairness of AI Models for Deepfake Detection

文章目录 An Examination of Fairness of AI Models for Deepfake Detection背景points贡献深伪检测深伪检测审计评估检测器主要发现评估方法审计结果训练分布和方法偏差An Examination of Fairness of AI Models for Deepfake Detection 会议/期刊:IJCAI 2021 作者: 背景…

【JAVA】注解+元注解+自定义注解(万字详解)

&#x1f4da;博客主页&#xff1a;代码探秘者 ✨专栏&#xff1a;《JavaSe》 其他更新ing… ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更新的动力❤️ &#x1f64f;作者水平有限&#xff0c;欢迎各位大佬指点&…

【Doris基础】Apache Doris中的Version概念解析:深入理解数据版本管理机制

目录 引言 1 Version概念基础 1.1 什么是Version 1.2 Version的核心作用 1.3 Version相关核心概念 2 Version工作机制详解 2.1 Version在数据写入流程中的作用 2.2 Version在数据查询流程中的作用 2.3 Version的存储结构 3 Version的进阶特性 3.1 Version的合并与压…

【图像处理基石】如何进行图像畸变校正?

图像畸变校正常用于计算机视觉、摄影测量学和机器人导航等领域&#xff0c;能够修正因镜头光学特性或传感器排列问题导致的图像失真。下面我将介绍几种常用的图像畸变校正算法&#xff0c;并提供Python实现和测试用例。 常用算法及Python实现 1. 径向畸变校正 径向畸变是最常…

电力系统时间同步系统

电力系统中&#xff0c;电压、电流、功率变化等特征量测量都是时间相关函数[1]&#xff0c;统一精准的时间源对于电网安全稳定运行至关重要&#xff0c;因此&#xff0c;电力系统运行规程[2]中明确要求继电保护装置、自动化装置、安全稳定控制系统、能量管理系统和生产信息管理…

Vue使用toFixed保留两位小数的三种写法

第一种&#xff1a;直接写在js里面&#xff0c;这是最简单的 val.toFixed(2)第二种&#xff1a;在ElementUi表格中使用 第三种&#xff1a;在取值符号中使用 {{}} 定义一个方法 towNumber(val) { return val.toFixed(2) } 使用 {{ towNumber(row.equiV…

Arch安装botw-save-state

devkitPro https://blog.csdn.net/qq_39942341/article/details/148387077?spm1001.2014.3001.5501 cargo https://blog.csdn.net/qq_39942341/article/details/148387783?spm1001.2014.3001.5501 megaton https://blog.csdn.net/qq_39942341/article/details/148388164?spm…

电脑为什么换个ip就上不了网了

在日常使用电脑上网时&#xff0c;很多人可能遇到过这样的问题&#xff1a;当IP地址发生变化后&#xff0c;突然就无法连接网络了。当电脑更换IP地址后无法上网&#xff0c;这一现象可能由多种因素导致&#xff0c;涉及网络配置、硬件限制或运营商策略等层面。以下是系统性分析…

github 2FA双重认证丢失解决

文章目录 前言一. 凭借ssh 解锁步骤1.1 要求输入设备码1.2.进入二重验证界面1.3.开始2FA恢复1.4.选择使用ssh验证 二.预防措施2.1 云盘上传git_recover_codes.txt2.2 开启多源FA认证2.2.1 大陆无法使用手机验证码 三.参考资料 前言 场景&#xff1a;没有意识到github recovery …

linux驱动 - 5: simple usb device驱动

参考第2节, 准备好编译环境并实现hello.ko: linux驱动 - 2: helloworld.ko_linux 驱动开发 hello world ko-CSDN博客 下面在hello模块的基础上, 添加代码, 实现一个usb设备驱动的最小骨架. #include <linux/init.h> #include <linux/module.h> #include <lin…

ETL脚本节点使用的方式

随着大数据时代的到来&#xff0c;企业对数据处理的需求日益增长&#xff0c;ETL 作为数据整合的关键技术&#xff0c;逐渐走进我们的视野。本文将为您揭秘 ETL 脚本节点的使用方式&#xff0c;助您轻松驾驭数据处理新境界。 一、ETL脚本的优势 1.提高效率&#xff1a;ETL 脚…

PH热榜 | 2025-06-02

1. Circuit Tracer 标语&#xff1a;Anthropic的开放工具&#xff1a;让我们了解AI是如何思考的 介绍&#xff1a;Anthropic的开源工具Circuit Tracer可以帮助研究人员理解大型语言模型&#xff08;LLMs&#xff09;&#xff0c;它通过将内部计算可视化为归因图的方式展现相关…

: influxdb + grafana+JMeter

influxdb和Grafana 不安装在被测机器上&#xff0c;可以统一放到一台机器上面 1、influxdb&#xff1a;一种时序数据库&#xff0c; 可以永久性保存数据【除非手动清除和数据库坏了】 2、Grafana&#xff1a;grafana是一款用go编写的开源应用&#xff0c;用于大规模指标数据的可…

TDengine 基于 TDgpt 的 AI 应用实战

基于 TDgpt 时序数据智能体的风力发电预测 作者&#xff1a; derekchen Demo 数据集准备 我们使用公开的UTSD数据集里面的某风场发电数据&#xff0c;作为预测算法的数据来源&#xff0c;基于历史数据预测未来一天内的每15分钟的发电量。原始数据集的采集频次为4秒&#xff…