keijiro / KlakSpout

Spout plugin for Unity
The Unlicense
651 stars 97 forks source link

Spout sender is not recognized by some Spout receivers #82

Open sgsrules opened 2 years ago

sgsrules commented 2 years ago

The spout sender works perfectly when using the Spout demo receiver as well as a receiver made using KlakSpout. Some apps do not seem to recognize it at all though. I haven't been able to get it to work with either GrandVJ or VirtualDJ. I'm able to send spout to both of these apps using other applications so it's not an issue with the apps.

I suspect that the issue is the pixel format being used. Spout recommends using BGRA32 for better compatibility but this format is not available in Unity so we have to use RGBA32 instead. It's possible that these apps are simply ignoring any senders that aren't using BGRA32. If this is the case I think it would be feasible to have the spout sender use BGRA32 and then have the spout shader in Unity swizzle the rgba components to bgra.

sgsrules commented 2 years ago

I fixed the issue. As i suspected it was indeed an issue with the pixel format. For whatever reason some spout apps do not support RGBA32, but they all seem to support BGRA32. Fixing it was fairly straight forward.

plugin.cpp line 58 desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;

You also have to change the pixel format used in unity because CopyResource won't let you use textures with different formats. For whatever reason unity won't let you select B8G8R8A8_UNORM as a pixel format using the GUI so you have to do it via script. So any render textures that are created need to be changed as well.

SpoutSender.cs line 44 _buffer = new RenderTexture(width, height, 0,GraphicsFormat.B8G8R8A8_UNorm); and line 102 if using camera capture var temp = RenderTexture.GetTemporary(Screen.width, Screen.height, 0,GraphicsFormat.B8G8R8A8_UNorm);

Additionally instead of hard coding the pixel format in the plugin you could simply pass in the desired format during initialization or you could pass in the source texture then use _texture->GetDesc; to duplicate it's properties and then change whatever flags you need.