It's bindless纹理化。您不会将此类纹理“绑定”到任何东西。
In 无约束纹理 https://www.opengl.org/wiki/Bindless_Texture,采样器的数据值是一个数字。具体来说,返回的数字glGetTextureHandleARB
。纹理句柄是 64 位无符号整数。
在着色器中,值sampler
输入缓冲区支持的接口块 https://www.opengl.org/wiki/Interface_Block_(GLSL)#Buffer_backed(UBO 和 SSBO)是 64 位无符号整数。因此采样器数组在结构上相当于 64 位无符号整数数组。
所以在 C++ 中,一个结构相当于你的ALL_TEXTURES
块将是:
struct AllTextures
{
GLuint64 textures[200];
};
好吧,假设你正确使用std140
当然是布局。否则,您必须查询结构的布局。
此时,您将缓冲区视为与任何其他 UBO 用法没有什么不同。通过粘贴来构建着色器的数据AllTextures
到一个缓冲区对象中,然后将该缓冲区作为 UBO 绑定到绑定 0。您只需使用实际的纹理句柄填充数组即可。
另外,我应该使用什么来更新顶点属性“texindex” - 我的纹理句柄数组或纹理句柄的实际索引?
好吧,两者都行不通。不是你写的那样。
See, ARB_bindless_texture https://www.opengl.org/registry/specs/ARB/bindless_texture.txt不允许您在任何时间从任何着色器调用中以任何方式访问您想要的任何纹理。除非您使用 NV_gpu_shader5,否则导致纹理访问的代码必须基于动态统一表达式 https://www.opengl.org/wiki/Dynamically_Uniform_Expression.
因此,除非渲染命令中的每个顶点都获得相同的索引或句柄...cannot使用它们来选择要使用的纹理。即使实例化也无法拯救您,因为动态统一表达式不关心实例化。
如果您想要渲染一堆四边形而无需更改它们之间的制服(并且无需依赖 NVIDIA 扩展),那么您有几种选择。大多数支持无绑定纹理的硬件也支持ARB_shader_draw_parameters https://www.opengl.org/registry/specs/ARB/shader_draw_parameters.txt。这使您可以访问gl_DrawID
,表示渲染命令的当前索引在一个glMultiDraw-风格命令 https://www.opengl.org/wiki/Vertex_Rendering#Multi-Draw。该扩展明确声明gl_DrawID
是动态均匀的。
所以你可以用它来选择要渲染的纹理。您只需要发出多次绘制命令,一遍又一遍地渲染相同的网格数据,但它会得到不同的结果gl_DrawID
每种情况下的索引。