Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
234 views
in Technique[技术] by (71.8m points)

c++ - Cannot apply blending to cube located behind half-transparent textured surface

Following the tutorial from learnopengl.com about rendering half-transparent windows glasses using blending, I tried to apply that principle to my simple scene (where we can navigate the scene using the mouse) containing:

  • Cube: 6 faces, each having 2 triangles, constructed using two attributes (position and color) defined in its associated vertex shader and passed to its fragment shader.
  • Grass: 2D Surface (two triangles) to which a png texture was applied using a sampler2D uniform (the background of the png image is transparent).
  • Window: A half-transparent 2D surface based on the same shaders (vertex and fragment) as the grass above. Both textures were downloaded from learnopengl.com

The issue I'm facing is that when it comes to the Grass, I can see it through the Window but not the Cube!

screenshot

My code is structured as follows (I left the rendering of the window to the very last on purpose):

// enable depth test & blending
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA);

while (true):
  glClearColor(background.r, background.g, background.b, background.a);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  cube.draw();
  grass.draw();
  window.draw();

Edit: I'll share below the vertex and fragment shaders used to draw the two textured surfaces (grass and window):

#version 130

in vec2 position;
in vec2 texture_coord;
// opengl tranformation matrices
uniform mat4 model;      // object coord -> world coord
uniform mat4 view;       // world coord  -> camera coord
uniform mat4 projection; // camera coord -> ndc coord
out vec2 texture_coord_vert;

void main() {
  gl_Position = projection * view * model * vec4(position, 0.0, 1.0);
  texture_coord_vert = texture_coord;
}

#version 130
in vec2 texture_coord_vert;
uniform sampler2D texture2d;
out vec4 color_out;

void main() {
  vec4 color = texture(texture2d, texture_coord_vert);
  // manage transparency
  if (color.a == 0.0)
    discard;
  color_out = color;
}

And the ones used to render the colored cube:

#version 130

in vec3 position;
in vec3 color;
// opengl tranformation matrices
uniform mat4 model;      // object coord -> world coord
uniform mat4 view;       // world coord  -> camera coord
uniform mat4 projection; // camera coord -> ndc coord
out vec3 color_vert;

void main() {
  gl_Position = projection * view * model * vec4(position, 1.0);
  color_vert = color;
}
#version 130

in vec3 color_vert;
out vec4 color_out;

void main() {
  color_out = vec4(color_vert, 1.0);
}

P.S: My shader programs uses GLSL v1.30, because my internal GPU didn't seem to support later versions.

Regarding the piece of code that does the actual drawing, I basically have one instance of a Renderer class for each type of geometry (one shared by both textured surfaces, and one for the cube). This class manages the creation/binding/deletion of VAOs and binding/deletion of VBOs (creation of VBOs made outside the class so I can share vertexes with similar shapes). Its constructor takes as an argument the shader program and the vertex attributes. I'll try to show the relevant piece of code below

Renderer::Renderer(Program program, vector attributes) {
  vao.bind();
  vbo.bind();

  define_attributes(attributes);

  vao.unbind();
  vbo.unbind();
}

Renderer::draw(Uniforms uniforms) {
  vao.bind();
  program.use();

  set_uniforms(unfiorms);
  glDrawArrays(GL_TRIANGLES, 0, n_vertexes);

  vao.unbind();
  program.unuse();
}
question from:https://stackoverflow.com/questions/65838909/cannot-apply-blending-to-cube-located-behind-half-transparent-textured-surface

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Your blend function function depends on the target's alpha channel (GL_ONE_MINUS_DST_ALPHA):

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA);
dest = src * src_alpha + dest * (1-dest_alpha) 

If the alpha channel of the cube is 0.0, the color of the cube is not mixed with the color of the window.

The traditional alpha blending function depends only on the source alpha channel:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
dest = src * src_alpha + dest * (1-src_alpha) 

See also glBlendFunc and Blending


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...