おもちゃラボ

Unityで遊びを作ってます

【AR Foundation】 光源推定をする

f:id:nn_hokuson:20201124151400j:plain

今回はAR Foundationで光源推定をする方法を紹介します。Directional Lightのデフォルト設定では現実の光源の強さや色合と異なるため、違和感がある映像になってしまいます。AR Foundationでは撮影された映像から光源の強さと色合いを推定できる光源推定機能が用意されているので、その使い方を紹介します。

AR Foundationの光源推定でできること

ARを周辺の環境となじませるためには、その環境に応じたライトの設定をする必要があります。そのため、AR Foundationには現実の光源のパラメータを推定する機能があります。光源推定で推定できる値は次のようなものがあります。

Ammbient Intensity 環境光の強さ
Ambient Color 環境光の色温度
Main Light Direction ライトの方向
Main Light Intensity ライトの強さ

ARKitでは上記のうち、ライトの方向と強さ(Main Light DirectionとMain Light Intensity)は推定できないことに注意してください。

f:id:nn_hokuson:20180925233222p:plain:w450

それでは、AR Foundationで得られる光源の推定値をUnityのライトに設定する方法を見ていきましょう。

Unityプロジェクトの作成と下準備

次にUnityでの作業に移ります。AR Foundationを使ったプロジェクトの作り方と、その準備についてはこちらの記事に詳しく説明しています。

nn-hokuson.hatenablog.com

ここでは、ヒエラルキーウインドウにAR SessionとAR Session Originオブジェクトを配置し終えたところからスタートします。

f:id:nn_hokuson:20201112202225p:plain:w550

光源推定を行う

ヒエラルキーウインドウで、AR Session Origin の子要素のAR Cameraを選択してください。

f:id:nn_hokuson:20201122104319p:plain:w250

AR CameraにアタッチされているAR Camera ManagerのLight Estimationの項目から「Ammbient Intensity」と「Ambient Color」を選択してください。

f:id:nn_hokuson:20201122104337p:plain:w250 f:id:nn_hokuson:20201122104349p:plain:w250

これでAR Foundationで環境光の色と強さを推定できるようになります。次に推定した値を実際のライトへ反映する必要があります。そのためのスクリプトを作成します。LightEstimateという名前でC#スクリプトを作成して、次のプログラムを入力してください。

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

public class LightEstimate : MonoBehaviour
{
    [SerializeField] ARCameraManager cameraManager;
    private Light light;

    void Start()
    {
        this.light = GetComponent<Light>();        
        cameraManager.frameReceived += OnCameraFrameReceived;
    }

    void OnCameraFrameReceived(ARCameraFrameEventArgs e)
    {
        Color color = Color.white;
        float intensity = 1.0f;

        if (e.lightEstimation.averageBrightness.HasValue)
        {
            intensity = e.lightEstimation.averageBrightness.Value;
            intensity *= 2.0f;
            if (intensity > 1) intensity = 1.0f;
        }
        if (e.lightEstimation.averageColorTemperature.HasValue)
        {
            color = Mathf.CorrelatedColorTemperatureToRGB(e.lightEstimation.averageColorTemperature.Value);
        }

        Color c = color * intensity;
        light.color = c;
        RenderSettings.ambientSkyColor = c;
    }

    private void OnDisable()
    {
        cameraManager.frameReceived -= OnCameraFrameReceived;
    }
}

光源のパラメータを推定した値はAR CameraManagerから送られてきます。 推定値を毎フレーム値を取得するため、frameReceivedイベントにOnCameraFrameReceivedメソッドを追加しています。

OnCameraFrameReceivedで、実際に光源推定した値をライトに反映する作業を行っています。ライトの推定値は引数であるARCameraFrameEventArgsのlightEstimation.averageBrightness.ValueとlightEstimation.averageColorTemperature.Valueに格納されています。推定した光源の色と強度をかけ合わせた値をDirectional Lightのcolorに設定しています。

また、ライトに反映すると同時にRenderSettings.ambientLightにも値を設定しています。これにより、環境から受ける光の強さと色も同時に設定しています。この設定はメニューのWindow/Rendering/LightingのEnvironment Lightから設定するパラメータに相当します。

f:id:nn_hokuson:20201122104531p:plain:w450

スクリプトをアタッチする

作成したLightEstimateスクリプトをDirectional Lightにドラッグ&ドロップしてアタッチしてください。

f:id:nn_hokuson:20201124144642p:plain:w650

次に今アタッチしたスクリプトのAR Camera Managerの欄に、AR Session Origin/ARCameraをドラッグ&ドロップしてください。

f:id:nn_hokuson:20201124144653p:plain:w650

実行結果

これでAR Tracked Object Managerの設定は終わりです。最後にAR Foundationの各種設定を次の記事を参考にして行い、実行してみてください。

nn-hokuson.hatenablog.com

ビルドして実行すると、ライトの色がモデルに反映されて、より自然なARになっていることが確認できます。

f:id:nn_hokuson:20201124151232g:plain:w500

まとめ

この記事では、AR Foundationを使って光源のパラメータを推定する方法を紹介しました。また、AR Foundationの基礎になっているARKitについては「swiftで作る ARKit超入門」がオススメです!こちらも、ぜひ参照ください。
booth.pm