【问题标题】:How are textures referenced in shaders?着色器中如何引用纹理?
【发布时间】:2015-12-23 09:30:28
【问题描述】:

快速 OpenGL 新手问题。我的片段着色器中有这一行:

uniform sampler2D mytexture;

我找到了我正在使用的示例代码,但找不到任何对 mytexture 的引用;只找到激活纹理单元并将之前复制到 GPU 的纹理绑定到它的调用。

我的问题是,片段着色器如何知道我正在使用的 only 纹理必须通过mytexture 引用?

我会想到一个

glBindTextureToUniform(texture_id, "mytexture");

或类似的必须被调用。

【问题讨论】:

标签: opengl graphics textures shader multitexturing


【解决方案1】:

正如concept3d 提到的,映射是在纹理单元和制服之间而不是纹理之间。这种差异的原因是多重纹理。

纹理单元是 OpenGL 中促进多重纹理的机制。当您希望在着色器中查找多个纹理时,您将每个纹理绑定到不同的纹理单元(实际上您将其绑定到单元内的目标)并为每个纹理设置不同的制服,以便在着色器中引用它们。每个纹理单元都有多个目标,例如 1D、2D、3D 等。

在着色器中查找的纹理,通过制服,指的是单位。它的类型(例如sampler2D)决定了所使用单元中的目标。这是映射的方式

统一的sampler2D mytexture; | | | | | +--->GL_TEXTURE0 / UNIT 0 GL_TEXTURE1 / UNIT 1 GL_TEXTURE2 / UNIT 2 | +--------------------+ +--------+ +------ ---------------+ | | +------------+ | | +------------+ | | +------------+ | | | | TEXTURE_1D | | | | TEXTURE_1D | | | | TEXTURE_1D | | | | +------------+ | | +------------+ | | +------------+ | | | +------------+ | | +------------+ | | +------------+ | +---------------->| TEXTURE_2D | | | | TEXTURE_2D | | | | TEXTURE_2D | | | +------------+ | | +------------+ | | +------------+ | | +------------+ | | +------------+ | | +------------+ | … | | TEXTURE_3D | | | | TEXTURE_3D | | | | TEXTURE_3D | | | +------------+ | | +------------+ | | +------------+ | | +------------+ | | +------------+ | | +------------+ | | |TEX_1D_ARRAY| | | |TEX_1D_ARRAY| | | |TEX_1D_ARRAY| | | +------------+ | | +------------+ | | +------------+ | | . | | . | | . | | . | | . | | . | | . | | . | | . | +--------------------+ +--------+ +------ ---------------+

从图像或表格等将纹理数据上传到这些目标(内框)。如果未明确设置,则活动单元默认为GL_TEXTURE0

片段着色器如何知道我正在使用的唯一纹理必须通过片段着色器中的 mytexture 引用?

最好用单位 ID 设置制服。如果你没有,它仍然有效,那么你取决于你的图形驱动程序的宽容行为。它可能不适用于所有设备,甚至可能不适用于驱动程序的未来版本。我们将不得不查找规范。知道这是否允许。

【讨论】:

  • 谢谢!我在 Emacs 中使用 artist-mode 绘制了它们 :)
【解决方案2】:

OpenGL 有概念纹理单元,从0 to MAX_TEXTURE_UNIT 开始固定。

  1. 首先选择活动纹理单元,使用glActiveTexture(GL_TEXTURE0)
  2. 然后将纹理绑定到活动纹理单元。使用glBindTexture(GL_TEXTURE_2D, tex);
  3. 最后,您将着色器统一值设置为引用 纹理单元而不是纹理 ID,它使用绑定到该单元的任何纹理。

将纹理单元视为一个容器,uniform 变量使用纹理单元中的任何内容。

换句话说,

  • 您将texture Id 绑定到texture unit。不是直接glBindTextureToUniform

  • 您将 uniform 变量设置为 纹理单元 的值,它将引用绑定到它的任何纹理。

【讨论】:

  • 赞成第三点;是许多初学者的绊脚石。
猜你喜欢
  • 2017-06-21
  • 2013-09-17
  • 1970-01-01
  • 1970-01-01
  • 2011-12-29
  • 2020-09-06
  • 2012-02-07
  • 2017-03-28
  • 1970-01-01
相关资源
最近更新 更多