Mipmap和最近的过滤会导致图像变暗

时间:2013-06-13 08:03:59

标签: opengl

我正在将图像加载到OpenGL应用程序中。通常我使用的是线性滤波,但现在测试最接近我发现生成的图像比原始图像明显更暗。但是,在我看来,线性滤波也会导致一些亮度松动。这是例子:

线性过滤: Linear filtering

最近过滤: Nearest filtering

原始图片: Original image

现在,我正在设置mipmaps级别(为4)。我发现当不使用mipmap时,原始亮度是完整的。可能是什么问题?它与伽马校正有关吗?

以下是图像加载和mipmap生成的代码:

                    ILinfo imageInfo;

        iluGetImageInfo(&imageInfo);
        iluFlipImage();

        if (imageInfo.Format == IL_RGB)
        {
            ilConvertImage(IL_BGRA, IL_UNSIGNED_BYTE);
        }
        else if (imageInfo.Format == IL_RGBA)
        {
            ilConvertImage(IL_BGRA, IL_UNSIGNED_BYTE);

        }

        iluGetImageInfo(&imageInfo);

        glPixelStorei(GL_PACK_ALIGNMENT, 1);
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

        glGenTextures(1, &textureName);
        glBindTexture(GL_TEXTURE_2D, textureName);

        glTexStorage2D(GL_TEXTURE_2D,numMipMapLevels,GL_RGBA8,imageInfo.Width,imageInfo.Height);
        glTexSubImage2D(GL_TEXTURE_2D,0,0,0,imageInfo.Width,imageInfo.Height,GL_BGRA,GL_UNSIGNED_BYTE,imageInfo.Data);

        /* ==================================== */
        // Trilinear filtering by default

        if(smooth){
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
            glGenerateMipmap(GL_TEXTURE_2D);
        }else{
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        }

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

我也在自定义FBO中运行MSAA传递,但它看起来与问题无关,因为我在测试时也关闭了MSAA并且同样的问题仍然存在。

1 个答案:

答案 0 :(得分:4)

从你的代码中看起来你创建了一个mipmapped纹理(如你所说的那样有4个mipmap级别),但之后只设置了第一级的图像。这意味着所有其他级别的图像都是未定义的。然后使用GL_NEAREST_MIPMAP_LINEAR时,它将访问最适合像素 - 纹素比(MIPMAP_LINEAR - 部分)的两个mipmap级别,然后从每个级别({{1)中选择一个最近的纹素}} - part)并插入那些。

从你的图像看起来未指定的mipmap级别只是黑色,所以你得到纹理颜色和黑色之间的插值,因此黑暗的纹理(嗯,他们实际上可以包含任何东西,纹理甚至不应该工作,因为纹理是不完整的,但在这方面可能不可变的存储行为不同)。当不使用mipmap时(因此仅使用NEAREST创建单个级别),过滤中将只使用一个级别(即使使用mipmapped过滤器),当然它具有有效的图像。

如果您打算使用某种mipmapping,那么您应该为每个mipmap级别设置纹理图像(或者设置顶级图像并在之后进行glGenerateMipmap调用)。如果您只是想使用真正的最近邻居过滤,那么只需使用glTexStorage(除了真正的三线性过滤器GL_NEAREST之外,我从未真正看到所有其他mipmap过滤器的实际用途。)