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