2017-08-17 31 views
5

Tôi đang cố gắng sử dụng OpenGL (C++) để hiển thị hai họa tiết lên hình chữ nhật. Tôi đang gặp rắc rối khi pha trộn cả hai.Kết hợp OpenGL tạo viền trắng xung quanh họa tiết

Hình ảnh đầu tiên xuất phát từ tệp .jpg (https://learnopengl.com/img/textures/container.jpg). Hình ảnh này không có kênh alpha.

Hình ảnh thứ hai xuất phát từ tệp .png (https://learnopengl.com/img/textures/awesomeface.png) và không có kênh alpha.

Vấn đề là khi tôi cố gắng pha trộn hai hình ảnh, nó tạo ra một đường viền màu trắng xung quanh hình ảnh trong suốt.

Tôi đã thử một vài chế độ hòa trộn khác nhau (theo khuyến cáo của OP trong câu hỏi này: Alpha blending with multiple textures leaves colored border) nhưng không có cách nào trong số chúng có vẻ hoạt động.

fragment shader của tôi trông như thế này:

#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); 
} 

Tôi có kiểm tra độ sâu cho phép (dường như không có bất kỳ tác) và tôi đang sử dụng đoạn mã sau cho việc thiết lập hòa trộn của tôi:

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

Đây là chính vòng lặp làm cho tôi:

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(); 

vấn đề này có thể dễ dàng quan sát thấy khi hầu hết chuyển 0,5 thành tham số cho hàm mix() trong trình đổ bóng phân đoạn. Khi sử dụng 0.0 hoặc 1.0 tôi nhận được (như mong đợi) chỉ có một trong các kết cấu.

Trả lời

3

Sự cố có thể xảy ra với kết cấu. nếu bạn thăm dò kết cấu bán trong suốt tại điểm ảnh bị hủy bởi alpha gần biên giới, giá trị RGB là gì? Một số biên tập viên (Photoshop sâu sắc) điền vào các khu vực trong suốt với màu trắng (hoặc với màu mặc định), mà có thể gây ra những biên giới trong quá trình pha trộn.

Antialising or interpolation sẽ khiến cho màu trắng chuyển sang vùng hiển thị.

Tôi không giải quyết vấn đề này từ quan điểm của nhà phát triển phần mềm, nhưng đã được nhiều người làm người sáng tạo nội dung hơn một lần (ví dụ như tai họa của người mới trong SecondLife).

+1

Cảm ơn bạn rất nhiều! Đây là giải pháp, tôi mở kết cấu trong suốt của mình lên trong GIMP và xuất nó, đảm bảo không đánh dấu vào "Lưu màu nền", sau đó, kết cấu được pha trộn như nó cần! – shmoo6000

Các vấn đề liên quan