自己解決したので一部抜粋します。
機能要件はスプラトゥーンのように壁のテクスチャに別のテクスチャを逐次ペイントして行き、各色どれくらいの割合で塗られたかを別途集計用テクスチャにも集計しやすい単色で書き込みし、リアルタイムに集計(各色のヒストグラムを計算)する事です。
C#
1public ComputeShader m_ComputeShader;
2ComputeBuffer m_CSBuffer;
3int m_ID_Histogram;
4
5void Awake()
6{
7 // Compute Shaderの中から関数(Kernel)のIDを得る
8 int m_ID_Histogram = m_ComputeShader.FindKernel("Histogram");
9
10 // Compute Shaderから結果を受け取るバッファを確保
11 m_CSBuffer = new ComputeBuffer(256, sizeof(uint) << 2);
12
13 // Compute Shaderにプロパティ設定
14 m_ComputeShader.SetBuffer(m_ID_Kistogram, "_Histogram", m_CSBuffer);
15
16 // 集計用ランダムアクセステクスチャを作成
17 summaryTexture = new RenderTexture(1024, 1024, 0, RenderTextureFormat.ARGB32);
18 summaryTexture.hideFlags = HideFlags.HideAndDontSave;
19 summaryTexture.enableRandomWrite = true;
20 summaryTexture.filterMode = FilterMode.Point;
21 summaryTexture.Create();
22
23 Graphics.SetRenderTarget(summaryTexture);
24 GL.Clear(false, true, new Color(0, 0, 0, 0)); // 空でフィル
25
26 // Compute Shaderにプロパティ設定
27 m_ComputeShader.SetTexture(m_ID_Histogram, "_Source", summaryTexture);
28}
29
30// summaryTextureの各画素のRGBA各値の数を集計
31void CalcSummary()
32{
33 // 結果受け取りバッファクリア
34 m_CSBuffer.SetData(new uint[256 << 2]);
35 m_ComputeShader.Dispatch(m_ID_Histogram, summaryTexture.width >> 4, summaryTexture.height >> 4, 1);
36}
37
38// 集計結果を表示
39void CSGetData(ComputeBuffer csbuf)
40{
41 uint[,] data = new uint[csbuf.count, 4];
42 csbuf.GetData(data);
43 for (int i = 0; i < data.GetLength(0); i++) Debug.LogFormat("{0} {1} {2} {3}", data[i,0], data[i,1], data[i,2], data[i,3]);
44}
45
46void Paint()
47{
48 // テクスチャペイントしつつ、集計用テクスチャにも塗った箇所を一部抜粋
49 Graphics.ClearRandomWriteTargets();
50 Graphics.SetRandomWriteTarget(1, summaryTexture); // 1はu1レジスタを表し、何番目に登録したSetRandomWriteTargetかを表す
51 // Graphics.Blitはsrcとdestに同じTextureを指定出来ないので、交互に書く
52 Graphics.Blit(paintTexture[idxTex], paintTexture[1 - idxTex], paintMaterial);
53 Graphics.ClearRandomWriteTargets();
54}
集計用 Compute Shader
Compute
1RWStructuredBuffer<uint4> _Histogram;
2Texture2D<float4> _Source;
3
4#pragma kernel Histogram
5[numthreads(16,16,1)]
6void Histogram(uint3 id : SV_DispatchThreadID)
7{
8 half4 color = saturate(_Source[id.xy]);
9 uint4 idx_c = (uint4)(round(color * 255.0));
10 InterlockedAdd(_Histogram[idx_c.x].x, 1); // Red
11 InterlockedAdd(_Histogram[idx_c.y].y, 1); // Green
12 InterlockedAdd(_Histogram[idx_c.z].z, 1); // Blue
13 InterlockedAdd(_Histogram[idx_c.w].w, 1); // Alpha
14}
壁のテクスチャの一部に別のテクスチャをペイントし、その際に集計用テクスチャにも単色でペイントする
paintMaterialにセットしたShader(一部抜粋)
Shader
1RWTexture2D<float4> _SummaryTex; // 集計用テクスチャ : register(u1);
2
3float4 frag(v2f i) : SV_TARGET
4{
5 if( このピクセルに何かを上書き描画する場合 )
6 {
7 // 集計用テクスチャのサイズ取得
8 float xs;
9 float ys;
10 _SummaryTex.GetDimensions(xs,ys);
11 // 集計用テクスチャにも単色で描画する
12 int2 loc;
13 loc.x = int(i.uv.x * xs);
14 loc.y = int(i.uv.y * ys);
15 _SummaryTex[loc] = float4(0, 1, 0, 1); // ここにチームカラーなど
16
17 // 別のTexture等から描きたい物の色をcolに入れてreturn
18 return col;
19 }
20 // 元のテクスチャのままにする場合は通常処理
21 return tex2D(_MainTex, i.uv);
22}
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。