私は私を混乱させる何かに遭遇しました。私はそれに対する答えを見つけることができません。私はこのようなシェーダ書く時:ユニフォームと変化のためのOpenGLとGLSLのメモリアライメント
layout (location = 0) in vec3 inPosition;
layout (location = 1) in vec3 inNormal;
layout (location = 2) in vec2 inTexCoords;
を私はvec3年代は、多くのであるvec4、またはSIMD互換性のあるデータ型として整列16バイトではないことを知っています。
struct Vertex
{
vec3 position;
vec3 normal;
vec2 texCoords;
};
各ベクトルは、サイズが8 *のはsizeof(フロート)、32バイトであること、無パディングで、お互いにぴったりと座っている:私のC++コードでの私のデータがあるので、私は、(私が思う)これを知っています。私はそれを制服に渡し、シェーダはそれをうまく読みます。したがって、両方が整列していることがわかります。
しかし、とき、それは例えばstd140規格にvec3は別のvec3またはvec4を追加する前に、余分な4つのバイトでパディングされなければならない、GLSLで均一なブロックに来る:メンバーである場合
- N基本的なマシン単位消費コンポーネントと三成分ベクトル、ベースアライメント4N
あるあなたもコンパクトにvec3と次vec3間に4バイトの整数または4バイトブール値を記憶することができるがサイズ。これは、頂点レイアウトのattribポインタ値がstd140レイアウトに従わないことを意味しますか?また、たとえば私のC++コードでSIMDの16バイト整列ベクタを使用している場合、私はもはやattribポインタの値をvec3、vec3、vec2として設定することはできませんが、むしろすべてのvec4を持っていますか?
警告:実装は時々 vec3コンポーネントのstd140レイアウト誤解し
はまた、私はマニュアルの次の警告を見ました。 構造体/配列を手動で埋めて、vec3をまったく使用しないようにすることをお勧めします。
ここではvec3の使用を避けると言っていますが、vec3の後に4バイトのintまたはboolをパックするスマートな省スペース技術だと思いました。
これは参考になりました。 floatBitsToIntは私の心を吹き飛ばしました。最初は0〜255のRGBAを格納するu8vec4を見つけようとしていましたが、glslはシングルバイトデータ型を扱っていないことが分かったので、次のアイデアはintを送り、適切なカラーチャネルを確保するためにビット演算子を使用します。 – Zebrafish
ちょっと待ってちょっと浮かれば私はまだ気づいたfloatBitsToIntでもやらなければならない。私の0 - 255の色が私のvec4.wなら、私はまだシフトし、正しいバイトを抽出する必要があります。 – Zebrafish