You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何GLSL中使用1.0/textureSize计算单个texel的尺寸?

为什么使用1.0 / textureSize(image, 0)计算单个纹素(texel)尺寸

你的推导逻辑完全正确,这个公式的成立前提是OpenGL的纹理采样规则:所有纹理的UV坐标都是归一化的[0.0, 1.0]区间值,和纹理本身的实际像素分辨率无关。

具体逻辑拆解

  • GLSL内置函数textureSize(sampler, lod)会返回指定LOD层级下纹理的实际像素分辨率,比如一张分辨率为1024×512的纹理,调用textureSize(image, 0)(0代表基础LOD层)会返回ivec2(1024, 512)
  • 归一化规则下,纹理的完整宽度对应UV坐标的1.0单位,这个范围内总共排布了1024个横向纹素,因此单个横向纹素对应的UV偏移量就是 1.0 / 1024
  • 同理单个纵向纹素对应的UV偏移量是1.0 / 512
  • 把两个维度的计算合并就得到了代码里的写法:vec2 tex_offset = 1.0 / textureSize(image, 0);

计算得到的tex_offset本质是单个纹素在归一化UV坐标系下的尺寸,方便我们在着色器中精准对相邻纹素做采样。你贴的高斯模糊代码就是典型的使用场景:

#version 330 core
out vec4 FragColor;
  
in vec2 TexCoords;

uniform sampler2D image;
  
uniform bool horizontal;
uniform float weight[5] = float[] (0.227027, 0.1945946, 0.1216216, 0.054054, 0.016216);

void main()
{             
    vec2 tex_offset = 1.0 / textureSize(image, 0); // 获取单个纹素的UV尺寸
    vec3 result = texture(image, TexCoords).rgb * weight[0]; // 当前片段的贡献值
    if(horizontal)
    {
        for(int i = 1; i < 5; ++i)
        {
            // 水平方向左右偏移i个纹素采样
            result += texture(image, TexCoords + vec2(tex_offset.x * i, 0.0)).rgb * weight[i];
            result += texture(image, TexCoords - vec2(tex_offset.x * i, 0.0)).rgb * weight[i];
        }
    }
    else
    {
        for(int i = 1; i < 5; ++i)
        {
            // 垂直方向上下偏移i个纹素采样
            result += texture(image, TexCoords + vec2(0.0, tex_offset.y * i)).rgb * weight[i];
            result += texture(image, TexCoords - vec2(0.0, tex_offset.y * i)).rgb * weight[i];
        }
    }
    FragColor = vec4(result, 1.0);
}

这段代码实现了可分离的高斯模糊,将二维高斯卷积拆分为水平、垂直两个一维卷积Pass,每次采样偏移时乘以tex_offset就能保证每次偏移刚好对应一个实际纹素的位置,保证模糊效果的准确性。

内容的提问来源于stack exchange,提问作者San Andreas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 04:27:03