グラフィックカードの計算、マニュアル、簡単

このガイドでは、最も単純なGPUコンピューティングプログラムの操作について説明します。 このプログラムのUnityプロジェクトへのリンクは次のとおりです。



プロジェクトファイル.unitypackageへのリンク



彼女はマンデルブロのフラクタルを描きます。



コードの各行については説明しません。GPUで計算を実装するために必要な手順のみを示します。 したがって、Unityでプログラムコードを開き、説明されたコード行がどのように使用されるかを確認するのが最善です。



フラクタルシェーダーはHLSLで記述されています。 以下はそのテキストです。 関連する行について簡単にコメントしましたが、詳細な説明は以下になります。



//   GPU       : RWTexture2D<float4> textureOut; //  ,       RWStructuredBuffer<double> rect; //      ,    RWStructuredBuffer<float4> colors; //    ,      CPU     #pragma kernel pixelCalc //    ,          CPU [numthreads(32,32,1)] //     ,      void pixelCalc (uint3 id : SV_DispatchThreadID){ //     .  id   ,      float k = 0.0009765625; //       10241024     22   double dx, dy; double p, q; double x, y, xnew, ynew, d = 0; //    ,           uint itn = 0; dx = rect[2] - rect[0]; dy = rect[3] - rect[1]; p = rect[0] + ((int)id.x) * k * dx; q = rect[1] + ((int)id.y) * k * dy; x = p; y = q; while (itn < 255 && d < 4){ //   :      ,      2x2 xnew = x * x - y * y + p; ynew = 2 * x * y + q; x = xnew; y = ynew; d = x * x + y * y; itn++; } textureOut[id.xy] = colors[itn]; //      :    ,    -   }
      
      





注意深い読者は言う:著者、説明してください! テクスチャサイズは1024×1024で、スレッド数は32×32です。 id.xyパラメーターは、テクスチャ内のすべてのピクセルにどのように対処しますか?

丁寧でありながら、GPUリーダーでのコンピューティングの問題については経験の浅い人が殺します。 そして、スレッドの数が32x32であるということはどこに続きますか? そして、「id.xy」の理解方法は?



次のように2番目に答えます。ディレクティブ[numthreads(32,32,1)]は、32x32x1スレッドがあることを示しています。 同時に、idパラメーターは32x32x1空間の座標形式で値を取るため、フローは3次元グリッドを形成します。 値の範囲はid.x [0、31]、値の範囲はid.y [0、31]、id.zは0です。また、id.xyは短いレコードuint2(id.x、id.y)です。



コマンドでCPU側からこのカーネルを呼び出すと、32x32スレッドになります(この最初の注意深い読者に既に答えています)。



 ComputeShader.Dispatch(kernelIndex, 1, 1, 1)
      
      





これらの3つのユニットを参照してください? これは、ディレクティブ[numthreads(32,32,1)]の番号と同じであり、互いに乗算されます。



次のパラメーターでシェーダーを開始した場合:



 ComputeShader.Dispatch(kernelIndex, 2, 4, 1)
      
      





これは、x軸に沿って32 * 2 = 64、y軸に沿って32 * 4 = 128、つまり合計64x128スレッドになります。 パラメータは、各軸で単純に乗算されます。



ただし、この場合、カーネルは次のように起動されます。



 ComputeShader.Dispatch(kernelIndex, 32, 32, 1)
      
      





これにより、合計1024x1024のスレッドが得られます。 そして、それはid.xyインデックスが1024x1024のテクスチャ空間全体をカバーする値を取ることを意味します



これは便宜上行われています。 データは配列に格納され、各ストリームはデータ単位で同じ操作を実行し、データ単位の数に等しいスレッド数を作成し、ストリームインデックスがそのデータ単位をアドレス指定するようにします。 とても快適です。



私たちのフラクタル化プログラムのシェーダーコードについて知る必要があるのはそれだけです。



次に、シェーダーコードを実行するためにCPU側で行ったことを見てみましょう。



変数の宣言:シェーダー、バッファー、およびテクスチャ



 ComputeShader _shader RenderTexture outputTexture ComputeBuffer colorsBuffer
      
      





enableRandomWriteを有効にすることを忘れずに、テクスチャを初期化します



 outputTexture = new RenderTexture(1024, 1024, 32); outputTexture.enableRandomWrite = true; outputTexture.Create();
      
      





オブジェクトの数とオブジェクトのサイズを設定して、バッファーを初期化します。 事前に入力された色の配列のデータをビデオメモリに書き込む



 colorsBuffer = new ComputeBuffer(colorArray.Length, 4 * 4); colorsBuffer.SetData(colorArray);
      
      





シェーダーを初期化し、カーネルにテクスチャとバッファーを設定して、データを書き込むことができるようにします



 _shader = Resources.Load<ComputeShader>("csFractal"); kiCalc = _shader.FindKernel("pixelCalc"); _shader.SetBuffer(kiCalc, "colors", colorsBuffer); _shader.SetTexture(kiCalc, "textureOut", outputTexture);
      
      





これがデータの準備です。 あとは、シェーダーカーネルを起動するだけです



 _shader.Dispatch(kiCalc, 32, 32, 1);
      
      





このコマンドを実行すると、RenderTextureテクスチャがカメラが見ているImageコンポーネントのmainTextureとして使用されるため、テクスチャはすぐに見える色で塗りつぶされます。



All Articles