コンテンツにスキップ

カーネルの実行

書き方説明
Gpu.Buffer(64, 64)バッファの生成
Gpu.Swap(ref a, ref b)2 つの入れ替え
Gpu.Run(nameof(Step), next, current)実行の呼び出し
Gpu.Run(nameof(Step), next, current, phase)値を渡した実行
Gpu.Run("Step", next, current)名前の文字列指定
Gpu.Run(nameof(Fade), current, next)複数のカーネル
Gpu.Show(current, display)面への表示
Gpu.Texture(current)テクスチャとしての取り出し
書き方説明エラー理由代わりに
カーネルが static でない[TsukimiKernel] を付けたメソッドがインスタンスのものTUKI0001設計static にする
戻り値が Color4 でないカーネルが別の型を返しているTUKI0001設計Color4 を返す
第 1 引数が KernelId でないカーネルの引数の並びが違うTUKI0001設計第 1 引数を KernelId にする
Gpu.Run の引数の数が合わないカーネルの引数と数が違うTUKI0001設計数を合わせる
Gpu.Run の引数の型が合わないカーネルの引数と型が違うTUKI0001設計型を合わせる
Gpu.Run(k, next, next)出力先のバッファを入力にも渡しているTUKI0001設計別のバッファを渡す
Gpu.Run("NotAKernel", ...)[TsukimiKernel] の付いていないメソッド名を渡しているTUKI0001設計nameof で綴りを固定する
Gpu.Pack16x2 をカーネルの外で呼ぶ詰め込みをカーネルの外に書いているTUKI0001, TUKI0099, TUKI0102設計カーネルの中で詰める

上の 8 形は、すべて同じ文言で断られます(TUKI0001「Udon に落とせない C# 構文です」。 最後の 1 つだけ、型が無い旨も併せて出ます)。どれもカーネルの規則を破ったものなのに、 文言は Udon の話をするので、文面から原因を絞り込めません。断られたら、上の表の行を 上から順に当たるのが早道です。

カーネルを 1 つ書くと、見せる面を差す公開フィールドが 1 つ増えます。何も差さないまま Gpu.Show まで進むと、実機で無言のまま止まります。コンパイラはこれを警告として出すだけで、 コンパイルは通します。

1 セル 4 成分・各 8 ビットで、内容はゼロで始まります。

using UnityEngine;
using Tsukimi;
public class ParHostBuffer : TsukimiBehaviour
{
private GpuBuffer2D current;
private GpuBuffer2D next;
void Start()
{
current = Gpu.Buffer(64, 64);
next = Gpu.Buffer(64, 64);
}
[TsukimiKernel]
static Color4 Step(KernelId id, GpuBuffer2D prev)
{
return new Color4(prev[id].R, 0f, 0f, 1f);
}
void Update()
{
Gpu.Run(nameof(Step), next, current);
}
}

前の結果を次の入力にするときに使います。自分で書いたメソッドの引数に ref は使えませんが、Gpu.Swap には使えます。

using UnityEngine;
using Tsukimi;
public class ParHostSwap : TsukimiBehaviour
{
private GpuBuffer2D current;
private GpuBuffer2D next;
void Start()
{
current = Gpu.Buffer(64, 64);
next = Gpu.Buffer(64, 64);
}
[TsukimiKernel]
static Color4 Step(KernelId id, GpuBuffer2D prev)
{
return new Color4(prev[id].R, 0f, 0f, 1f);
}
void Update()
{
Gpu.Run(nameof(Step), next, current);
Gpu.Swap(ref current, ref next);
}
}

第 2 引数が出力先です。第 3 引数以降が、カーネルの第 2 引数以降に順番どおり対応します。

using UnityEngine;
using Tsukimi;
public class ParHostRun : TsukimiBehaviour
{
private GpuBuffer2D current;
private GpuBuffer2D next;
void Start()
{
current = Gpu.Buffer(64, 64);
next = Gpu.Buffer(64, 64);
}
[TsukimiKernel]
static Color4 Step(KernelId id, GpuBuffer2D prev)
{
return new Color4(prev[id].R, 0f, 0f, 1f);
}
void Update()
{
Gpu.Run(nameof(Step), next, current);
Gpu.Swap(ref current, ref next);
}
}

渡した値の個数と型は、コンパイルのときにカーネルの引数と照合されます。

using UnityEngine;
using Tsukimi;
public class ParHostRunExtraArgs : TsukimiBehaviour
{
private GpuBuffer2D current;
private GpuBuffer2D next;
private float phase;
void Start()
{
current = Gpu.Buffer(64, 64);
next = Gpu.Buffer(64, 64);
}
[TsukimiKernel]
static Color4 Step(KernelId id, GpuBuffer2D prev, float t)
{
return new Color4(prev[id].R * t, 0f, 0f, 1f);
}
void Update()
{
phase = phase + Time.deltaTime;
Gpu.Run(nameof(Step), next, current, phase);
}
}

カーネルの名前は文字列でも渡せます。nameof を使うと、綴りを間違えたときに C# の側で気づけます。

using UnityEngine;
using Tsukimi;
public class ParHostRunStringName : TsukimiBehaviour
{
private GpuBuffer2D current;
private GpuBuffer2D next;
void Start()
{
current = Gpu.Buffer(64, 64);
next = Gpu.Buffer(64, 64);
}
[TsukimiKernel]
static Color4 Step(KernelId id, GpuBuffer2D prev)
{
return new Color4(prev[id].R, 0f, 0f, 1f);
}
void Update()
{
Gpu.Run("Step", next, current);
}
}

カーネルを複数書いて、順に走らせられます。

using UnityEngine;
using Tsukimi;
public class ParHostTwoKernels : TsukimiBehaviour
{
private GpuBuffer2D current;
private GpuBuffer2D next;
void Start()
{
current = Gpu.Buffer(64, 64);
next = Gpu.Buffer(64, 64);
}
[TsukimiKernel]
static Color4 Step(KernelId id, GpuBuffer2D prev)
{
return new Color4(prev[id].R, 0f, 0f, 1f);
}
[TsukimiKernel]
static Color4 Fade(KernelId id, GpuBuffer2D prev)
{
return new Color4(prev[id].R * 0.5f, 0f, 0f, 1f);
}
void Update()
{
Gpu.Run(nameof(Step), next, current);
Gpu.Run(nameof(Fade), current, next);
}
}

Gpu.Show を呼ぶと、対象のマテリアルの主テクスチャがバッファに差し替わります(マテリアルは対象ごとの複製になります)。

using UnityEngine;
using Tsukimi;
public class ParHostShow : TsukimiBehaviour
{
private GpuBuffer2D current;
private GpuBuffer2D next;
public Renderer display;
void Start()
{
current = Gpu.Buffer(64, 64);
next = Gpu.Buffer(64, 64);
}
[TsukimiKernel]
static Color4 Step(KernelId id, GpuBuffer2D prev)
{
return new Color4(prev[id].R, 0f, 0f, 1f);
}
void Update()
{
Gpu.Run(nameof(Step), next, current);
Gpu.Swap(ref current, ref next);
Gpu.Show(current, display);
}
}

Gpu.Texture は、Unity や VRChat 側の API へ渡すときに使います。返るのはバッファそのもので、複製ではありません。

using UnityEngine;
using Tsukimi;
public class ParHostTexture : TsukimiBehaviour
{
private GpuBuffer2D current;
private GpuBuffer2D next;
private RenderTexture tex;
void Start()
{
current = Gpu.Buffer(64, 64);
next = Gpu.Buffer(64, 64);
}
[TsukimiKernel]
static Color4 Step(KernelId id, GpuBuffer2D prev)
{
return new Color4(prev[id].R, 0f, 0f, 1f);
}
void Update()
{
Gpu.Run(nameof(Step), next, current);
tex = Gpu.Texture(current);
}
}