カーネルの実行
書ける形(8)
Section titled “書ける形(8)”| 書き方 | 説明 |
|---|---|
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) | テクスチャとしての取り出し |
書けない形(8)
Section titled “書けない形(8)”| 書き方 | 説明 | エラー | 理由 | 代わりに |
|---|---|---|---|---|
カーネルが 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 | 設計 | カーネルの中で詰める |
原因を言わないエラー
Section titled “原因を言わないエラー”上の 8 形は、すべて同じ文言で断られます(TUKI0001「Udon に落とせない C# 構文です」。
最後の 1 つだけ、型が無い旨も併せて出ます)。どれもカーネルの規則を破ったものなのに、
文言は Udon の話をするので、文面から原因を絞り込めません。断られたら、上の表の行を
上から順に当たるのが早道です。
面の差し忘れ
Section titled “面の差し忘れ”カーネルを 1 つ書くと、見せる面を差す公開フィールドが 1 つ増えます。何も差さないまま
Gpu.Show まで進むと、実機で無言のまま止まります。コンパイラはこれを警告として出すだけで、
コンパイルは通します。
バッファの生成
Section titled “バッファの生成”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); }}2 つの入れ替え
Section titled “2 つの入れ替え”前の結果を次の入力にするときに使います。自分で書いたメソッドの引数に 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); }}実行の呼び出し
Section titled “実行の呼び出し”第 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); }}値を渡した実行
Section titled “値を渡した実行”渡した値の個数と型は、コンパイルのときにカーネルの引数と照合されます。
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); }}名前の文字列指定
Section titled “名前の文字列指定”カーネルの名前は文字列でも渡せます。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); }}複数のカーネル
Section titled “複数のカーネル”カーネルを複数書いて、順に走らせられます。
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); }}表示と取り出し
Section titled “表示と取り出し”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); }}テクスチャとしての取り出し
Section titled “テクスチャとしての取り出し”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); }}