【问题标题】:Binding textures in OpenGL在 OpenGL 中绑定纹理
【发布时间】:2011-07-13 01:16:34
【问题描述】:

所以我分批渲染我的场景,以尽量减少状态变化。 由于我的着色器通常需要多个纹理,因此我将其中一些同时绑定到不同的纹理单元。其中一些纹理在多个批次中使用,因此甚至可以保持绑定。

现在我的问题是,是否可以在批处理期间重新绑定我需要的所有纹理,即使其中一些可能已经绑定?或者我应该检查哪些是绑定的,只绑定新的? glBindTexture 有多贵?我正在使用着色器,将未使用的纹理绑定到着色器不会从中采样的纹理单元是否很糟糕,或者我应该取消绑定它们?

我主要是在问“如何使其快速”,而不是“如何”。

编辑:如果我提供代码会有帮助吗?

【问题讨论】:

    标签: opengl graphics textures


    【解决方案1】:

    GPU 编程的神圣规则是,你与 GPU 交谈越少,她就越爱你。 glBindTexture 比 CPU 上的单一条件检查要昂贵得多,所以对于频繁的状态变化,我认为你应该看看是否需要将新的纹理索引传输到 GPU。

    【讨论】:

    • 显示列表已被弃用,因此您最好不要使用它们。
    • glBindTexture 是 slow,就像任何状态变化(glEnable,...)一样。尽你所能在你自己的代码中避免它们。如果不相信,通过 gDEBbugger 运行你的程序,看看它说了什么。
    • 重新绑定所有纹理的好处是我不需要更改着色器制服(例如,我总是可以指望“metal_2”在 texture_2 中)。我想我必须对其进行分析,我不确定统一集与 glBindTexture 的性能。
    【解决方案2】:

    答案很困难,因为任何强大的 GL 实现都应该将绑定已绑定的纹理作为优化的无操作。您应该尝试进行基准测试,看看设置条件是否会产生影响。

    这同样适用于纹理单元中未使用的纹理,因为 GL 实现确实知道最终使用了哪些纹理单元,因此拥有未使用的纹理单元不应影响性能(作为优化)。

    【讨论】:

    • 不要指望 GL 实现做这个优化。
    • 不过,这是一个有效的假设。如今,GPU 通常有几组状态,驱动程序会在这些状态下进行处理(请参阅 Tom Forsynth 的博客以获取长篇文章)。这意味着即使更改纹理也不一定会停止(这是一个最坏的假设,但仍然应该这样做)。这种资源管理显然只能在实现跟踪绑定的内容并且不冗余应用更改的情况下才能完成。这并不能保证任何事情,但这是一个现实的假设。
    • 另一方面,在重新绑定对象时存在缓存未命中问题,nVidia 称这是其无绑定图形扩展的主要原因(“一个新瓶颈”)。据报道,有很多缓存未命中,因为驱动程序必须获取状态以检查绑定的内容以及它是否有效以及每次绑定的其他内容。因此,即使在驱动程序中对其进行了优化,避免不必要的绑定仍然不是一个坏主意。
    • 有谁知道 OpenTK 是否默认这样做?
    【解决方案3】:

    跟踪你绑定了哪些纹理(不要使用 glGet(GL_TEXTURE_BINDING_2D) ),只有在它改变时才重新绑定。有些司机会为您执行此操作,有些则不会。

    如果您提前知道您的目标平台是什么,那么做一个简单的基准测试就可以很容易地了解它有多大的不同。

    您还可以按批次使用的纹理对批次进行排序,以最大程度地减少纹理变化。

    【讨论】:

      【解决方案4】:

      我想说最好的方法是使用 glBindTextures https://www.khronos.org/opengl/wiki/GLAPI/glBindTextures 一次绑定所有纹理。或者使用无绑定纹理:)

      【讨论】:

        猜你喜欢
        • 2013-02-22
        • 2013-09-07
        • 1970-01-01
        • 2015-02-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-11-21
        相关资源
        最近更新 更多