Unity 6でCompute ShaderをWebGLで使用してみた

プログラム

Unity6でWebGL版の強化が入ったらしく,どうやらCompute Shaderが使えるようになったみたいです.これは期待大.早速試してみるとエラーでつまったので,その解決方法を記しておきたいと思います.

問題のコード

今回はテストということで,ただ単にrender textureの色を赤色にするだけのコードです.
コードは,適当にRawImageなどを作ってアタッチしてあげれば大丈夫です.
ただし,このコードは一部間違っているので,参考にする際はこれを見てください.

using UnityEngine;
using UnityEngine.UI;

public class ComputeShaderExample : MonoBehaviour
{
    public ComputeShader computeShader;
    private RenderTexture renderTexture;

    void Start()
    {
        renderTexture = new RenderTexture(256, 256, 0);
        renderTexture.enableRandomWrite = true;
        renderTexture.Create();

        computeShader.SetTexture(0, "Result", renderTexture);

        int threadGroupsX = renderTexture.width / 8;
        int threadGroupsY = renderTexture.height / 8;
        computeShader.Dispatch(0, threadGroupsX, threadGroupsY, 1);
        GetComponent<RawImage>().texture = renderTexture;
    }
    void OnDestroy()
    {
        if (renderTexture != null)
            renderTexture.Release();
    }
}
#pragma kernel CSMain

RWTexture2D<float4> Result;

[numthreads(8, 8, 1)] 
void CSMain (uint3 id : SV_DispatchThreadID) {
    Result[id.xy] = float4(1, 0, 0, 1);
}

発生した問題1

早速上のコードをビルドしてブラウザで見てみると…

こんな感じのエラーが出ます.

htdocs.framework.js:9 IndexOutOfRangeException: Invalid kernelIndex (0) passed, must be non-negative less than 0.

もちろん,KernelIndexも調べてみましたが,0未満ではありませんでした.

原因・解決1

Unity 6なので,新しすぎて情報がなくて苦労しましたが,以下の動画で説明してくれていました(これ見たらこの記事意味ないかも…).


結論としては,Graphics APIの設定が間違えていました.
Unity 6では新たにWebGPUに対応したらしく,Compute ShaderはWebGL 2では利用できないようです.なので,Graphic APIをWebGPUに変える必要があります.ただし,現段階(2024/11/11)では正式対応ではなく,デフォルトでは隠れていて使用できないようです.しばらくしたら,デフォルトで選択できるようになるそうです.
以下に利用する手順を示しておきます.

WebGPUを使えるようにする

まず,ProjectSettings.assetを書き換えます.場所は,プロジェクトが置かれているフォルダ->ProjectSettings->ProjectSettings.assetです.見つけたら適当なエディタで開いて,以下の画像のようにwebGLEnableWebGPUTrue(1)にしてあげます.

Graphics APIをWebGPUにする

次はUnityのeditorに戻って,APIの設定を変更します.場所はおなじみのPlayer settingで変更します.
場所は,Build Project->Player Settings->Other Settings->Graphics APIsです.開けたら以下の手順で設定します.

  • Auto Graphics APIのチェックを外す
  • WebGPUをAPIsのリストに追加
  • WebGPUをWebGL2の上に持ってくる.

問題2

先程のInvalid kernelIndexエラーは消えましたね.
しかし,Texture Formatの問題が残っています.

エラー内容としては以下です.

The layout's binding format (TextureFormat::RGBA8Unorm) doesn't match the shader's binding format (TextureFormat::RGBA32Float).

原因・解決法2

Render Textureのインスタンスを作成する際,カラーフォーマットを指定しないと,プラットフォームに合わせて,自動で選んでくれるようです.なので,明示的にカラーフォーマットを指定して合わせてあげます.修正しコードを以下に示します.

using UnityEngine;
using UnityEngine.UI;

public class ComputeShaderExample : MonoBehaviour
{
    public ComputeShader computeShader;
    private RenderTexture renderTexture;

    void Start()
    {
        // renderTexture = new RenderTexture(256, 256, 0);ここを以下のように変更.
        renderTexture = new RenderTexture(256, 256, 0, RenderTextureFormat.ARGBFloat);
        renderTexture.enableRandomWrite = true;
        renderTexture.Create();

        computeShader.SetTexture(0, "Result", renderTexture);

        int threadGroupsX = renderTexture.width / 8;
        int threadGroupsY = renderTexture.height / 8;
        computeShader.Dispatch(0, threadGroupsX, threadGroupsY, 1);
        GetComponent<RawImage>().texture = renderTexture;
    }
    void OnDestroy()
    {
        if (renderTexture != null)
            renderTexture.Release();
    }
}
#pragma kernel CSMain

RWTexture2D<float4> Result;

[numthreads(8, 8, 1)] 
void CSMain (uint3 id : SV_DispatchThreadID) {
    Result[id.xy] = float4(1, 0, 0, 1);
}

結果

今度はいい感じに動きました.

おわりに

情報が少なくて自分は苦労したので,同じ様に困っている方の参考になれば幸いです.
今回使用したプロジェクトは,一応GitHubに置いておいたので,ご自由にお使いください.

Build software better, together
GitHub is where people build software. More than 100 million people use GitHub to discover, fork, and contribute to over...

コメント

タイトルとURLをコピーしました