2017-08-17 6 views
5

J'essaye d'utiliser OpenGL (C++) pour rendre deux textures sur un rectangle. J'ai de la difficulté à les mélanger tous les deux.Le mélange OpenGL crée une bordure blanche autour des textures

La première image provient d'un fichier .jpg (https://learnopengl.com/img/textures/container.jpg). Cette image n'a pas de canal alpha.

La deuxième image provient d'un fichier .png (https://learnopengl.com/img/textures/awesomeface.png) et possède un canal alpha.

Le problème est que lorsque j'essaie de fondre les deux images, cela crée une bordure blanche autour de l'image transparente.

J'ai essayé quelques modes de fusion différents (comme recommandé par l'OP dans cette question: Alpha blending with multiple textures leaves colored border) mais aucun d'entre eux ne semble fonctionner.

Mon fragment shader ressemble à ceci:

#version 330 core 
out vec4 FragColor; 

in vec3 ourColor; 
in vec2 TexCoord; 

// texture samplers 
uniform sampler2D texture1; 
uniform sampler2D texture2; 

void main() 
{ 
    // linearly interpolate between both textures 
    FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.5); 
} 

J'ai le test de profondeur activé (ne semble pas avoir d'effet) et je suis en utilisant le code suivant pour la mise en place mon mélange:

glEnable(GL_DEPTH_TEST); 
glEnable(GL_BLEND); 
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 

Ceci est ma principale boucle de rendu:

Rendering::Pipeline pipeline = Rendering::Pipeline("src/GLSL/vertex.glsl", "src/GLSL/fragment.glsl"); 
pipeline.load(); 

//      Position,    Color,     Texture Coord. 
//      (X Y Z)     (R G B)     (S T) 
float vertices [32] = { 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // top right 
         0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // bottom right 
         -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom left 
         -0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f };// top left 

unsigned int vertexIndices [6] = { 3, 2, 0, 
            2, 1, 0 }; 


unsigned int vbo; 
unsigned int vao; 
unsigned int ebo; 

glGenVertexArrays(1, &vao); 
glGenBuffers(1, &vbo); 
glGenBuffers(1, &ebo); 

glBindVertexArray(vao); 

glBindBuffer(GL_ARRAY_BUFFER, vbo); 
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); 
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(vertexIndices), vertexIndices, GL_STATIC_DRAW); 

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*) 0); 
glEnableVertexAttribArray(0); 

glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*) (3 * sizeof(float))); 
glEnableVertexAttribArray(1); 

glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*) (6 * sizeof(float))); 
glEnableVertexAttribArray(2); 

unsigned int texture1; 
unsigned int texture2; 
int width; 
int height; 
int numChannels; 
unsigned char* data; 

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

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

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 

data = stbi_load("res/jpg/container.jpg", &width, &height, &numChannels, STBI_rgb); 

if (data) 
{ 
    lTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); 
    glGenerateMipmap(GL_TEXTURE_2D); 
} 

stbi_image_free(data); 

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

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

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 

stbi_set_flip_vertically_on_load(true); 

data = stbi_load("res/png/awesomeface.png", &width, &height, &numChannels, STBI_rgb_alpha); 

if (data) 
{ 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); 
    glGenerateMipmap(GL_TEXTURE_2D); 
} 

stbi_image_free(data); 

glUseProgram(pipeline.getProgramId()); 
glUniform1i(glGetUniformLocation(pipeline.getProgramId(), "texture1"), 0); 
glUniform1i(glGetUniformLocation(pipeline.getProgramId(), "texture2"), 1); 

while (!this->mQuit) 
{ 
    this->counter.start(); 

    InputProcessor::getInstance().processInputs(); 

    if (this->debugOverlay) 
    { 
     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 
    } 
    else 
    { 
     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 
    } 

    glClearColor(0.2f, 0.3f, 0.3f, 1.0f); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    glActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_2D, texture1); 

    glActiveTexture(GL_TEXTURE1); 
    glBindTexture(GL_TEXTURE_2D, texture2); 

    pipeline.use(); 
    glBindVertexArray(vao); 
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); 

    SDL_GL_SwapWindow(this->sdlWindow); 

    this->counter.stop(); 
    this->deltaTime = this->counter.getDelta(); 
} 

    this->quit(); 

La question est plus facile à observer lorsque passant 0.5 comme paramètre à la fonction mix() dans le fragment shader. Lorsque j'utilise 0.0 ou 1.0 je reçois (comme prévu) une seule des textures.

Répondre

3

Le problème peut provenir de la texture elle-même. Si vous sonder la texture semi-transparente au pixel qui a été annulé par alpha près de la frontière, quelles sont les valeurs RVB? Certains éditeurs (Photoshop profondément) remplissent la zone transparente avec la couleur blanche (ou avec la couleur par défaut), ce qui peut provoquer ces frontières lors de la fusion. L'anti-polissage ou l'interpolation provoquerait le glissement du blanc dans la zone visible.

Je ne m'occupais pas de ce problème du point de vue du développeur de logiciels, mais l'avais été plus d'une fois en tant que créateur de contenu (c'est le fléau d'un novice dans SecondLife, par exemple).

+1

Merci beaucoup! C'était la solution, j'ai ouvert ma texture transparente dans GIMP et je l'ai exporté, en veillant à ne pas cocher "Enregistrer la couleur de fond", après cela, la texture s'est mélangée comme il se doit! – shmoo6000