1

我试图在 OpenGL ES 2.0 片段着色器中处理 mipmaped 纹理的细节级别。

根据这个答案,不可能使用bias参数来texture2D访问片段着色器中特定级别的细节。根据这篇文章,详细程度是根据相邻片段的并行执行自动计算的。我必须相信事情就是这样运作的。

我无法理解的是它的原因为什么不能访问特定级别的详细信息,而这样做确实应该非常简单?为什么必须依赖复杂的固定功能呢?

对我来说,这似乎非常违反直觉。毕竟,整个 OpenGL 相关的东西都是从固定的功能演变而来的。并且 OpenGL ES 旨在覆盖比 OpenGL 更广泛的硬件范围,因此仅支持许多事物的更简单版本。因此,如果规范的开发人员决定 LOD 参数是强制性的(可能默认为零),并且着色器程序员以他认为合适的任何方式来制定适当的 LOD,我将完全理解。添加一个自动执行该计算的函数似乎是我在桌面 OpenGL 中所期望的。

不提供对特定级别的直接访问对我来说根本没有任何意义,无论我如何看待它。特别是因为该bias参数表明我们确实被允许调整细节级别,所以显然这不是关于从内存中仅针对并行处理的一堆片段的单个级别获取数据。我想不出任何其他原因。


当然,为什么问题往往会吸引意见。但由于 Stack Overflow 不接受基于意见的答案,因此请将您的意见仅作为评论发表。另一方面,答案应该基于可验证的事实,例如有明确知识的人的陈述。如果有开发者讨论这个事实的记录,那就完美了。如果里面有人发博文讨论这个问题,那还是很好的。

由于堆栈溢出问题应该处理真正的编程问题,有人可能会争辩说,询问原因是一个糟糕的问题。获得答案不会使明确的 lod 访问突然出现,因此不会帮助我解决眼前的问题。但我觉得这里的原因可能是由于 OpenGL ES 如何工作的一些重要方面,我到目前为止还没有掌握。如果是这样,那么理解这一决定背后的动机将有助于我和其他人更好地理解 OpenGL ES 作为一个整体,从而在他们的程序中更好地利用它,在性能、准确性、可移植性等方面. 因此,我可能会将这个问题表述为“我错过了什么?”,这对我来说是一个非常现实的编程问题。

4

1 回答 1

8

texture2DLod (...)在顶点着色器纹理查找中起到非常重要的作用,这在片段着色器中是不必要的。

当在片段着色器中进行纹理查找时,片段着色器可以访问当前正在着色的图元的每个属性梯度(如dFdx (...)dFdy (...)的偏导数),并且它使用此信息来确定在过滤期间从哪个 LOD 获取相邻的纹素.

在顶点着色器运行时,没有关于图元的信息是已知的,也没有这样的梯度。在顶点着色器中使用 mipmap 的唯一方法是显式获取特定 LOD,这就是引入该函数的原因。

桌面 OpenGL 更智能地解决了这个问题,它为顶点着色器提供了一种纹理查找变体,实际上将渐变作为其输入之一。该函数被称为textureGrad (...),它是在 GLSL 1.30 中引入的。ESSL 1.0 是从 GLSL 1.20 派生的,并没有从所有相同的基本硬件功能中受益。

ES 3.0 没有这个限制,桌面 GL 3.0 也没有。当显式 LOD 查找被引入桌面 GL (3.0) 时,它可以从任何着色器阶段完成。这可能只是一个疏忽,或者可能存在一些基本的硬件限制(回想一下,旧的 GPU 曾经有专门的顶点和像素着色器硬件,而嵌入式 GPU 从来没有处于 GPU 设计的前沿)。


不管这个限制的最初原因是什么,它已经在后来的 OpenGL ES 2.0 扩展中得到纠正,并且是 OpenGL ES 3.0 的核心。现代 GL ES 2.0 实现很有可能实际上支持片段着色器中的显式 LOD 查找,给出以下扩展:

GL_EXT_shader_texture_lod

在片段着色器中显示显式 LOD 查找的伪代码:

#version 100
#extension GL_EXT_shader_texture_lod : require

attribute vec2      tex_st;
uniform   sampler2D sampler;

void main (void)
{
  // Note the EXT suffix, that is very important in ESSL 1.00
  gl_FragColor = texture2DLodEXT (sampler, tex_st, 0);
}
于 2015-03-11T12:11:17.203 回答