我正在将图像加载到OpenGL应用程序中。通常我使用的是线性滤波,但现在测试最接近我发现生成的图像比原始图像明显更暗。但是,在我看来,线性滤波也会导致一些亮度松动。这是例子:
线性过滤:
最近过滤:
原始图片:
现在,我正在设置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并且同样的问题仍然存在。
答案 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过滤器的实际用途。)