ARFoundation之路-Environment Probe之二

版權聲明:Davidwang原創文章,嚴禁用於任何商業途徑,授權後方可轉載。

  在ARFoundation中,環境反射功能可以使虛擬物體反射真實世界中的環境信息,從而更好的將虛擬場景與真實世界環境混合。

(一)使用Environment Probe

  AR環境反射是一個高級功能,需要學習掌握相關知識才能運用自如。在ARFoundation使用環境反射的基本步驟如下:
1、在場景中的AR Session Origin對象上掛載AR Environment Probe Manager組件並作相應設置;
2、確保需要反射的虛擬對象帶有反射材質並能反射Probe;
3、使用自動或者手動方式設置反射探頭捕獲環境信息供反射體使用。

  按照上述步驟,首先我們在AR Session Origin對象上掛載AR Environment Probe Manager組件,我們選擇手動設置反射探頭,因此我們不勾選“Automatic Placement”並選擇紋理過濾模式爲“Trilinear”,如下圖所示。
在這裏插入圖片描述
  然後給需要反射的虛擬物體設置反射材質,本節中我們使用的是Unity中的Standard Shader,並設置其Mesh Renderer中的Light Probes 和Reflection Probes均爲Blend Probes以使其使用反射探頭生成的Cubemap,勾選上Standard Shader中Forward Rendering Options節的Specular Highlights和Reflections,如下圖所示。

在這裏插入圖片描述
  最後我們新建一個C#腳本AppController,並編寫如下腳本。

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

[RequireComponent(typeof(ARRaycastManager))]
public class AppController : MonoBehaviour
{
    public GameObject spawnPrefab;
    static List<ARRaycastHit> Hits;
    private ARRaycastManager mRaycastManager;
    private AREnvironmentProbeManager mProbeManager;
    private AREnvironmentProbe mProbe;
    private GameObject spawnedObject = null;
    private void Awake()
    {
        Hits = new List<ARRaycastHit>();
        mRaycastManager = GetComponent<ARRaycastManager>();
        mProbeManager = GetComponent<AREnvironmentProbeManager>();
    }

    void Update()
    {
        if (Input.touchCount == 0)
            return;
        var touch = Input.GetTouch(0);
        if (mRaycastManager.Raycast(touch.position, Hits, TrackableType.PlaneWithinPolygon | TrackableType.PlaneWithinBounds))
        {
            var hitPose = Hits[0].pose;
            var probePose = hitPose;
            probePose.position.y += 0.2f;
            if (spawnedObject == null)
            {
                spawnedObject = Instantiate(spawnPrefab, hitPose.position+ new Vector3(0f,0.05f,0f), hitPose.rotation);
                mProbe = mProbeManager.AddEnvironmentProbe(probePose, new Vector3(0.6f, 0.6f, 0.6f), new Vector3(1.0f, 1.0f, 1.0f));
            }
            else
            {
                spawnedObject.transform.position = hitPose.position;
                mProbe.transform.position = hitPose.position;
            }
        }
    }
}

  在上述代碼中,我們手動添加了一個反射探頭,代碼的其他內容稍後詳細進行分析,編譯運行,效果如下,左圖爲沒有反射的虛擬物體,右圖爲採用了環境反射的虛擬物體,可以看到,虛擬物體反射了計算機屏幕及其他周邊環境。
在這裏插入圖片描述

(二)AR Environment Probe Manager

  在ARFoundation中,由AR Environment Probe Manager負責管理環境反射相關任務,AR Environment Probe Manager有三個屬性,Automatic Placement、Environment Texture Filter Mode、Debug Prefab。

  • Automatic Placement

  ARFoundation既允許自動放置反射探頭也允許手動放置反射探頭,或者兩者同時使用。在自動放置模式下,由應用程序設備自動選擇合適的位置放置反射探頭。在手動放置模式下,由開發人員在指定位置放置反射探頭。自動放置由底層SDK提供算法,自主選擇在何處及如何放置反射探頭,以獲得比較高質量的環境信息,自動放置的確定依賴於在實際環境中檢測到的關鍵特徵點信息。手動放置主要是爲了獲得對特定虛擬對象的最精確環境信息,綁定反射探頭與虛擬對象位置可以提高反射渲染的質量,因此,手動將反射探頭放置在重要的虛擬對象中或其附近會產生爲該對象生成的最準確的環境信息。通常而言,自動放置可以提供對真實環境比較好的宏觀環境信息,而手動放置能提供在某一個點上對周圍環境更準確的環境映射從而提升反射的質量。

  反射探頭負責捕獲環境紋理信息,每個反射探頭都有一個比例(Scale)、方向(Orientation)、位置(Position)和大小(Size)。比例、方向和位置屬性定義了反射探頭相對於Session空間的空間信息,大小則定義了反射探頭反射的範圍,無限大小表示環境紋理可用於全局,而有限大小表示反射探頭只能捕獲其周圍特定區域的環境信息。

  在手動放置時,爲了使放置的反射探頭能更好的發揮作用,通常反射探頭的放置位置與大小設置應遵循以下原則:
  1、反射探頭的位置應當放在需要反射的虛擬物體頂部中央,高度應該爲虛擬物體高的兩倍。這可以確保反射探頭下部與虛擬物體下部對齊,並捕獲到虛擬物體放置的平面的環境信息。
  2、反射探頭的長與寬應該爲虛擬物體長與寬的三倍,確保反射探頭能捕獲到虛擬物體周邊的環境信息。
  3、反射探頭可以朝向任何方向,但是,Unity的反射探頭只支持軸對齊模式,因此,最好在放置時就設置成軸對齊。

  • Environment Texture Filter Mode

  環境紋理過濾模式主要可選爲Point、Bilinear、Trilinear,爲達到比較好的視覺效果,一般我們選擇Bilinear或者Trilinear

  • Debug Prefab

  該屬性用於在調試時可視化反射探頭,在發佈時應置空。

  在ARFoundation中,AR Environment Probe Manager提供瞭如下方法管理環境反射:

方法 描述
AddEnvironmentProbe(Pose pose, Vector3 scale, Vector3 size) 添加一個AREnvironmentProbe,Pose指定了放置的位置與方向,Scale指定了相對於Session空間的比例,Size指定了反射探頭可探測的環境範圍。
GetEnvironmentProbe(TrackableId trackableId) 根據TrackableId獲取一個AREnvironmentProbe。
RemoveEnvironmentProbe(AREnvironmentProbe probe) 移除一個AREnvironmentProbe,如果移除成功則返回True,否則返回False。
environmentProbesChanged 在反射探頭髮生變化是觸發的事件,如一個新的environment probe創建、對一個現存的environment probes進行更新、移除一個environment probes。

(三)性能優化

  在AR中使用反射探頭反射環境可以大大的增強虛擬物體的可信度,但由於AR攝像頭獲取的環境信息不充分,因此爲更好的揚長避短,在AR中使用反射探頭反射真實環境需要注意以下幾點:

  1、避免精確反射
  如上所述,AR中從攝像頭獲取的信息不足以對周圍環境進行精準的再現,即不能生成完全的Cubemap,因此反射體對環境的反射也不能做到非常精準,希望利用反射探頭實現對真實環境的鏡面反射是不現實的。通常的做法是合理的設計,既能發揮反射增強虛擬物體可信的優勢,但也要同時避免對真實環境的精確反射。同時,因爲在AR中不能獲取到完全的Cubemap並且Cubemap更新也不實時(爲降低硬件消耗),通常在小面積上可以使用高反射率而在大面積上使用低反射率,達到既營造反射效果又避免反射不準確而來帶負面作用。

  2、對移動對象的處理
  烘焙的環境貼圖不能反應環境的變化,實時的反射探頭又會帶來過大的性能消耗,對移動對象的反射處理需要特別進行優化。在設置反射探針時可以考慮以下方法:
  如果移動物體移動路徑可知或可以預測,可以提前在其經過的路徑上放置多個反射探頭並進行烘焙,這樣移動物體可以根據距離的遠近對不同的反射探頭生成的Cubemap採樣。
  創建一個全局的環境反射,如Skybox,這樣當移動物體移動出某個反射探頭的範圍時仍然可以反射而不是突然出現反射中斷。
  當移動物體移動到一個新的位置後重新創建一個反射探頭並銷燬原來位置的反射探頭。

  3、防止濫用
  在AR中,生成Cubemap不僅僅是在某個點拍攝6個方向的照片做貼圖,因爲真實環境信息的不充分,AR需要更多時間來收集來自攝像頭的圖像信息,並且還要使用人工智能算法對缺少的信息進行計算補充,這是個耗時耗性能的過程。過多的使用反射探頭不僅不會帶來反射效果的實質性提升,相反會導致應用卡頓和電池的快速消耗。在AR中,當用戶移動位置或者調整虛擬對象大小時,應用程序都會重新創建反射探頭,因此我們需要限制此類更新,如更新頻率不應大於每秒1次。

  4、避免突然切換
  突然的移除反射探頭或者添加新的反射探頭會讓用戶感到不適。在ARFoundation中使用自動放置反射探頭的模式下,只要Session開始,會創建一個全局的類似Skybox的大背景以防止反射突然的切換。在手動放置時,開發者應該確保反射的自然過渡,確保虛擬物體始終能反映適合的環境,或者使用一個全局的在各種環境下都能適應的靜態Cubemap作爲過渡手段。

參考文獻

1、Adding Realistic Reflections to an AR Experience Adding Realistic Reflections to an AR Experience
2、AR Environment Probe Manager AR Environment Probe Manager

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章