所以我知道每个顶点的texCoords在被发送到着色器时被标准化为0.0f和1.0f之间的值,但是它如何确定例如500的texCoord是0.7还是0.1 ?如果在没有指定任何纹理的情况下绘制对象怎么办?
答案 0 :(得分:1)
所以我知道每个顶点的texCoords在被发送到着色器时被标准化为介于0.0f和1.0f之间的值
GL_UNSIGNED_BYTE
值转换为GLfloat
并除以 255.0f (数据类型的最大值))听起来像(2)就是在这里进行规范化。
假设您有texCoord
500.0 ,并且未启用(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);
[500.0 --> 1.0 - 0.5/texSize]
{clamp to edge}TexCoord = fract (TexCoord); [500.0 --> 0.00]
vec2 tc = fract (TexCoord * 0.5f) * 2.0f;
vec2 len = vec2 (1.0f, 1.0f);
TexCoord = len - abs (tc - len); [500.0 --> 0.00]
基本上,当使用常规采样器和texture (...)
时,您可以看到 [0.0,1.0] 范围之外的任何值都将基于换行模式返回到范围内。我没有浏览整个模式列表,因为有很多扩展,这给你一个大概的想法。
您通常会从片段着色器中对纹理进行采样。只有在规范化参数设置为glVertexAttribPointer (...)
的情况下调用GL_TRUE
时,才会进行顶点规范化。如果未启用属性规范化,则规范化范围之外的属性将保持不变,并且片段着色器将接收插值(也超出范围)。这是纹理包装模式发挥作用的时候;非标准化坐标使其成为片段着色器,texture (...)
使用环绕模式对所有内容进行排序。
可以在不使用标准化纹理坐标的情况下对纹理进行采样,这可以使用texelFetch (...)
完成。但是你会放弃很多奢侈品,比如mipmapping和纹理过滤。