本日はShader枠です。
通常のShaderでは型や関数の定義や一般的使用可能な処理は外部ファイルに定義し、includeすることで使いまわします。
今回はComputeShaderでも同様に外部ファイルに処理を記述して読み込むことが可能であるのか気になったので調べていきます。
〇環境
・Windows11PC
・Unity6000.32f1
〇外部に定義したHLSLファイルを読み込む
今回はメインのコンピュートシェーダーを次のように構成しました。
#pragma kernel CSMain
// 出力用の構造体
struct ResultData {
float3 value;
};
// スレッドグループのサイズ(1x1x1)
[numthreads(1, 1, 1)]
void CSMain(uint3 id : SV_DispatchThreadID, RWStructuredBuffer<ResultData> resultBuffer)
{
// 入力データ
float3 a = float3(1.0, 0.0, 0.0);
float3 b = float3(0.0, 1.0, 0.0);
// 関数の呼び出し
float3 result = Function(a, b);
// 結果をRWStructuredBufferに格納
resultBuffer[0].value = result;
}
ここではただ計算をするだけですが、実際の計算は別のfuc.hlslファイルに定義しました。
float3 Function(float3 a, float3 b)
{
return a + b;
}
Unityでこれを動かすためのC#コードは以下のようになります。
using UnityEngine;
public class ComputeShaderController : MonoBehaviour
{
public ComputeShader computeShader;
private ComputeBuffer resultBuffer;
private Vector3 result;
void Start()
{
// コンピュートシェーダーの実行
DispatchComputeShader();
// 結果を表示
Debug.Log("結果: " + result);
}
void DispatchComputeShader()
{
// 結果を格納するためのComputeBufferを作成
resultBuffer = new ComputeBuffer(1, sizeof(float) * 3); // float3のサイズを指定
int kernelHandle = computeShader.FindKernel("CSMain");
// コンピュートシェーダーにバッファを設定
computeShader.SetBuffer(kernelHandle, "resultBuffer", resultBuffer);
// コンピュートシェーダーをディスパッチ
computeShader.Dispatch(kernelHandle, 1, 1, 1);
// 結果をCPU側にコピー
Vector3[] resultArray = new Vector3[1];
resultBuffer.GetData(resultArray);
// 結果をログに表示
result = resultArray[0];
Debug.Log("計算結果: " + result);
// バッファを解放
resultBuffer.Release();
}
}
ここではresultBufferというバッファを作成し、結果を受け取ります。
コンピュートシェーダー側でfnc.hlslの処理を使用するために#include fnc.hlslを定義します。
#pragma kernel CSMain
#include "fnc.hlsl"//定義
・・・
[numthreads(1, 1, 1)]
void CSMain(uint3 id : SV_DispatchThreadID, RWStructuredBuffer<ResultData> resultBuffer)
{
・・・
}
これによってコンピュートシェーダー側でFunction()の処理が使用可能となります。
今回の処理は以下の二つのベクトルの足し算です。
float3 a = float3(1.0, 0.0, 0.0);
float3 b = float3(0.0, 1.0, 0.0);
この処理を実行するとコンソールに正しい計算結果が表示されました。

以上で外部に定義したHLSLファイルをコンピュートシェーダーでも使用可能であることがわかりました。
本日は以上です。