UnityでComputeShaderを使ってみたいと思っていたところ、チュートリアル的な資料があまりないような気がする。
そんな中良さそうなチュートリアル記事を見つけたが、英語で書かれている・・・。
ということで翻訳してみた。
元のページはこちら。
http://scrawkblog.com/2014/06/24/directcompute-tutorial-for-unity-introduction/
DirectCompute tutorial for Unity: Introduction
Unityを使って2年になるけど、その前はC++でプログラムを書いてて、自分でグラフィックコンテキストをOpenGLベースで書いてた。その時は自作のグラフィックスAPIを使う道を選んで、その結果GLSLシェーダについてたくさんのことを学んだ。
Unityを使い始めた時にCgをシェーダ言語として使い始めた。GLSLとCgはそんなに違いはなくて、比較的簡単に変換できる(GLSLは実際にUnityでサポートしてるけど、こなれてない感じ)。OpenGLを使っていた経験がとてもよいことで、膨大な検証コードをポーティングするの応力を与えてくれた、特に、OpenGLをUnityでやるにはよかった。(例えば、最近のProland portなど)
Unityを使い始めた時、MicrosoftのDirectX11のサポートが始まって、Direct11はDirectComputeAPIから来た。このAPIは、コンピュートシェーダを使う上で全く新しいGPUの使い方を生み出した。ただ問題がひとつあった。連続的なチュートリアルがかけていて、DirectComputeを使うドキュメントもほとんどなかった。google先生に頼っても何も出てこないし、Microsoftのドキュメントは広すぎて、amazonでも数種類の本しかこの手のトピックは扱ってない。もし君が何か良い学ぶための手がかりを持っていたら、ポストしてリンクをコメントに貼って欲しい。
ここ数年で、この強力なAPIをどうやって使うかをなんとか覚えてきてるけど、まだ情報が欠けていると感じる。そのために、このトピックに関して、UnityでのDirectComputeについての連続したチュートリアルを書くと決めた。イントロダクションとして、なぜDirectComputeが必要か、何が伝統的なグラフィックスパイプラインと違うか、どうやってコンピュートシェーダでカーネルに書くか、どうやってGPU内部に敷き詰められたスレッドを使うか、どのようなバッファタイプがあるか、どうやってスレッド・共有メモリを同期させるか、どうやってパフォーマンスを上げるかを説明したい。
幾つかのチュートリアルでは普通のCGシェーダを書いた経験を求められるかもしれないが、コンピュートシェーダに移行する前にCgシェーダのある程度の理解をしておくことを強くおすすめする。この理由は、コンピュートシェーダで処理するデータは、視覚的に表示する必要があり、普通のCgシェーダを使ってレンダリングすることになるからである。しかし私は、それらについてもカバーする。コンピュートシェーダはMicrosoftのHLSLで書かれている。この言語についてチュートリアルを進めるために知る必要はないが、どれかのシェーダ言語(GLSL、Cg,HLSL)について触った経験があるとよい。HLSLはとてもCgと似ているので、違う言語と気づかないかもしれない。また、私はsyntax highlighter をコンピュートシェーダ用に使うことをおすすめする。Monodevelopでデフォルトで動くはずだ。
The Graphics pipline
DirectComputeがなぜ必要かを理解するために、デフォルトパイプラインの歴史を知る必要がある。
それは90年台はじめに始まった。その時3Dグラフィックスは、有名になりつつあり、GPUも標準機能となりつつあった。必要なものはGraphicsAPIだったので、開発者は辛いながらもパワフルな新しいデバイスを使っていた。1992年にOpenGL1.0がリリースされ、IRIS GLというと呼ばれるシステムSGIとともに起こった。MicrosoftはOpenGLの初期メンバーの一人でOpenGLアーキテクチャのレビュー(ARB)をしていて、SGI、Digital Equipment Corp, IBM, Intelの標準であるOpenGLを開発する手助けをしていた。あるときMicrosoftはARBから去り、独自のライバルとなるシステム、Direct3Dを開発し、それはDirectXのAPIの一部となった。ARBはKhronosグループに発展し、現在のメンバーは、3DLabs,ATI,Discreet, Evans & Sutherland, Intel, NVIDIA, SGI, Sun Microsystemsなどである。
すべての開発者はジオメトリをGPUとOpenGLでレンダリングするために送る必要があり、スクリーン上にピクセルが表示される出力の時までをパイプラインに通していた。パイプラインは、修正され、開発者は部分的にON/OFFを指定したり、ある設定を修正したりなどをした。開発者がGPUにより多くの要求を求めるようになりより高度な特徴がパイプラインに現れたことにより、パイプライン自身がよりフレキシブルなものになる必要が出てきた。その解決策として、パイプラインの一部をプログラマブルにするようになった。開発者は、パイプラインのある部分で処理するためにプログラムを書くことができる。この新しいプログラムは、シェーダとして知られている。(プログラムとシェーダには技術的な違いがあるが、それはここでは話をしない)
この新しいプログラマブルなパイプラインは、新しい可能性を生み出し、過去の世代のゲームのグラフィックスのクォリティには必要不可欠になった。パイプラインはそもそもグラフィックスを生成するためのみに開発されたが、新しい自由度として、GPUは別の様々なタイプのアルゴリズムに応用可能となった。
研究は始まっており、GPUのマルチスレッド環境で動くアルゴリズムに修正され、その範囲は、物理学、経済学、数学など、データを処理するためにGPUを使い始めている。性能の低いGPUは耐えられないため、GPGPUやGeneralPurpose Graphical Processing Unitプログラミングなどを産んだ。
General Purpose Graphical Processing Unit programming
GPGPUはすぐにメインストリームになって、産業利用が始まった。しかし問題もある。GraphicsAPIはグラフィックスパイプラインに未だに絡みついている。どれだけフレキシブルなシェーダが与えられたとしても、パイプラインへの制限は考慮する必要がある。
Vertexシェーダはまだ、頂点を出力するためにあり、Fragmentシェーダはピクセルを出力する。素晴らしい置き換えや発想によって開発される一方、GPGPUがさらに開発されたとしても新しい使い方がでてくる。APIは必要で、開発者をグラフィックスパイプラインの複雑さかや低性能のGPUのためにグラフィックス以外の設定で辛い目にあう環境が提供されることから自由になれる。
次の数年でGPGPUのAPIは現れ始め、現在の開発者はCUDAやOpenCL、DirectComputeといった選択を使わなくなる。その新しいAPIは、まったく新しい方法でGPUを動かし、伝統的なグラフィックスパイプラインとの境界はなくなる。いくつかの制限はあるが、マルチスレッド環境でより仕事ができるようになる。
GPGPUへの要望はグラフィックスと関係ない設定でのGPUの使い方についての方法を提供するしつつ、ゲーム業界では、新しい可能性についての方法が熱心に作られている。ゲームがより写実的になり、現実世界の物理をシミュレートするようになった。これらの計算は、複雑な処理が要求される。
性能と自由度がGPGPUによって提供されるため、それらの計算が大きな範囲でより繊細に行われるようなった。元々のグラフィックスAPIは、我々が現在関わっている3Dゲームに関してまったく新しい世界へつながっていた。新しいGPGPUのAPIも同じで、全く新しい時代のゲームを連れてくるだろう。現在の世代のゲームはそれらのAPIの利用によって生み出されてより写実的なグラフィックスや信頼性の高い物理によって支配されている。
あなたが今必要なものはそれらをどうやって使うかである。次のパートでどうやってカーネルをセットアップし、スレッドで埋めるかについて話をする。
下の図は現在のdx11パイプラインである。
# 訳したけど...
この記事は概要で実装じゃなかったorz
次の記事から実際の具体的な話になるみたい。