OpenGL,将透明纹理与对象颜色混合

OpenGL, blending transparent textures with object color

本文关键字:对象 颜色 混合 纹理 透明 OpenGL      更新时间:2023-10-16

我可以将片段着色器设置为显示对象的颜色或对象的纹理颜色。我的问题是,我如何将这两者结合起来,这样我就可以得到一张带有砖块线条的透明图片,然后显示下面的不同颜色,这样通过改变物体的颜色,你就可以改变砖块的颜色。

我尝试在片段着色器中使用mix(),但它只向我显示glClearColor,它是透明的,而不是我指定的红色!

我的碎片着色器:

#version 120
uniform sampler2D diffuse;
varying vec3 shared_colors;
varying vec2 shared_texCoords;
void main() {
    vec4 color = vec4(shared_colors, 1);
    vec4 texture = texture2D(diffuse, shared_texCoords);
    vec4 finalColor = vec4(mix(color.rgb, texture.rgb, 1), 1);
    gl_FragColor = finalColor;
}

编辑:添加纹理加载程序功能:

void Texture::createTexture(SDL_Surface *rawImage, GLenum format) {
    //Convert to a texture of pure color pixels for OpenGL
    SDL_Surface *image = SDL_CreateRGBSurface(NULL, rawImage->w, rawImage->h, 32, 0, 0, 0, 0);
    SDL_BlitSurface(rawImage, NULL, image, NULL);
    //Generate texture
    glGenTextures(1, &m_texture);
    //Tell OpenGL to use this texture
    glBindTexture(GL_TEXTURE_2D, m_texture);
    //Set texture parameters
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    //Generate texture from image
    glTexImage2D(GL_TEXTURE_2D, 0, 4, image->w, image->h, 0, format, GL_UNSIGNED_BYTE, image->pixels);
    m_dimension = new PixelSize(image->w, image->h);
    //Free loaded images
    SDL_FreeSurface(rawImage);
    SDL_FreeSurface(image);
}

您应该仔细查看mix (...),以了解为什么对a使用1实际上没有任何意义(返回y

让我们从考虑通常的阿尔法混合函数开始:GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA

这意味着获取源的alpha通道,并将其乘以源颜色(片段颜色),然后将其添加到alpha通道乘以目标颜色的倒数(framebuffer

AlphaBlend=SrcRGBA*SrcA+DstRGBA*(1.0-SrcA

现在,如果你看看mix (...)的实现,它应该很熟悉:

x*(1.0-a)+y*a

显然,这与a的任何值的顺序有关!=0.51.0-0.5=0.5),更重要的是,在这种情况下,如果您对a使用1.0的值,它会完全抛出您的一种颜色(因为这会使x乘以0.0)。