纹理协调如何在 GLSL 中归一化

How do texture coordinated get normalized in GLSL

所以我知道每个顶点的 texCoords 在被发送到着色器时被标准化为 0.0f 和 1.0f 之间的值,但是它如何确定 500 的 texCoord 是 0.7 还是 0.1?如果对象是在没有指定任何纹理的情况下绘制的呢?

So I know each vertex's texCoords get normalized to a value between 0.0f and 1.0f upon being sent to a shader

这并不完全准确。

纹理坐标可能结束的原因有两个 "normalized."

  1. 定点顶点属性的实际归一化
    • (例如 GL_UNSIGNED_BYTE 值转换为 GLfloat 并除以 255.0f(最大值数据类型))
  2. 纹理环绕模式

在我看来 (2) 就是这里进行标准化的原因。

假设您有 500.0texCoord 并且未启用 (1) 中定义的规范化。该值超出了标准化范围,因此纹理环绕开始发挥作用。可能是:

  1. 夹紧

    • TexCoord = clamp (TexCoord, 0.0, 1.0); {钳}
      
      
                                         @@@ This is deprecated
      
                                      [500.0 --> 1.00]
      
    • TexCoord = clamp (TexCoord, 0.0 + 0.5/texSize, 1.0 - 0.5/texSize);
                                                                         {夹到边缘}
      
      
                                      [500.0 --> 1.0 - 0.5/texSize]
      
  2. 重复

    TexCoord = fract (TexCoord);         [500.0 --> 0.00]
    
  3. 镜像

    vec2 tc  = fract (TexCoord * 0.5f) * 2.0f;
    vec2 len = vec2 (1.0f, 1.0f);
    
    TexCoord = len - abs (tc - len);     [500.0 --> 0.00]
    
  4. ...

基本上你可以看到,在使用常规采样器和 texture (...) 时,任何超出范围 [0.0, 1.0] 的值都将根据换行返回到范围内模式。我没有查看整个模式列表,因为有许多扩展名,这给了你一个大概的概念。


虽然您通常从片段着色器中采样纹理。顶点规范化仅在您调用 glVertexAttribPointer (...) 并将 规范化 参数设置为 GL_TRUE 时发生。如果不启用属性规范化,规范化范围之外的属性将保持不变,片段着色器将接收插值(也超出范围)。这是纹理环绕模式发挥作用的时候;非标准化坐标使其进入片段着色器,texture (...) 使用 wrap 模式将其全部排序。

可以在不使用归一化纹理坐标的情况下对纹理进行采样,这是使用 texelFetch (...) 完成的。但是你一般放弃了很多奢侈品,比如 mipmapping 和纹理过滤。