如何在GLSL中对纹理协调进行规范化

时间:2015-08-06 01:05:55

标签: textures glsl coordinates

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

1 个答案:

答案 0 :(得分:1)

  

所以我知道每个顶点的texCoords在被发送到着色器时被标准化为介于0.0f和1.0f之间的值

这不完全准确。

纹理坐标可能会卷入“标准化”的原因有两个。

  1. 定点顶点属性的实际标准化
    • 例如 GL_UNSIGNED_BYTE值转换为GLfloat并除以 255.0f (数据类型的最大值))
  2. 纹理包裹模式
  3. 听起来像(2)就是在这里进行规范化。

    假设您有texCoord 500.0 ,并且未启用(1)中定义的规范化。该值超出标准化范围,因此纹理包装起作用。它可能是:

    1. 钳位

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

                                      [500.0 --> 1.0 - 0.5/texSize]
      
                                                                         {clamp to edge}
      
      
      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. ...

    5. 基本上,当使用常规采样器和texture (...)时,您可以看到 [0.0,1.0] 范围之外的任何值都将基于换行模式返回到范围内。我没有浏览整个模式列表,因为有很多扩展,这给你一个大概的想法。

      您通常会从片段着色器中对纹理进行采样。只有在规范化参数设置为glVertexAttribPointer (...)的情况下调用GL_TRUE时,才会进行顶点规范化。如果未启用属性规范化,则规范化范围之外的属性将保持不变,并且片段着色器将接收插值(也超出范围)。这是纹理包装模式发挥作用的时候;非标准化坐标使其成为片段着色器,texture (...)使用环绕模式对所有内容进行排序。

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