D3D12 Alpha blending not working both ways

Started by
4 comments, last by LorenzoGatti 5 days, 15 hours ago

Hi, my alpha blending isn't working in the way I was hoping.

I have a cube and plane with a transparent texture. The cube goes through the plane. When looking top-down, the cube does not show through the transparency of the plane, but the plane does show through the transparency of the cube.

How could I fix something like this?

I am using D3D12. My pixel shader is very simple; it just returns the texture color. I am using the CommonStates::AlphaBlend for my blend description:

https://github.com/microsoft/DirectXTK12/wiki/CommonStates#blend-states

The plane is shown in the background through the cube's branches, but the other half of the cube is not shown under the plane.
Advertisement

The problem is one of:

  • You have depth writing enabled. For actual transparent rendering you should disable depth writing and render surfaces in back-to-front order.
  • For the special case of foliage, you should be using a “cutout” shader, not alpha blending. This would involve using the equivalent of GLSL “discard” to not draw pixels where alpha < 0.5 (anything not discarded should be 100% opaque). With a cutout shader, you can still write to depth buffer and don't have to sort draw calls by depth. This is how most games render foliage.

I want to focus on the first bullet. How am I supposed to stay organized when I have to organize all of my vertices individually?? I have my renderer organized between objects; each object has a mesh with its own vertex buffer. How could I render back-to-front without completely dismantling the system I already have? How do other general-purpose renderers pull it off?

coulomb said:
How do other general-purpose renderers pull it off?

Usually you have some center per model, e.g. from its bounding box. They can sort all object distances from their center to the camera, and render objects in that order.
It can fail if the objects intersect each other, but usually it's good enough.

If all your objects are static, you could build a BSP. This splits intersecting polys to deal with intersections, you can do traversal instead sorting, and it's robust.

What do you want to compromise on? Quality of transparency or cost of sorting?

In the first case, a “cutout” shader of the type Aressera describes sorts fragments perfectly by depth, without any reorganization of your rendering, but can only render the closest fragment fully opaque.

In the second case, alpha blending requires accumulating fragments back to front and you need to sort, and usually also split, your objects on the fly according to the viewpoint; the most appropriate spatial indexing structure and/or the most acceptable glitches and approximations depend on your geometry.

Omae Wa Mou Shindeiru

Advertisement