opengl - 将 mix() 应用于具有 Alpha 通道的纹理会导致伪影
问题描述
我有两个纹理:猫和墙,两个图像都是使用 QImage 加载的,具有相同的大小(512x512),并以 PNG 格式(QImage::Format_ARGB32)加载。
//Load texture image
QImage imgWallTexture(":Scenes/Sc5Texture/textures/wall512x512.png");
if(imgWallTexture.isNull()) {
qInfo("[ERROR] initScene: image texture load failed!");
return;
}
imgWallTexture = QGLWidget::convertToGLFormat(imgWallTexture);
//Load texture image
QImage imgCatTexture(":Scenes/Sc5Texture/textures/cat512x512.png");
if(imgCatTexture.isNull()) {
qInfo("[ERROR] initScene: image texture load failed!");
return;
}
imgCatTexture = QGLWidget::convertToGLFormat(imgCatTexture);
//Texture ID(name)
unsigned int wallTexture = 0;
unsigned int catTexture = 0;
//Allocate 1 buffer for textures
glFunctions->glGenTextures(1, &wallTexture);
glFunctions->glGenTextures(1, &catTexture);
//Select wall texture
glFunctions->glBindTexture(GL_TEXTURE_2D, wallTexture);
//Load data to texture
glFunctions->glTexImage2D(GL_TEXTURE_2D, //selected texture type
0, //mipmap level(we generate him using OpenGL)
GL_RGBA, //texture data format
imgWallTexture.width(),
imgWallTexture.height(),
0, //always zero
GL_RGBA, //image format
GL_UNSIGNED_BYTE, //image data format
imgWallTexture.bits() //image data
);
if(glFunctions->glGetError() != GL_NO_ERROR) {
qInfo("[ERROR] initScene: glTexImage2D failed!");
return;
}
//Generate mipmap for texture
glFunctions->glGenerateMipmap(GL_TEXTURE_2D);
//Setting up texture
//Texture draw
glFunctions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glFunctions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
//Texture filtration
glFunctions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glFunctions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//Select cat texture
glFunctions->glBindTexture(GL_TEXTURE_2D, catTexture);
//Select wall texture
glFunctions->glBindTexture(GL_TEXTURE_2D, catTexture);
//Load data to texture
glFunctions->glTexImage2D(GL_TEXTURE_2D, //selected texture type
0, //mipmap level(we generate him using OpenGL)
GL_RGBA, //texture data format
imgCatTexture.width(),
imgCatTexture.height(),
0, //always zero
GL_RGBA, //image format
GL_UNSIGNED_BYTE, //image data format
imgCatTexture.bits() //image data
);
if(glFunctions->glGetError() != GL_NO_ERROR) {
qInfo("[ERROR] initScene: glTexImage2D failed!");
return;
}
//Generate mipmap for texture
glFunctions->glGenerateMipmap(GL_TEXTURE_2D);
//Setting up texture
//Texture draw
glFunctions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glFunctions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
//Texture filtration
glFunctions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glFunctions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//Unselect texture
glFunctions->glBindTexture(GL_TEXTURE_2D, 0);
在我的片段着色器代码中,我使用 mix() 函数来混合纹理。
#version 450 core
out vec4 FragColor;
in vec2 wallTexCoord;
in vec2 catTexCoord;
uniform float mixValue;
//for texture
uniform sampler2D wallTexture;
uniform sampler2D catTexture;
void main()
{
FragColor = mix(texture(wallTexture, wallTexCoord), texture(catTexture, catTexCoord), mixValue);
}
如果 mixValue = 0,那么我会看到一堵普通的墙。
如果 mixValue = 1,那么我会看到一只没有伪影的普通猫。
但如果 mixValue 更接近 1,那么我会得到伪像:
我认为图片中有一些伪影,但我通过 Photoshop 运行了两张图像以避免图像中的内部伪影。
我该如何解决?
解决方案
伪影是由透明纹素中的意外颜色数据引起的。一个简单的解决方法是使用预乘 alpha。
推荐阅读
- java - ip(...) 中的错误:安装包 ... 退出状态非零
- python - 在熊猫下面有条件地选择一个单元格
- css - Flexbox 高度在滚动时也总是 100%
- java - Java GUI,从一个类转换到另一个类
- ansible - Ansible - 如何检查列表中的所有元素是否相同?
- javascript - 尝试使用 NodeJS 从 SQLite DB 获取数据
- oracle - 递归 WITH 查询在 oracle 中如何工作?什么时候进入循环?
- sas - 转换 SAS DATE 并在 PROC SQL 中使用
- visual-studio-code - VSCode多次复制粘贴?
- jasperserver - Jasper 服务器...仪表板在哪里?