NBidiaのサンプルプロジェクトgl_commandlist_basicで、glBindBufferRangeのオフセット/アライメントがどのように機能するのかを理解できません。 私はオフセットが256のGL_UNIFORM_BUFFER_OFFSET_ALIGNMENTの倍数である必要があること、および/またはglBindBufferの範囲でオフセットとアラインメントが非常に重要であることを読んだことがあります。。私はmat4/vec4で動作するサンプルUBOと、mat4/mat3/vec4で動作しないサンプルを持っています。どちらの場合も、UBOは256の倍数になることはありません。私はvec4(0.f、1.f、0.f、1.f)を送信しようとしています。なぜ私のglBindBufferRangeオフセットの配置が間違っていますか?
mat4 = 64バイト、mat3 = 36バイト、vec4 = 16バイトの場合、動作例は64 + 16 = 80バイトで、は256の倍数ではありません。動作していない例は64 + 36 + 16 = 116バイトです。
NVは、作業/非からこれを削除
inline size_t uboAligned(size_t size) { return ((size + 255)/256) * 256; }
として定義された差のいずれかの方法を作っていないをuboAligned と呼ばれるインラインを使用します。
float/vec2/vec3/vec4などの形でUBOに「パディング」を追加する必要があると仮定します。mat4を使用する場合に必要なパディングの正確な量を決定するにはどうすればよいですか/ mat3/vec4 UBO?
/* APPLICATION */
typedef struct
{
glm::mat4 MM;
// glm::mat3 NM;
glm::vec4 Cs;
} myData0;
Gluint objectUBO;
glCreateBuffers(1, &objectUBO);
glNamedBufferData(objectUBO, uboAligned(sizeof(abjObjectData) * 2), 0, GL_STATIC_DRAW); //
for (unsigned int i = 0; i < allObj.size(); ++i)
{
myData0 myDataTemp;
myDataTemp.Cs = glm::vec4(0.f, 1.f, 0.f, 1.f);
glNamedBufferSubData(objectUBO, sizeof(abjObjectData) * i, sizeof(abjObjectData), &objDataInit);
}
//hot loop
for (unsigned int i = 0; i < allObj.size(); ++i)
{
glBindBufferRange(GL_UNIFORM_BUFFER, 1, objectUBO, uboAligned(sizeof(abjObjectData)) * i, sizeof(abjObjectData));
//draw
}
/* HW */
out vec4 Ci;
struct ObjectData
{
mat4 MM;
// mat3 NM;
vec4 Cs;
};
layout (std140, binding = 1) uniform objectBuffer { ObjectData object; };
void main()
{
Ci = object.Cs;
}
"*これを作業中から削除するとどちらにも違いはありません。*"どのくらい削除しましたか?あなたは何を関数に返すようにしましたか? –
もし私がUBOでvec4を送るだけなら、2番目のオブジェクトのuboAligned()オフセットは256になり、シェーダの値は読み込まれませんが、uboAligned()がなければオフセットは16になります。 ..もし私が手作業でUBOに240ビットの余分なデータを書き込むと、それは読み込まれます。しかし、いくつかのパディングを持つNVの例は「最大256まで加算されません。」オフセット/パディングが混乱するのは混乱します(?)GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT – waaitt