为什么在片段着色器中无法访问纹理lod

时间:2015-03-11 09:48:05

标签: opengl-es fragment-shader texture2d glsles level-of-detail

我正试图在OpenGL ES 2.0片段着色器中使用mipmap纹理的细节级别。

根据this answer,无法使用bias参数texture2D来访问片段着色器中的特定详细信息级别。根据{{​​3}},相反的细节水平是从相邻片段的并行执行中自动计算出来的。我必须相信这就是事情的运作方式。

我无法理解的是为什么 为什么无法访问特定级别的详细信息,这样做的确非常简单? 为什么不得不依赖复杂的固定功能?

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

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


当然,为什么问题往往会吸引意见。但由于Stack Overflow不接受基于意见的答案,请将您的意见仅作为评论发布。另一方面,答案应该基于可验证的事实,例如具有明确知识的人的陈述。如果有任何开发者讨论这个事实的记录,那将是完美的。如果有人在讨论这个问题时有博客文章,那仍然会非常好。

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

1 个答案:

答案 0 :(得分: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);
}