0
votes

Long story short, I have a shader which absolutely has to work with logical OR blending. I am bitpacking data in one shader, where pixels overlap, combining this data into an output RenderTexture, and then unpacking it in another shader.

This needs to be crossplatform. I want to support DX11/12 (where it works fine), OpenGL (standard, core, and ES), and ideally Vulkan and Metal.

Here's the thing.

Unity claims that it can only use logical OR blending in a specific subset of DX11. It actually seems to work fine on all versions of DX11.1+ and DX12. It does not, however, work on any other platform.

OpenGL lists support for logical OR blending in their spec. It seems that this should work with all versions of OpenGL above 2 (including ES, unless I missed something).

How, in Unity, can I have this shader crosscompile to GLSL, and enable this blend op? I assume it might be possible by P/Invoking the library for glEnable and related functions, but I'd like to know if there is a way to write on Cg shader and have this crosscompile properly. Metal/Vulkan isn't a dealbreaker, it would be nice to extend support, but I'm more than happy to settle for only supporting DX11+ and OpenGL 2+.

1
For mobile platforms, it's not supported on OpenGL ES 2.x onwards (it was in OpenGL ES 1.x but removed as it was so rarely used). - solidpixel
Per the Direct3D hardware feature levels, logical opts in the output merger (the thing that does alpha blending into a render target) is optional on FL 11.0 video cards, but is supported for FL 11.1, 12.0, and 12.1 hardware. Keep in mind that this is the video hardware which is distinct from the Direct3D API version. - Chuck Walbourn
Thank you both for the clarifications; ultimately I've decided to drop mobile support. I do have a workaround for OpenGL 3.0+/OpenGL core, plus Vulkan. - Daedalus

1 Answers

0
votes

So, ultimately what I wanted to do is impossible on most mobile systems. It was mostly a hope to expand my potential customer base, but I've decided that the extra complication isn't worth it, and I've dropped mobile support for now.

However, it is possible to get this setup working across DX11.1+, DX12, OpenGL 3.0+, OpenGL Core, and Vulkan. You need to create a native plugin for Unity, and bind all of your rendering resources manually. I couldn't get the P/Invoke approach working,because there's no exposed way to synchronise them with the rendering context. I did want to do this to remove Unity's mesh interop cost anyhow, so it's probably a good thing to be forced into. Anyhow, I wanted to post back here for anyone trying something similar in future and say that it seems the only way to do this is with a native plugin.