当前位置: 首页 > 知识库问答 >
问题:

OpenGL纹理用法

花健
2023-03-14

所以最近我开始阅读OpenGL维基文章。这就是我在这里描述OpenGL纹理的方式。不过,有几点尚不清楚。

以下陈述是真的、假的还是视情况而定?

  1. 将两个纹理绑定到同一个纹理单元是不可能的。
  2. 将两个采样器绑定到同一个纹理单元是不可能的。
  3. 将一个纹理绑定到两个不同的纹理单元是不可能的。
  4. 将一个采样器绑定到两个不同的纹理单元是不可能的。
  5. 应用程序有责任明确将什么采样器类型传递给什么统一变量。
  6. 着色器程序有责任确保将采样器作为正确类型的统一变量。
  7. 纹理单元的数量足够大。让加载到应用程序的每个网格占用尽可能多的纹理单元。
  8. 一些采样器参数是纹理参数的重复。它们将覆盖纹理参数设置。
  9. 一些采样器参数与着色器程序中的采样器描述重复。着色器程序的描述将覆盖采样器参数。

共有1个答案

闾丘鸣
2023-03-14

我将在下面浏览您的陈述。有时我会与OpenGL 4.5核心配置文件规范中的引用争论。这些都不是GL 4.5特有的,我选择它只是因为那是最新的版本。

1.将两个纹理绑定到同一个纹理单元是不可能的。

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

在一个程序对象中,不允许不同采样器类型的变量指向同一纹理图像单元。这种情况只能在下一个触发着色器调用的渲染命令发出时检测到,然后将生成无效_操作错误。

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

2.不可能将两个采样器绑定到同一纹理单元。

您可能指的是采样器对象(而不是GLSL中的“采样器”类型),所以这是真的。

3.不可能将一个纹理绑定到两个不同的纹理单元。

错误。您可以将相同的纹理对象绑定到尽可能多的可用单元。然而,这是一个相当无用的操作。在固定功能管道的日子里,这在一些角落的情况下用处有限。例如,我见过有人将相同的纹理绑定两次并使用寄存器组合器将两者相乘,因为他需要一些方形操作。但是,使用着色器,您可以对纹理进行一次采样,然后对结果做任何您想做的事情,所以真的没有用例了。

4.不可能将一个采样器绑定到两个不同的纹理单元。

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

5.应用程序的责任是明确将哪种采样器类型传递给哪种统一变量。

6.shader program负责确保采样器为正确类型的均匀变量。

我不太确定你在这里问什么。着色器中的采样器变量选择纹理目标,并且还必须匹配您要使用的纹理对象的内部数据(即对于isamp erusamp er,您需要未归一化的整数纹理格式,否则结果是未定义的)。

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

7.纹理单元的数量足够大。让每个加载到应用程序的网格占据尽可能多的纹理单元。

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

通常,在绘制调用之间必须切换纹理。使用数组纹理和纹理图谱可能会进一步减少必要的状态切换(以及最终的绘制调用)的数量。

非常现代的GPU还支持GL_ARB_bindless_纹理,它完全绕过了间接寻址的“纹理单元”层,并允许着色器通过一些不透明句柄直接引用纹理对象(基本上归结为引用引擎盖下的某个虚拟GPU内存地址)。然而,该功能还不是OpenGL标准的一部分。

8.一些采样器参数是纹理参数的重复。它们将覆盖纹理参数设置。

对传统上,GL中没有单独的采样器对象。取而代之的是,诸如过滤或包裹模式之类的采样器状态是纹理对象本身的一部分。但现代硬件并不是这样运行的,因此sampler objects API被引入为GL_ARB_sampler_objects扩展(如今,它是GL的核心功能)。如果采样器对象绑定到纹理单元,其设置将覆盖纹理对象中存在的采样器状态。

9.一些采样器参数与着色器程序中的采样器描述重复。着色器程序的描述将覆盖采样器参数。

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

 类似资料:
  • 我有一个用于OpenGL中模型渲染的纹理数组。此数组包含漫反射和镜面纹理。由于某些网格没有镜面纹理,因此我在每次渲染后简单地将NULL纹理绑定到我的镜面采样器,并且只有当网格具有镜面纹理时,我才绑定一个。但是,我仍然在没有镜面纹理的网格上看到镜面纹理。 这是我的渲染代码 材质索引保存数组中纹理的索引,如果网格没有镜面纹理 索引为-1 纹理单元0用于漫反射 纹理单元2用于镜面

  • “我在我的申请中发现了一个奇怪的行为,希望你能解释给我听。”。你看,我有两个3D纹理,它们被发送到片段着色器,渲染得非常好。但有一个问题,当我创建另一个纹理(它是1D纹理)时,一个黑屏正在被渲染,而不是正确的前一个结果。 关于这个1D纹理,我甚至没有将其发送到片段着色器。当我调用glTexImage1D(…)时,黑屏就出现了。我评论这句话,它就消失了!!这两种纹理被渲染。 我觉得纹理单位肯定有问题

  • 在andrid上的opengl es中,当我将两个纹理相邻放置时,会有一个轻微的接缝,可以看到它们后面绘制的对象。基本上看起来是一个小差距。我把范围缩小到了地图上 glTexParameteri(GL_纹理_2D、GL_纹理_最小过滤器、GL_线性_MIPMAP_线性);glTexParameteri(GL_纹理_2D、GL_纹理_MAG_过滤器、GL_线性); 如果我将它们都设置为距接缝最近的G

  • 假设我有一个金字塔…我知道如何绘制它,我知道如何为整个金字塔设置纹理,但如何为每面墙设置不同的纹理? 我通过在 我试图通过添加<code>GL11.glBindTexture(GL11.GL_TEXTURE_2D,TEXTURE.getTextureID())来绑定纹理 后,但

  • 好的,所以我需要创建我自己的纹理/图像数据,然后在OpenGL中将它显示到一个四边形上。我让四边形工作,我可以用我自己的纹理加载器在上面显示一个TGA文件,它完美地映射到四边形。 但是我如何创建自己的“自制图像”,即每个像素1000x1000和3个通道(RGB值)?纹理数组的格式是什么,例如如何将像素(100,100)设置为黑色? 这就是我对完全白色的图像/纹理的想象: 编辑:下面的答案是正确的,

  • 本文向大家介绍OpenGL ES纹理详解,包括了OpenGL ES纹理详解的使用技巧和注意事项,需要的朋友参考一下 使用前面学过的技术已经可以利用OpenGL ES构建立体图形,并通过顶点着色器和片元着色器对其进行各种变化呢和光照等效果使得三维效果更加真实,实际上我看看到很多的3D游戏漂亮多了,那是因为有各种各样的漂亮的图像带给人很多视觉盛宴,这篇文章在前面的基础上,增加物体的表面贴图,使得物体更