将 mix() 应用于具有 Alpha 通道的纹理会导致伪影

时间:2021-02-08 20:03:05

标签: opengl glsl

我有两个纹理:一只猫和一堵墙,两个图像都使用 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,那么我看到的是一堵普通的墙。

Scr when mixValue = 0

如果 mixValue = 1,那么我会看到一只没有伪影的普通猫。

Scr when mixValue = 1

但是如果 mixValue 更接近于 1,那么我会得到工件:

Scr when mixValue closer to 1

我认为图片中存在一些伪影,但我通过 Photoshop 运行这两张图像以避免图像中出现内部伪影。

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

伪影是由透明纹素中的意外颜色数据引起的。一个简单的解决方法是使用预乘 alpha。

相关问题