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.
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