Unity 6のWebGPUを試す(GitHub ActionsでDeployまで)

## はじめに

先週開催されたCEDEC2024にて、`リリース間近！Unity 6 のすべて`という講演がありました。

> 現在はYouTubeにて無料で公開されています。
> <iframe width="560" height="315" src="https://www.youtube.com/embed/9sBQd74HVtg?si=8gQ9n70dCwF9r2Zs" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

こちらの講演にてUnity公式の方が`WebGPUを使えばVFXGraphが使えるようになり、Browser上で共有ができるようになった`というようなことをおっしゃっていたので、今回はこれを実際に試してみたいと思います。

ということで今回は最新のUnity 6で**WebGPU&VFXGraphをGitHub ActionsでPagesにDeployしてgithub.io上で公開する**ところまで紹介したいと思います。

## 公式デモ

https://boat-demo.cds.unity3d.com/

https://vfx-demo.cds.unity3d.com/

## 環境

OS - Windows 11 Pro
Browser - Microsoft Edge 128
Unity - Unity 6 Preview (6000.0.18f1) Personal License
Module - Visual Effect Graph 17.0.3

## Unity 6

### インストール

何はともあれまずUnityのインストールから始めます。

![0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660536/143a39ba-d828-42bd-82d9-7ebb6935a45e.png)

WebGPUのビルドに`WebGL Build Suppoert`のModuleが必要なのでこちらをインストールします。

(Moduleでは名前にWebGLとありますが、WebGPUも実験的機能としてこちらに入っています。)

### プロジェクトを作成

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660536/064f3091-2665-8e39-ae5c-73759e78588a.png)

`Universal 3D`を選択します。プロジェクト名は適当に`unity6-webgpu-testcodes`としました。

:::note warn
HDRPではWebGPUが利用できないので注意してください。
:::

> ![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660536/23a64d28-ff7e-aef8-9828-a854901d6191.png)
> メジャーバージョンが更新される毎にUnityのロード画面の画像が変わりますが、Unity 6からはロード画面自体が変更されていました。新しい感じがしてとても良いですね！

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660536/0e3f2ad4-0942-b801-7158-00c3db58a425.png)

VFXはデフォルトでは利用できないので、UPMからPackageを追加する必要があります。

`Window`→`Package Manager`を選択してPackage Managerを開き、`Unity Registry`の中の`Visual Effect Graph`をInstallします。

ここからはAssetを用意していきます。初めに専用のSceneを作成します。名前は`VFX_Dog`としました。

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660536/cc85d80f-196a-0459-bc69-5be42fc18bb3.png)

また、テスト用Meshとして、私が学生時代に勉強用で作成した犬のような3DModelを使います。

![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660536/07e4a3ed-d537-3bb2-e4b1-73365b44c213.png)

VFX GraphでMeshを利用するには、pCacheで点群データに変換する必要があります。

`Window`→`Visual Effects`→`Utilities`→`Point Cache Back Tool`を選択してpCache Toolを開き、`Export UVs`にチェックし`Save to pCache file...`で生成します。名前は`P_Dog`としました。

次に簡単なVFX Graphを作成していきます。

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660536/7a27b114-f38f-e3d1-286f-7c61728b9e54.png)

右クリック→`Create`→`Visual Effects`→`Visual Effect Graph`で新しく作成します。今回は`Simple Loop`というテンプレートから作成していきました。名前は`V_Dog`としました。

![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660536/2e603ab1-6188-2b36-67f6-5d0c5d5dd045.png)

ここまで追加したAssetです。

![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660536/5de2caa0-aa7b-c06e-8a7c-477ccee56539.png)

Prefabの中身はMeshとVFXになります。

![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660536/2e24d97a-5628-940d-df6f-24cc02eaed3f.png)

VFX Graphで作成していきます。先ほど作成したAssetをダブルクリックすることでEditorが表示されます。今回外部変数は利用しないので、右上の`Blackboard`ボタンをクリックして非表示にします。

![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660536/91ded5d9-e4c0-b8e6-7687-bfd792206b3d.png)

VFX Graphの全体像です。詳しくは説明しませんが、点群データをもとにParticleを生成し、テクスチャからサンプリングした色をそのまま色として、`Turbulence`でいい感じに動かすようにしています。

![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660536/ce815118-64bd-6c6c-da7e-9cb3dd94f0ce.png)

Editor上でのレンダリング結果です。飛沫シミュレーションみたいになってしまいましたが、私はこういったセンスがないのでとりあえずこれで進めます。

![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660536/81a50c08-5f25-3ef1-d3f0-dbe25a84c6ce.png)

Buildに向けた準備を行っていきます。まず、Unity 6で新しくなったBuild Profilesで変更していきます。SceneLiseから右クリックで`Sample Scene`を削除し`Add Open Scenes`で現在のSceneを追加します。

![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660536/77a423ff-19b8-55ab-d740-3943f7f07aca.png)

`Web`では特に編集する項目はありませんが、実はまだWebGPUが有効化されていません。現状まだUI上で有効化するオプションが追加されていないため、TextEditorで`Project Settings`を直接変更する必要があります。

`ProjectSettings/ProjectSettings.asset`を適当なTextEditorで開き、以下のように変更します。

```diff
  webGLMemoryLinearGrowthStep: 16
  webGLMemoryGeometricGrowthStep: 0.2
  webGLMemoryGeometricGrowthCap: 96
- webGLEnableWebGPU: 0
+ webGLEnableWebGPU: 1
  webGLPowerPreference: 2
  webGLWebAssemblyTable: 0
  webGLWebAssemblyBigInt: 0
```

これでWebGPUが利用できるようになりした。`Player Settings`へ移動します。

![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660536/796438c2-4df5-7d7f-2a49-b7e8ae09e1fe.png)

`Auto Graphics API`のチェックを外し、`Graphics APIs`を`WebGPU (Experimental)`に置き換えます。

![15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660536/1b3a5b6d-896e-9648-9c18-42fb4924e93b.png)

このようになっていればOKです。

![16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660536/bf9ccc2b-8fd2-09b3-eba1-5b28c2fb13ca.png)

また、GitHub Pagesで公開する場合は圧縮関係がデフォルトのまま以下のようなエラーがでるので、`Decomporession Fallback`のチェックを入れます。

```
Unable to parse Build/WebGL.framework.js.gz! This can happen if build compression was enabled but web server hosting the content was misconfigured to not serve the file with HTTP Response Header "Content-Encoding: gzip" present. Check browser Console and Devtools Network tab to debug.
```

### 動作確認

これで一度`Web`にPlatformを切り替えて、`Build And Run`をクリックします。Buildが完了すると、ブラウザが自動で起動し、ページが表示されます。

![18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660536/b455e2d4-93e4-7f81-8f5b-e86bb4f805c9.png)

飛沫犬が表示されるようになりました。

:::note warn

現在、私もメインで利用しているFirefox(Version 130)では、StableバージョンではまだWebGPUがサポートされていないためこのように表示されません。(Experimental(Nightly)ではフラグで有効化可能)

![17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660536/26a2c61a-dbda-5166-0d6b-7bc483324f35.png)

現在どのBrowserがWebGPUをサポートしているかは以下のサイトで確認することができます。

https://caniuse.com/webgpu

:::

これでUnity側の必要最低限の対応は終わりです。次はこのUnityプロジェクトをGitHub Actionsを利用してBuild&Deployしていきます。

## GitHub

今回のGitHub Repositoryはこちらになります。

https://github.com/shirokuma1101/unity6-webgpu-testcodes

CC0なので、好きに使ってください。

### GameCI用の準備

:::note warn
GitHub ActionsではGameCIを利用してBuildしていきますが、Personal Licenseを利用している場合、従来の方法では認証できなくなったため注意が必要です(回避策もありましたが、塞がれました)。ここではPersonal Licenseを利用する場合の手順を説明します。

https://github.com/game-ci/documentation/issues/408
:::

まず、UnityのPersonal Licenseを取得する必要があります。

![19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660536/177e8e5b-15ff-04b4-10bf-b196999c068c.png)

`歯車`→`License`→`Add`→`Get a free personal license`で新しいLicenseを取得します。

Windowsの場合は以下に保存されています。

`C:\ProgramData\Unity\Unity_lic.ulf`

また、Unity Accountを3rd party(Googleとか)で作成した場合はパスワードを再設定する必要があります。(3rd party認証でのログインではなく、メールアドレスとパスワードでもログインできる状態にする必要があります。)

![21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660536/14ceb9e1-5609-b9df-e4bf-b30796124457.png)

Repositoryの`Settings`→`Security/Secrets and variables`→`Actions`の`Repository secrets`で先ほどの情報をそれぞれ`UNITY_EMAIL`、`UNITY_PASSWORD`、`UNITY_LICENSE`として追加します。(LicenseはUnity_lic.ulfファイルをTextEditorで開き、中身をそのままコピペする。)

![20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660536/6eed8736-8f9b-a10b-2a6f-a1c8556fbc89.png)

また、Pagesの設定で、`Build and deployment`の`Source`を`GitHub Actions`に変更します。これを変更しておかないと、Deploy時にエラーがでます。

最後にGitHub Actionsを定義する構成ファイルを作成します。

### GitHub Actions

ファイルは`.github/workflows/main.yaml`に作成します。

```yaml
name: Build and deploy WebGPU

on:
  workflow_dispatch:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

jobs:
  ubuntu-build:
    runs-on: ubuntu-latest

    permissions:
      checks: write

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Cache library
        uses: actions/cache@v4
        with:
          path: Library
          key: Library-${{ hashFiles('Assets/**', 'Packages/**', 'ProjectSettings/**') }}
          restore-keys: |
            Library-

      - name: Build project
        uses: game-ci/unity-builder@v4
        env:
          UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
          UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
          UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
        with:
          allowDirtyBuild: true
          targetPlatform: WebGL

      - name: Upload artifacts
        uses: actions/upload-pages-artifact@v3
        with:
          path: build/WebGL/WebGL

  ubuntu-deploy:
    runs-on: ubuntu-latest

    needs: ubuntu-build

    permissions:
      pages: write
      id-token: write

    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}

    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4
```

内容としては簡単に

- なにかPushされたら実行する
- LibraryフォルダはAsset関連が変更されない場合はCacheする
- GameCIを利用してWebGL Platformとしてビルド
- ArtifactをGitHub PagesにDeploy

となります。

### 最終確認

成果物は`User名.github.io/Repository名/`にDeployされます。

私の場合は以下のURLにDeployされました。

https://shirokuma1101.github.io/unity6-webgpu-testcodes/

![22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660536/29ba5222-749e-941f-f911-42fdabd62b8a.png)

GitHub Pages上でも飛沫犬を確認することができました🎉

## おわりに

WebGPUは前々から触ってみたいとは思っていたのですが、今までは実行確認まで敷居が少し高いものとなっているイメージでした。(以下の記事は私の先輩が書いた素晴らしい記事)

https://zenn.dev/kd_gamegikenblg/articles/a5a8effe43bf3c

しかし今はUnityで実験的機能とは言え簡単にビルドするところまでできるようになっていました。個人的にBrowserで実行するApplicationの構想があったので、Unity 6正式Release時には開発に着手したいです。