Open16

2021.2から導入されたらしいMesh.GetVertexBuffer APIを試す

にー兄さんにー兄さん

目的

  • Unity 2021.2のドキュメントに載っているMesh.GetVertexBuffer APIを試す
  • Azure Kinectの点群(位置だけ?)を頂点情報に流し込んでみる
にー兄さんにー兄さん

GetVertexBuffer()はGraphicsBufferオブジェクトを返すので、
これをComputeShaderで処理することで頂点の位置を変化させる

にー兄さんにー兄さん

実装イメージとしては

  1. MeshやMeshFilterの初期化
  2. MeshからVertexBufferを取得し、ComputeShaderにバインドする
  3. Azure Kinectを初期化しカメラを起動
  4. 点群情報を取得(Short3[]からVector3[]とかに変換しておく)
  5. 点群からGraphicsBufferを生成してComputeShaderに渡す
  6. 点群バッファから頂点バッファを計算し更新
  7. 4~6を繰り返す

って感じ?

にー兄さんにー兄さん

メッシュオブジェクトでPointCloudを表現するためにはmesh.setIndicesでMeshTopologyというものを指定する。
これでPointにすれば頂点が点でレンダリングされる。OpenGLでもこういう感じのことするもんね

にー兄さんにー兄さん

なんとなくまだプロジェクト自体には手を付けられておらず、外堀を埋める感じでComputeShaderの勉強などをしている

にー兄さんにー兄さん

ComputeShaderでやることとしては、AzureKinectで取得した点群情報をMeshのVertexBufferに書き込むことまで

VertexBufferはGetVertexBuffer メソッドで取得できるんだけど、keijiro先生および公式のサンプルでは
RWByteAddressBufferという型でComputeShaderにバインドしている
https://github.com/keijiro/NoiseBall6/blob/d55ebdc90651e4abe57fb9929078ba350475b415/Common/NoiseBall.compute#L14
https://github.com/Unity-Technologies/MeshApiExamples/blob/1531c9973b66f30ab9a7b37912a8d690d878a1f5/Assets/ProceduralWaterMesh/WaterComputeShader.compute#L12

ComputeShaderのサンプルでよく見るBufferというえばRWStrcturedBuffer<T>型なんだけど、
こちらは構造体をジェネリクスに取れるのにたいしてRWByteAddressBufferはバッファ単位で読み書きをするためのバッファらしい
https://docs.microsoft.com/ja-jp/windows/win32/direct3dhlsl/sm5-object-rwbyteaddressbuffer

にー兄さんにー兄さん

AzureKinectから取得できる点群は、デフォルトではShort3型という、Microsoft.Azure.Kinect.Sensor名前空間に存在する構造体になっている。
_xyzImage.GetPixels<Short3>.ToArray()とすればShort3の配列が返ってくるので、
これを模した構造体をComputeShader内に作ってRWStructuredBuffer<Short3>でバインドすれば取得できると思う

にー兄さんにー兄さん

Kinectの点群取得からComputeShaderで使うまでは何となくできるかもだけど、
まだRWByteAddressBufferとして渡されたVertexBufferを操作の方法を理解していない
あとスレッドってどの値を設定すればいいのか、とか