<p>It depends on the order of rendering. When first rendering the object which is far away and then rendering the closer object, the transparency will work. Otherwise when first rendering the close object, you depthbuffer will block the object which is behind.
There are different ways to manage this issue:</p>
<p>1:First render all opaque geometries. and then render the transparent.</p>
<p>This gives you NOT the correct output, because other transparent objects which are behind transparent objects will cause the same problem you described. But opaque objects will always be visible.</p>
<p>2:Use other rendertechniques like Order independent transparencies (OIT)</p>
<p>Here you create a list of fragments (pixels) for each pixel on your screen. The list of fragments must hold the depth and color value. when all geometry is rendered, you can iterate through each list and sort the fragments by the depth value and render them again from back to front. This will give you a very good final image.</p>
<p>This technique can be improved when first enable depth writing, depth testing and rendering the opaque objects.
Disable depth writing, enable depth testing. And then render the transparent ones. This will shrink your list size.</p>

CC BY-SA 4.0
2021-09-23T06:32:50.090Z
In case using OIT: you can store the list in a Shader Storage Buffer Object (SSBO) and use atomicAdd(), atomicCompSwap() and other atomic functions within GLSL (shader) to avoid writing to the same memory location from different GPU "Threads" .
Thomas
CC BY-SA 4.0
2021-09-23T10:06:31.410Z
I'll implement this and hopefully it'll solve the problem. (Unfortunately I do not have enough reputation to cast a vote for you). Thank you for your answers.
Paweł Pomierski
CC BY-SA 4.0
2021-09-24T11:39:31.273Z
@PawełPomierski you are welcome =)
Thomas
CC BY-SA 4.0
2021-09-24T11:40:39.160Z
@PawełPomierski have in mind, that you can also render your blocks from back to front... if your datastructure (chunks) allow this
Thomas
CC BY-SA 4.0
2021-09-22T09:21:57.950Z
2021-09-22T09:21:57.950Z
Thomas
<p>I can't actually spot the problem from your pictures, but the problem you describe is a very common one for new developers trying to implement transparency, so I'll assume it's there.</p>
<p><strong>The problem:</strong></p>
<p>Let's consider what happens to a single pixel. In boring old opaque rendering, we expect the pixel to have the frontmost triangle at that pixel (closest to the camera, lowest Z value). This can be done with a depth buffer: the GPU stores the Z coordinate of the frontmost triangle that touches the pixel so far, and overwrites the pixel when drawing a triangle in front of that, and doesn't overwrite it when drawing a triangle behind that. Therefore the final result has the colour from the frontmost triangle.</p>
<p>However this simple algorithm <em>only works</em> for fully opaque triangles. With a translucent triangle, instead of just overwriting the colour of the pixel, the GPU combines it with the colour already in the colour buffer. If some of the triangles are skipped because of the depth buffer algorithm, the final colour is wrong. The only case when it's right is when the triangles are drawn in back-to-front order. And <em>if you use the typical alpha blending algorithm for translucency</em>, then you can't just solve it by turning off the depth buffer, because the colour is calculated differently depending on which order the triangles are rendered in, and it's only correct when they are drawn in back-to-front order (when you get the correct result whether the depth buffer is on or off).</p>
<p><strong>The solution:</strong></p>
<p>If you only have fully opaque and fully transparent pixels, a <em>really easy solution</em> is to enable alpha test. Pixels with 0 alpha will be fully discarded and won't update the depth buffer. Pixels with 1.0 alpha will act as opaque.</p>
<pre><code>glEnable(GL_ALPHA_TEST); // &lt;- literally that simple
</code></pre>
<p>If you have partially translucent pixels, then you have two options: either <em>actually render front-to-back</em> or implement one of the schemes of <em>order-independent transparency</em>. All of these options have significant tradeoffs. Fortunately, you appear to have only fully transparent pixels, so it is not necessary to delve into either.</p>

CC BY-SA 4.0
2022-04-11T10:15:04.527Z
2022-04-11T10:15:04.527Z
Criticize SE actions means ban
<p>I'm trying to implement voxel world using OpenGL (Core 3.3). I've come across a problem with transparency. It looks like sometimes GPU decides to not render stuff that would be important. Can you help me diagnose the problem, please?
(I thought this problem can be related to sorting (I don't perform any extra sorting at the moment), but I've changed &quot;clear color&quot; to glClearColor(1.0f, 1.0f, 1.0f, 0.01f); and the &quot;gaps&quot; are still noticeable)</p>
<p><strong>EDIT:</strong> I've found a resource that claims that it is indeed  sorting problem and drawing background triangles at first should solve this issue. However every 'chunk' (16x16 blocks' column) is rendered as a separate batch with single draw call. Is there a way to preserve this batch rendering?</p>
<p>Here are some pictures:</p>
<p><a href="https://i.sstatic.net/QaKhT.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/QaKhT.png" alt="enter image description here" /></a>
<a href="https://i.sstatic.net/ahFb2.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/ahFb2.png" alt="enter image description here" /></a></p>
<p><a href="https://i.sstatic.net/JUwqg.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/JUwqg.png" alt="enter image description here" /></a>
<a href="https://i.sstatic.net/8nOV0.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/8nOV0.png" alt="enter image description here" /></a></p>
<p>The Ftagment Shader is very simple:</p>
<pre><code>#version 330 core
out vec4 FragColor;
in vec2 v_TexCoord;

uniform sampler2D u_Texture;

void main()
{
    vec4 texColor = texture(u_Texture, v_TexCoord);
    if(texColor.a &lt; 0.2)
        discard;
    FragColor = texColor;
}
</code></pre>
<p>Depth test and blending:</p>
<pre><code>void Renderer::clear() const {
    glClearColor(0.53f, 0.8f, 0.92f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

//Before render loop

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_DEPTH_TEST);
</code></pre>
<p>Do you have any idea how can I fix this problem?</p>

<opengl><3d><fragment-shader><transparency><z-buffer>
OpenGL transparency - object behind is not rendered
Paweł Pomierski
# OpenGL transparency - object behind is not rendered

(Asked by: username_0 on 2021-09-21)

I'm trying to implement voxel world using OpenGL (Core 3.3). I've come across a problem with transparency. It looks like sometimes GPU decides to not render stuff that would be important. Can you help me diagnose the problem, please?
(I thought this problem can be related to sorting (I don't perform any extra sorting at the moment), but I've changed "clear color" to glClearColor(1.0f, 1.0f, 1.0f, 0.01f); and the "gaps" are still noticeable)

**EDIT:** I've found a resource that claims that it is indeed sorting problem and drawing background triangles at first should solve this issue. However every 'chunk' (16x16 blocks' column) is rendered as a separate batch with single draw call. Is there a way to preserve this batch rendering?

Here are some pictures:

[![enter image description here](https://i.sstatic.net/QaKhT.png)](https://i.sstatic.net/QaKhT.png)
[![enter image description here](https://i.sstatic.net/ahFb2.png)](https://i.sstatic.net/ahFb2.png)

[![enter image description here](https://i.sstatic.net/JUwqg.png)](https://i.sstatic.net/JUwqg.png)
[![enter image description here](https://i.sstatic.net/8nOV0.png)](https://i.sstatic.net/8nOV0.png)

The Ftagment Shader is very simple:

```
#version 330 core
out vec4 FragColor;
in vec2 v_TexCoord;

uniform sampler2D u_Texture;

void main()
{
    vec4 texColor = texture(u_Texture, v_TexCoord);
    if(texColor.a < 0.2)
        discard;
    FragColor = texColor;
}

```

Depth test and blending:

```
void Renderer::clear() const {
    glClearColor(0.53f, 0.8f, 0.92f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

//Before render loop

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

```

Do you have any idea how can I fix this problem?

**Tags:** opengl, 3d, fragment-shader, transparency, z-buffer


---

## 2 answers

### Answer by username_1 on 2021-09-22. Score: 1

It depends on the order of rendering. When first rendering the object which is far away and then rendering the closer object, the transparency will work. Otherwise when first rendering the close object, you depthbuffer will block the object which is behind.
There are different ways to manage this issue:

1:First render all opaque geometries. and then render the transparent.

This gives you NOT the correct output, because other transparent objects which are behind transparent objects will cause the same problem you described. But opaque objects will always be visible.

2:Use other rendertechniques like Order independent transparencies (OIT)

Here you create a list of fragments (pixels) for each pixel on your screen. The list of fragments must hold the depth and color value. when all geometry is rendered, you can iterate through each list and sort the fragments by the depth value and render them again from back to front. This will give you a very good final image.

This technique can be improved when first enable depth writing, depth testing and rendering the opaque objects.
Disable depth writing, enable depth testing. And then render the transparent ones. This will shrink your list size.

> **Comments:**
> **username_1**: In case using OIT: you can store the list in a Shader Storage Buffer Object (SSBO) and use atomicAdd(), atomicCompSwap() and other atomic functions within GLSL (shader) to avoid writing to the same memory location from different GPU "Threads" .  
> **username_0**: I'll implement this and hopefully it'll solve the problem. (Unfortunately I do not have enough reputation to cast a vote for you). Thank you for your answers.  
> **username_1**: @username_0 you are welcome =)  
> **username_1**: @username_0 have in mind, that you can also render your blocks from back to front... if your datastructure (chunks) allow this  

---

### Answer by username_2 on 2022-04-11. Score: 0

I can't actually spot the problem from your pictures, but the problem you describe is a very common one for new developers trying to implement transparency, so I'll assume it's there.

**The problem:**

Let's consider what happens to a single pixel. In boring old opaque rendering, we expect the pixel to have the frontmost triangle at that pixel (closest to the camera, lowest Z value). This can be done with a depth buffer: the GPU stores the Z coordinate of the frontmost triangle that touches the pixel so far, and overwrites the pixel when drawing a triangle in front of that, and doesn't overwrite it when drawing a triangle behind that. Therefore the final result has the colour from the frontmost triangle.

However this simple algorithm *only works* for fully opaque triangles. With a translucent triangle, instead of just overwriting the colour of the pixel, the GPU combines it with the colour already in the colour buffer. If some of the triangles are skipped because of the depth buffer algorithm, the final colour is wrong. The only case when it's right is when the triangles are drawn in back-to-front order. And *if you use the typical alpha blending algorithm for translucency*, then you can't just solve it by turning off the depth buffer, because the colour is calculated differently depending on which order the triangles are rendered in, and it's only correct when they are drawn in back-to-front order (when you get the correct result whether the depth buffer is on or off).

**The solution:**

If you only have fully opaque and fully transparent pixels, a *really easy solution* is to enable alpha test. Pixels with 0 alpha will be fully discarded and won't update the depth buffer. Pixels with 1.0 alpha will act as opaque.

```
glEnable(GL_ALPHA_TEST); // <- literally that simple

```

If you have partially translucent pixels, then you have two options: either *actually render front-to-back* or implement one of the schemes of *order-independent transparency*. All of these options have significant tradeoffs. Fortunately, you appear to have only fully transparent pixels, so it is not necessary to delve into either.


---

