GLSLで定義した構造体を含めたSSBO(ShaderStorageBufferObject)についてです。
例えば、以下のようなコードで想定外の動作に遭いました。
struct TPoint
{
int Status;
vec3 Position;
vec3 Velocity;
};
layout (std430, binding = 0) buffer Point
{
TPoint Points[];
};
問題は2つです。
- vec3はvec4としてアライメントされる
- 最大のデータサイズに応じてメモリパディングが行われる(構造体は構造体としてサイズ定義)
これを踏まえると、GLSLではTPoint構造体の変数1つについて図のようなメモリ配置と認識します。
![](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F251232%2F3b8341ce-af6a-7186-e6ae-174b6b1e39b5.jpeg?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=71d658b39b92b59bea78da787942d412)
アライメントさえ分かっていれば、SSBOのメモリ確保をこれに合わせれば解決です。
あるいは、vec3の変数をXYZの3要素に分解してもいいです。パディングが無駄に感じる場合は(筆者はそうですが)この方がいいでしょう。
次が修正したコードです。
struct TPoint
{
int Status;
float PositionX;
float PositionY;
float PositionZ;
float VelocityX;
float VelocityY;
float VelocityZ;
};
layout (std430, binding = 0) buffer Point
{
TPoint Points[];
};
参考:
https://stackoverflow.com/questions/29531237/memory-allocation-with-std430-qualifier