我是否正确理解在OpenGL中绘制每个具有不同纹理的多个对象的典型方法是使用glBindTexture
一次简单地绑定一个纹理并绘制使用它的对象,然后绑定不同的纹理并做同样的事情?
换句话说,在任何特定时间,只有一个纹理可以“活动”以进行绘制,这是使用glBindTexture
绑定的最后一个纹理。这是对的吗?
答案 0 :(得分:9)
使用glBindTexture一次绑定一个纹理并绘制使用它的对象,然后绑定不同的纹理并执行相同的操作?
换句话说,在任何特定时间,只有一个纹理可以“活动”以进行绘制
这两个陈述不是一回事。
单个渲染操作在任何时候都只能使用单个 set 纹理。该集合由当前绑定到各种纹理图像单元的纹理定义。可用的纹理图像单元数可通过GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
查询。
因此,对于单个渲染命令,多个纹理可以“活动”。
然而,不与绑定一堆纹理然后渲染多个对象相同,其中每个对象仅使用一些(或者在您的情况下为一个)绑定纹理。 可以这样做,但实际上,没有多大意义。
GLSL采样器和纹理图像单元之间的关联是程序对象状态的一部分。这是the value you set on the sampler uniform。因此,为了做你的建议,你必须绑定一堆纹理,将制服设置为其中一个,渲染,然后将制服设置为下一个,渲染等。
您仍然需要承担绑定这些纹理的所有费用。你仍然需要承担改变制服的所有开销。实际上,它可能效率较低,因为正常的方式(绑定,渲染,绑定,渲染)不涉及改变统一状态。
另外,这很奇怪。通常,您不应动态更改统一采样器状态。你定义了一个简单的约定(漫反射纹理来自单元0,镜面反射来自单元1等),你坚持这个约定。任何GL 3.x级硬件都需要提供不少于48个纹理图像单元(每级16个),所以它不会像你要用完一样。
有些机制可以完全不同于你所说的。例如,可以利用array textures,但这需要显式着色器逻辑和支持。这几乎肯定比“绑定一堆纹理”方法更快,因为你只绑定一个。此外,你要改变的制服是一个常规的数据统一而不是采样器制服,这可能会更快。
使用数组纹理机制,您还可以利用instancing,假设您使用稍微不同的参数渲染相同的对象。