Fusee icon indicating copy to clipboard operation
Fusee copied to clipboard

Transparency in complex scenes

Open RedImp1470 opened this issue 5 years ago • 3 comments

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:

  1. Transparent parts have the color of the Clear Color

image

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

image

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:

  1. Ground
  2. Tendrils
  3. Pillar

Expected result, where the order of the meshes in the scene graph coincidentally matched the correct drawing order:

image

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.

image

RedImp1470 avatar Mar 27 '20 13:03 RedImp1470

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

griestopf avatar Mar 27 '20 13:03 griestopf

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.

RedImp1470 avatar Mar 27 '20 14:03 RedImp1470

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:

  1. 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)
  2. Sort renderable data and add commands via Action (Command Pattern). Sorting can be done via one key or with multiple keys by type.
  3. 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

CoffeeParser avatar Apr 24 '20 10:04 CoffeeParser