1

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

在此处输入图像描述

我将如何修改下面的片段着色器代码以在分段掩码 ( 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;
}
4

1 回答 1

1

您需要在 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

请参阅:为整个事物设置 3D 纹理。

有关更多信息,另请参阅glTexParameter文档

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

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

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

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

于 2021-04-23T06:57:33.197 回答