Categories: Unity

Unity:鏡面反射する床にキャラクターを表示する方法

今回はUnityのシーンで鏡面反射する床を作成した場合、床にキャラクターを映す設定を試してみたいと思います。

鏡面反射する床にキャラクターを表示する設定

今回は鏡のように鏡面反射する床に、Reflection Probeを使用してキャラクターを表示する設定について試してみました。

シーンのライティング設定

まずは以前の記事でも使用した部屋を流用してシーンに配置します。このような部屋になります。ライトはBakeライトのみです。

シーンの環境光と環境反射はすべて無効。リアルタイムGIも無効にしてあります。

リアルタイムGIも無効にしてあります。これは”Unity公式マニュアルのWebGL グラフィックス “に下記の記述を参考にしました。

グローバルイルミネーション
Unity WebGL は Baked GI のみをサポートしています。 Realtime GI は WebGL では今のところサポートされていません。なお、Non-Directional ライトマップのみがサポートされています。

ライトマップについても上記のサポート内容にあわせてDirectional Mode [Non-Directional]に変更しました。

鏡面反射マテリアルの作成

さて、鏡面反射のマテリアルを作成しましょう。新しくマテリアルを作成して床のオブジェクトに割り当て、設定を次のようにMetallicとSmoothnessの値を最大にします。

[Scene]ビューで見るとこのように床が真っ黒になりました。

Reflection Probeの設定

それではシーンにReflection Probeを追加しましょう。Reflection Probeの設定は次のように変更します。

  • Type [Realtime]
  • > Refresh Mode [Every frame]
  • > Time Slicing [All faces at once]
  • Runtime settings
  • > Box Projection [✓]
  • Cubemap capture settings
  • > Resolution [512]
  • > Clear Flags [Solid Color]
  • > Background [R0, G0, B0]

するとこのようになります。

Reflection Probeの位置を床面に対して垂直方向にカメラと対称位置に移動します。今回の場合はカメラの位置がX 0, Y 1, Z -4.5 となっているのでReflection Probeの位置はX 0, Y -1, Z -4.5 にします。これでカメラから見て床面の反射が正しく見えるようになります。

そこにキャラクターを置いてみるとこのように鏡面反射の床ができました!

移動するカメラに合わせてReflection Probeも一緒に動かす

ゲーム中にカメラが移動する場合は、Reflection Probeも一緒に動かす必要があります。そこで今回はスクリプトを使用してReflection Probeの位置を制御することにします。スクリプトの内容は次の通りです。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RealtimeReflection : MonoBehaviour
{
    // "ReflectionProbe"を格納する変数を宣言
    ReflectionProbe probe;

    // ゲームが始まる前の処理(Start関数よりも前に実行される)
    void Awake()
    {
        // 変数"probe"にReflectionProbeコンポーネントを格納
        probe = GetComponent<ReflectionProbe>();
    }

    void Update()
    {
        // カメラの座標を参照してReflectionProbeコンポーネントの座標に代入
        // Y座標のみマイナスに変換
        probe.transform.position = new Vector3(

            Camera.main.transform.position.x,
            Camera.main.transform.position.y * -1,
            Camera.main.transform.position.z
        );

        // ReflectionProbeのキューブマップを更新
        probe.RenderProbe();
    }
}

Reflection Probeにスクリプトを割り当てましょう。そしてスクリプトからReflection Probeのキューブマップを更新するので、Reflection Probeの設定でRefresh Mode [Via scripting]に変更します。

リアルタイムReflection ProbeのWebGLサポート

WebGLでのReflection Probeサポートについては”Unity公式マニュアルのWebGL グラフィックス “に解説があったので見てみました。

リフレクションプローブ
リフレクションプローブは WebGL でサポートされています。しかし、特定のミップマップへレンダリングする WebGL 仕様の制限により、滑らかなリアルタイムのリフレクションプローブはサポートされません (そのため、リアルタイムのリフレクションプローブは常に鋭いリフレクションを生成し、とても解像度が低く見えます。)。滑らかなリアルタイムのリフレクションプローブには WebGL 2.0 が必要です。
WebGL 2.0 のサポート
Unity で WebGL 2.0 を有効にするには、WebGL Player Settings の Other Settings にある Automatic Graphics API をオフにして、Graphics API として WebGL 2.0 の項目を追加します。

ということで、メニュー:Edit > Project Settings > Playerを選択。[Inspector]ウィンドウで Player Settings > Other Settings > Auto Graphics APIのチェックを外して確認するとUnityバージョン2017ではあらかじめWebGL 2.0 の項目が追加されてたのでチェックを入れたままにしました。

WebブラウザのWebGL 2.0のサポートについて

なお、Webブラウザの方でWebGL 2.0 のサポート状況について検索すると下記のニュースが見つかりました。
Google、デスクトップ版「Google Chrome」が“WebGL 2.0”に対応したことを明らかに – 窓の杜

2017年1月にリリースされたChrome 56とFirefox 51から標準でサポート。最新のOpera 47も大丈夫のようです。

今回のWebGLビルド

今回の内容をWebGLでビルドしてみました。床は一枚板のままだと単調だったのでNormalマップとMetallicマップで目地を追加。実行速度の確認用に画面左上にStandard AssetsのUtilityに含まれているFPSCounterを付けてみました。

キャラクターの操作方法はPoint & Clickです。目的場所をクリックするとキャラクターが移動します。
ダウンロードサイズ:約26MB

参考Webサイト

Reflection Probeの位置をカメラ位置に合わせて制御する方法について、下記のWebサイトの情報を参考させていただきました!

corevale