OpenGL - 在没有 NV_gpu_shader5 的情况下访问 glMultiDrawElementsIndirect 内的无绑定纹理

Posted

技术标签:

【中文标题】OpenGL - 在没有 NV_gpu_shader5 的情况下访问 glMultiDrawElementsIndirect 内的无绑定纹理【英文标题】:OpenGL - Accessing bindless textures inside glMultiDrawElementsIndirect without NV_gpu_shader5 【发布时间】:2022-01-19 10:12:59 【问题描述】:

我正在使用glMultiDrawElementsIndirectARB_bindless_texture 的组合来绘制东西。我使用内置的顶点着色器变量gl_DrawID 获取纹理句柄。据说这个变量是一个动态统一的表达式,这意味着我在访问着色器内的无绑定纹理时不必依赖NV_gpu_shader5。它看起来像这样。

#version 460 core

out flat int MaterialIndex;

void main()

    ...
    MaterialIndex = gl_DrawID;

#version 460 core
#extension GL_ARB_bindless_texture : require

struct Material

    sampler2D Albedo;
    ivec2 pad0;
;

layout(std140, binding = 1) uniform BindlessUBO

    Material Materials[256];
 bindlessUBO;

in flat int MaterialIndex;

void main()

    Material material = bindlessUBO.Materials[MaterialIndex];
    vec3 albedo = texture(material.Albedo, coords).rgb;

这适用于支持NV_gpu_shader5 的 NVIDIA RTX 3050 Ti。具有所有网格和纹理的模型在一次绘制调用中被正确绘制。但是,在不支持扩展的 AMD RX 5700XT 上,驱动程序会在几秒钟后崩溃。两个 GPU 都可以在没有任何纹理的情况下渲染模型。所以现在我的猜测是MaterialIndex 不是一个动态统一的表达式,即使它从一个表达式中获取它的值。将MaterialIndex 从顶点传递到片段着色器是否使其成为非 d.u.e?我怎样才能在片段着色器中的glMultiDrawElementsIndirect 中获取绘图命令的索引作为 d.u.e?没有NV_gpu_shader5,有没有办法完成我想做的事情?

【问题讨论】:

您的一个着色器以 4.3 为目标而另一个以 4.6 为目标是否有特定原因?关于多绘制命令的动态统一的定义在版本之间略有变化,对于 4.6,我认为您的表达式是动态统一的,因为它在同一个调用组中具有相同的值。即使它不是动态统一的,我也不希望着色器崩溃而是返回垃圾。 @BDL 我的默认值始终是 4.3,但由于gl_DrawID,我不得不使用 4.6。我都切换到了4.6。同样的问题。它实际上比崩溃更不确定的行为。取决于我看和移动的地方,我猜。有时它会冻结,有时整个电脑会崩溃。如果我将MaterialIndex 替换为常量,则它可以工作。 听起来像是 AMD 的驱动程序错误。 @BDL 原来是驱动问题。 @derhass 确实:)。 【参考方案1】:

从 AMD 驱动程序 19.12.2 升级到 21.12.1 后,该错误消失了。因此,使用flat 限定符将gl_DrawID 从顶点传递到片段着色器实际上确实将其保留为动态统一表达式,我不需要依赖NV_gpu_shader5 :)。

【讨论】:

以上是关于OpenGL - 在没有 NV_gpu_shader5 的情况下访问 glMultiDrawElementsIndirect 内的无绑定纹理的主要内容,如果未能解决你的问题,请参考以下文章

为啥在我的 OpenGL 引擎中没有从 MyGUI 获得任何屏幕输出?

为啥三角形没有显示在屏幕上(OpenGL 3.3)?

如何在 OpenGL 3.0 中编程? (没有更高)

制作没有屏幕的 OpenGL 上下文

在没有 openGL 的情况下使用 Qt

SDL+OpenGL 程序没有出现在 linux 上