微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

GLSL 中的最近邻插值

如何解决GLSL 中的最近邻插值

我有一个 GLSL 片段着色器作为管道的一部分,用于渲染混合在一起的两个 3D 体积的切片。对于其中一个卷,我想使用最近邻插值,因为它是一个“分割掩码”(即在每个体素处指示另一个图像中的体素属于哪个结构,例如 0 表示背景,1 表示目标结构;请参见下图中的紫色叠加),因为认的三线性插值会在边界处产生不需要的伪影(下图中边界处的绿线)

enter image description here

我必须如何修改下面的片段着色器代码才能在分割掩码 (vol2) 上使用最近邻插值?

uniform sampler3D vol1;
uniform sampler3D vol2;
uniform sampler2D lut1;
uniform sampler2D lut2;

uniform float maskAlpha = 0.5;

void main()
{
    float data1 = texture3D(vol1,gl_TexCoord[0].xyz).r;
    float data2 = texture3D(vol2,gl_TexCoord[0].xyz).r;
    vec4 col1 = texture2D(lut1,vec2(data1));
    vec4 col2 = texture2D(lut2,vec2(data2));
    
    gl_FragColor = col1 + col2 * maskAlpha;
}

解决方法

您需要在 CPU 端代码中为每个纹理设置所需的过滤:

glEnable(GL_TEXTURE_3D);    
glBindTexture(GL_TEXTURE_3D,???); // here the ??? is the texture ID ...
glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);

基本支持的过滤器是:GL_NEAREST,GL_LINEAR

看这个:setting up 3D texture 了解整个事情。

有关详细信息,另请参阅 glTexParameter 文档

如果您无权访问 CPU 端代码,那么您可以将纹理坐标与片段着色器内的 texel 位置对齐。但是,为此您需要知道纹理的分辨率。

所以对于每个坐标 x=<0,1> 和分辨率 xs [textels],你可以试试这个:

x' = floor((x*(xs-1)+0.5))/(xs-1);

并使用该新坐标来获取纹素...但是没有对其进行测试,因此可能需要进行一些调整(例如将纹素的中心移动 0.5 ...)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。