非片段着色器中的纹理查找如何工作?

时间:2014-08-08 04:14:38

标签: opengl glsl

以下是GLSL规范的摘录:

  

"纹理查找功能在所有着色阶段都可用。但是,仅为片段着色器计算自动细节级别。其他着色器的操作就像细节的基本级别计算为零一样。"

所以这就是我的看法:

顶点着色器:

vec4 texel = texture(SamplerObj, texCoord);   
// since this is vertex shader, sampling will always take place
// from 0th Mipmap level of the texture.

片段着色器:

vec4 texel = texture(SamplerObj, texCoord);   
// since this is fragment shader, sampling will take place
// from Nth Mipmap level of the texture, where N is decided
// based on the distance of object on which texture is applied from camera.

我的理解是否正确?

2 个答案:

答案 0 :(得分:4)

听起来不错。您可以在顶点着色器中使用textureLod()而不是texture()指定显式LOD。

我相信你也可以通过在纹理上设置GL_TEXTURE_MIN_LOD参数来使用更高的LOD。如果你打电话,例如:

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 2.0f);

在绑定纹理时,在顶点着色器中对纹理进行采样时,应使用mipmap level 2。我从未尝试过这个,但这是我对行为定义的理解。

答案 1 :(得分:2)

// since this is fragment shader, sampling will take place
// from Nth Mipmap level of the texture, where N is decided
// based on the distance of object on which texture is applied from camera.

我认为关于距离的一点不正确。要使用的mipmap级别是使用相邻像素的纹理坐标的推导来确定的。采样器硬件可以确定这一点,因为生成的片段着色器代码通常使用SIMD指令并同时为多个像素生成值。例如,在英特尔硬件上,单个线程通常在4x4像素网格上运行。这意味着无论何时将消息发送到采样器硬件,都会给出一组纹理坐标16和16个纹素。采样器硬件可以通过查看这16个纹理坐标之间的差异来确定推导。这可能就是GLSL规范进一步说明的原因:

  

隐式导数在非均匀控制流和非碎片着色器纹理提取中未定义。

非均匀控制流会弄乱隐式导数,因为可能并非线程中正在处理的所有片段都会同时进行采样。