所以最近我开始阅读OpenGL维基文章。这就是我如何描绘here中描述的OpenGL纹理的方式。虽然,有几点还不清楚。

以下陈述是对,错还是取决于?

  • 将两个纹理绑定(bind)到相同的纹理单元是不可能的。
  • 将两个采样器绑定(bind)到同一纹理单元是不可能的。
  • 将一个纹理绑定(bind)到两个不同的纹理单元是不可能的。
  • 将一个采样器绑定(bind)到两个不同的纹理单元是不可能的。
  • 明确将什么采样器类型传递给什么统一变量是应用程序的责任。
  • 确保着色器程序将采样器作为统一变量的正确类型是着色器程序的责任。
  • 纹理单元数足够大。让每个加载到应用程序的网格物体占用尽可能多的纹理单元。
  • 一些采样器参数与纹理参数重复。它们将覆盖纹理参数设置。
  • 一些采样器参数与着色器程序中的采样器描述重复。 Shader程序的描述将覆盖采样器参数。
  • 最佳答案

    我将在下面仔细阅读您的陈述。有时我会用OpenGL 4.5 core profile specification的引号引起争论。这些都不是GL 4.5特有的,我选择它是因为它是最新版本。



    如果我说“假”,那可能会产生误导。确切的说法是“将两个纹理绑定(bind)到同一纹理单元的同一目标是不可能的”。从技术上讲,您可以说将2D纹理和3D纹理绑定(bind)到同一单元。但是您不能在同一个绘图调用中同时使用两者。请注意,这是一个动态错误情况,具体取决于您将采样器制服设置为什么值。引用GL规范的第7.10节“Samplers”:



    因此,当您实际配置该着色器以使两个采样器制服引用同一单元的不同目标时,GL将立即检测到此错误情况(否则将触发着色器调用)。但这不是错误。如果您将两个制服临时设置为相同的值,但不尝试在该状态下绘制,则不会产生任何错误。



    您可能是指Sampler Objects(而不是GLSL中的“采样器”类型),所以这是事实。



    假。您可以将同一纹理对象绑定(bind)到尽可能多的单元。但是,这是相当无用的操作。早在固定功能管道的时代,在一些极端情况下,这种方法的使用受到限制。例如,我见过有人两次将相同的纹理绑定(bind)在一起,并使用寄存器组合器将两者相乘,因为他需要进行平方运算。但是,使用着色器,您可以对纹理进行一次采样,然后对结果进行任何处理,因此,实际上没有用例了。



    假。一个采样器对象可以被多个纹理单元引用。您只需为所需的每个采样状态创建一个采样器对象,而无需创建冗余状态。



    我不太确定您在这里问什么问题。着色器中的sampler变量将选择纹理目标,并且还必须与要使用的纹理对象的内部数据匹配(即对于isamplerusampler,您将需要非规范化的整数纹理格式,否则结果是不确定的)。

    但是我不知道“将什么采样器类型传递给什么统一变量”在这里意味着什么。就GL客户端而言,不透明的采样器制服只是可以设置为要使用的纹理单元的索引的东西,并且可以通过glUniform1i等作为整数来完成。没有传递给统一变量的“采样器类型”。



    在一般情况下不行。 GL 4.5规范所需的GL_MAX_TEXTURE_IMAGE_UNITS(定义了片段着色器可以访问多少个不同的纹理单元)仅为16。(每个shder阶段都有单独的限制,因此有GL_MAX_VERTEX_TEXTURE_IMAGE_UNITSGL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS等。它们都是必需的)在当前规格中至少为16。)

    通常,您必须在绘制调用之间切换纹理。 array texturestexture atlasses的使用可能使人们进一步减少必要的状态切换(最终是绘制调用)的数量。

    非常现代的GPU还支持GL_ARB_bindless_texture,它完全绕过了间接的“纹理单元”层,并允许着色器通过一些不透明的句柄直接引用纹理对象(基本上可以归结为在底层引用一些虚拟GPU内存地址)。但是,该功能尚未成为OpenGL标准的一部分。



    是。传统上,GL中没有单独的采样器对象。取而代之的是,采样器状态(例如过滤或环绕模式)是纹理对象本身的一部分。但是现代硬件无法以这种方式运行,因此采样器对象API已作为 GL_ARB_sampler_objects 扩展引入(如今是GL的核心功能)。如果采样器对象绑定(bind)到纹理单元,则其设置将覆盖纹理对象中存在的采样器状态。



    我不知道那是什么意思。着色器程序定义什么“采样器描述”?只有统一的声明,并且可能只有通过layout(binding=...)的初始化。但是,这仅仅是初始值。客户端可以随时通过将统一设置为另一个值来更新该值,这样就不会真正“覆盖”任何内容。但是我不确定你是不是这个意思。

    关于c++ - OpenGL纹理用法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30304105/

    10-12 12:35
    查看更多