【ShaderGraph】Quadで擬似的な3D空間を表現したサンプルを紹介

本記事は「[サムザップ #2 Advent Calendar 2020](https://qiita.com/advent-calendar/2020/sumzap2)」の12/5の記事です。
昨日の記事は @hiroki_shimada さんの「[Googleフォトが有料化！？みんなどうする？](https://qiita.com/hiroki_shimada/items/8930e70283422da353b4)」でした。

# はじめに
オープンワールドのゲームなどでよく見る"ビルの中の部屋"ってどう表現するのか。
部屋の中の細々としたオブジェクトを1つ1つメッシュ書いてたらパフォーマンス悪いですよね…
そこで試行錯誤して、平面の中に擬似的な3D空間をShaderGraph使って実現してみたので、そのサンプルを紹介しようと思います。

って言っても、テキストだと分かりづらいので、先にアウトプットがこちらになります。

# 今回作成したもの
今回作ったものはこちらになります。
![FakeInteriorDemo_720.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209889/3c09a476-0dac-f6d6-3d1b-179f9ddadea8.gif)
※Gifにしている都合上、フレームレート下げててカクカクなので、滑らかな動画のサンプルはこちらをご覧ください。
[【ShaderGraph】Quadで擬似的な3D空間を表現したサンプル（YouTube）](https://youtu.be/dRMoQjpGssw)

# 準備
「Universal Render Pipeline（以下、Universal RP）」と「Shader Graph」の導入から行います。

## 使用したバージョン情報
今回、使用した環境のバージョン情報は下記になります。

|項目|バージョン|
|:---|---:|
|Unity|Unity2019.4.10f1|
|Universal RP|7.3.1|
|Shader Graph|7.3.1|

## UniversalRP,ShaderGraphの設定
PackageManagerの中身はこんな感じです。
![PackageManager.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209889/92b85769-4b30-d6f9-a500-26bfd69515c2.png)
※最小限に抑えています
「In Project」でフィルタリングかけて、UniversalRPがなければ、PackageManagerからインストールが必要です。
以前までは、UniversalRPとShaderGraphはそれぞれインポートする必要があった記憶があるのですが…
ここにShaderGraphがリストアップされていなくても、「Unity Registry」でShaderGraphを検索すると入っている表示になりました。
![PackageManager_ShaderGraph.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209889/25a095c4-48b4-9183-e0fc-a3668d1bd3c6.png)
今回は
[Create] > [Rendering] > [Universal Render Pipeline] > [Pipeline Assets(Forward Renderer)]
でPipeline Assetsを作成し、そのままProjectSettingsのGraphicsに設定しています。
![ProjectSettings.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209889/bda6e5f0-6088-dee7-d449-6c48cb3fe2bd.png)

## テスト用のCubemapを準備
一応、今回テスト用に使用したCubemapの画像を貼っておきます。
![test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209889/618b67c4-05c9-f66e-9cc2-0cf3fde5ed16.png)

# 作成したShaderGraphの紹介
作成したShaderGraphの全体像がこちらになります。
![FakeRoom_ShaderGraph.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209889/4915b1f7-b8e4-1c2e-7a7f-77f42c8e492a.png)
量が多いので、番号振った順に紹介していこうと思います。
![FakeRoom_ShaderGraph 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209889/d87be0f1-0241-c136-a96a-f2b939afacd6.png)

## 1.Calculate Virtual Room Bounding Box
擬似的な3D空間のBoundingBox計算をしている部分になります。
![Calculate Virtual Room Bounding Box.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209889/36813cdd-b37f-79e3-d557-2ac05fc64e78.png)

## 2.Get Tangent View Vector
Viewの正接(tanθ)Vectorを計算している部分になります。
![Get Tangent View Vector.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209889/50ff3e9f-fc7a-ebf7-5f68-e4f91857452c.png)

## 3.Find Real Window Corner/Get Wall Corners
1,2の計算結果を使って、擬似3D空間のCorner部分の計算をしています。
![Find Real Window Corner:Get Wall Corners.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209889/5b36eddb-1392-16cd-7423-925ee4e57d8b.png)

## 4. Raycasting + Intersection/Flip back the axis/Sample the Cubemap Interior
1,2,3の計算結果を使用して、平面上のMeshに擬似的な3D空間を表現させる為の計算をし、Cubemap画像をQuadに貼ります。
![otherGraph.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209889/7b1a6418-01a3-5c09-14f0-7f5abe862b45.png)
ここまででQuadで擬似的な3D空間を表現する部分は、ほぼ完成です。
![TestDemo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209889/8e74f375-8301-8b93-65bc-b79db5504c90.png)
「Quadで擬似的な3D空間を表現する」というのは、基本的に窓越しに部屋を覗くなどで中のオブジェクトを表示する際に、パフォーマンス的に全てメッシュ作成する訳にもいかないので、平面上に3D空間がその中にあるように見せる手法になります。
なので、窓ガラスっぽい表現を足していきます。

## 5.Sample Sky Cubemap
窓で反射して写る空を表現するために、空模様のCubemapを使用して、反射した空をBlendします。
![Sample Sky Cubemap.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209889/5970993d-cf2e-3e87-a6cc-35dab41a0ebe.png)

## 6.Side Powered Reflections/Limit Side Reflection View Angle
見る角度によって反射具合を計算します。
![Side Powered Reflections:Limit Side Reflection View Angle.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209889/98577577-f583-dc1b-1507-9ac22552ae88.png)

## 7.最終的な計算/Blend
4,5,6の計算結果をblend/Lerpして、UnlitMasterのColorで描画させます。
![finishCalcurate.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209889/5a6091ce-8776-aa31-ae0c-028558d3f331.png)

# Re: 今回作成したもの
再掲載になりますが、今回作ったものはこちらになります。
![FakeInteriorDemo_720.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209889/3c09a476-0dac-f6d6-3d1b-179f9ddadea8.gif)
※Gifにしている都合上、フレームレート下げててカクカクなので、滑らかな動画のサンプルはこちらをご覧ください。
[【ShaderGraph】Quadで擬似的な3D空間を表現したサンプル（YouTube）](https://youtu.be/dRMoQjpGssw)

# 最後に
明日は @arima_moto さんです。