Transparency in complex scenes
See #257
The following refers to the Deferred Example. After I did some alteration in the lighting calculation we can render transparent textures, but....
When rendering the scene forward, we can see two kinds of issues with meshes that have a partially transparent albedo texture:
- Transparent parts have the color of the Clear Color

- Transparent parts are too transparent - for example we can see through the pillar in the picture below

When debugging the draw calls in RenderDoc, we can see that meshes like the one in picture 1 are drawn before any other meshes behind them. Debugging the example in the second picture reveals the following draw order:
- Ground
- Tendrils
- Pillar
Expected result, where the order of the meshes in the scene graph coincidentally matched the correct drawing order:

Therefore I think we should implement a way to sort transparent meshes before we render them to avoid this behavior.
With Deferred Rendering comes an additional issue where the lighting is not applied correctly for the transparent parts.

... a well known issue in 3D rendering. Transparency requires some kind of sorting. There are varying levels of complexity. Simpler approaches have more cases where transparency remains incorrect. More complex approaches have less incorrect behavior, but require more calculation.
🡅 Simple
- Render non-transparent objects first, then objects with (partial) transparency
- Render non-transparent objects first, then sort objects with (partial) transparency along camera-Z (e.g. using their bounding box center)
- Partition (semi)transparent objects spatially and fix intersections before sorting
🡇 Complex
Personally I'd try a BSP solution (becaus we may be able to also implement occlusion culling with this at the same time). In any case I think this will require some conceptional work. E. g. on how to not destroy the scene graph for the user and manage/share states.
This might help. I've implemented a general purpose Renderqueue based on this approach last year.
http://realtimecollisiondetection.net/blog/?p=86
The approach is called replay queue and works very well even for complex scenes with multi Pass shading, renderlayers and post processing.
Steps:
- Traverse scene and collect renderable data to a flat list. Renderable data is used as input for rendercontext commands (buffer handles, shader handles, input layout handles, etc)
- Sort renderable data and add commands via Action (Command Pattern). Sorting can be done via one key or with multiple keys by type.
- Run commands in loop on rendercontext
Tips: Avoid linq or fat object allocation in tight loops because triggers GC and slows down the rendering.
Exploit cache efficiency as much as possible: https://github.com/dbartolini/data-oriented-design