bevyengine / bevy

A refreshingly simple data-driven game engine built in Rust
https://bevyengine.org
Apache License 2.0
36.1k stars 3.56k forks source link

Multi-pass materials #12208

Open viridia opened 8 months ago

viridia commented 8 months ago

What problem does this solve or what need does it fill?

Certain visual effects, such as cartoon outlines, require that a mesh be rendered twice: once for the inner part and once for the outline. There are various ways of implementing outlines, but a popular one is to inflate the object along the normals, and then draw the back-facing polygons in black.

What solution would you like?

A way to define a material that has multiple passes, with each pass rendered using a specified shader. Typically this would be a standard material shader for the inner part, and a custom shader for the outline.

Ideally, each pass should support Bevy's extended shaders.

What alternative(s) have you considered?

The workaround is to clone the object, however this is less than optimal.

viridia commented 7 months ago

Based on the discussion in the Discord, it seems that this feature would be hard to implement. Apparently there is an assumed 1:1 relationship between entities and draw calls, and multi-pass materials would break this assumption.

viridia commented 7 months ago

Well, I spoke too soon: turns out there is a way to do this today, but it's an undocumented quirk of the way the Bevy extractor works. If you insert two materials, of different types, into an entity it will render both of them.

However, because this is an undocumented feature, it might break in the future. So the task, then, is to write an example that uses this feature, one that will break if the feature gets removed.