ID:2546058
 
Applies to:DM Language
Status: Open

Issue hasn't been assigned a status value.
I've been experimenting with the new masking filters and plane masters. Something that became pretty apparent is that planes and plane masters seem to be the only reasonable way to apply filters to the scene as a whole vs individual atoms. On top of that, some very neat effects can be achieved via render_target on plane masters especially when it comes to non-rendering slates.

However, atoms can only exist on one plane at a time. A work around for this is to create a second dummy atom that uses the first as a render target but on the needed plane, then add the second one to the first's vis_contents. This is less than ideal as it means literally double the amount of atoms being created per atom that needs this technique, more if you wanted to render to more planes. Some trickery with caching is being used to work around the worst case scenario, but it's less than ideal.

Some kind of native way of (visually) rendering an atom multiple times to multiple planes would be incredibly useful for the needed effects and could allow some pretty interesting effects to be achieved.
Because this is already served with render_target and render_source, I'm not sure there's a use case compelling enough for this. The idea of providing a "secondary plane list" for atoms would be kind of nightmarish on the backend, so there needs to be a lot more justification. To be honest I'm not sure how possible it would be to implement the idea at all.

Can you describe the use case you have in mind in more detail? Maybe one of us is missing something that might point to a better implementation.
Alright, here's what I'm doing:

Three planes all with plane masters managing them:
1. Lighting Plane: BLEND_MULTIPLY plane with light objects
2. Emissive Plane: Non-rendering slate with objects to mask out lighting
3. Emissive Blocker Plane: Non-rendering slate with objects to mask out emissive

The lighting plane has an alpha mask filter with MASK_INVERSE on it with the render target set to the emissive plane, and the emissive plane has an alpha mask filter with MASK_INVERSE on it with the render target set to the blocking plane.

Objects for the emissive plane are given simple mask textures, which are added via vis_contents to needed standard objects. This allows you to add glowing emissive masks to objects that mask out lighting.

Without the blocker plane the issue is that these overlays will now *always* mask lighting whether or not they're blocked, resulting in this problem:
https://file.house/PgEG.png

The solution I came up with for this was the blocker plane, which masks the emissive plane. For simple objects that don't change much, a static icon overlay is added via vis_contents that's on the blocker plane.
For more complicated of things that change their outline and general shape a lot (ie, mobs with clothes), an object is created that is added to vis_contents that render_target copies the parent object on to the blocker plane.

End result of all this mess is this:
https://file.house/EDh6.png
accurate emissive masks with (mostly) accurate blocking of them as well.

code here: https://github.com/tgstation/tgstation/pull/49454

The intended idea behind multiple planes was that instead of the whole nonsense with copying the appearance onto a different plane with vis_contents and render targets and the like, something could just be placed on the emissive blocker plane as well as whatever its standard plane is.

If you're wondering why the blocking objects aren't just put on a full rendering plane to be used as a mask, the issue is that that would require changing the entire way depth sorting is currently handled to planes. And then introduces some more complexity because currently we use a couple of tricks with planes to fake things like ambient occlusion as well as blur the whole (game world) screen.

If you have an idea of how to execute this better with current available tools, I'm all ears.

ADDENDUM:
I wrote this whole post, and thinking about it more I thought of a better way of doing this with a different feature: being able to choose other channels besides alpha as the mask channel on the alpha mask filter.

Would you prefer I edit this post or make a new thread for that?