Write linear colour + alpha to a RenderTarget

I have found a way to write linear space colour (not sRGB/ gamma space) + alpha to a RenderTarget, but I find it hard to believe this is the best way. I’ll write it here for anyone else who wants to, and would love if people could correct me in their answers.

1: For a linear colour, you need

RenderTarget1->RenderTargetFormat = ETextureRenderTargetFormat::RTF_RGBA8_SRGB;

This seems counterintuitive: surely, it should be RTF_RGBA8? No, after graphing linear values from 0 to 1, you can see a clear gamma curve with RTF_RGBA8, and a straight line with RTF_RGBA8_SRGB.

2: For writing to the alpha of the RenderTarget, the following things have to be in place in the material:

a) use a Surface material, not User Interface. Unlit shading model of course.

b) use a Masked Blend mode

c) the Opacity Mask Clip Value should be 0

d) Used with Editor Compositing should be ticked.

To preview the “correct” linear colour in a UI, so that a colour picker will tell you exactly what you put in, you can use the “gamma 1” console command. This has the effect of changing all the UI’s colours. Change back with “gamma 2.2”

It also seems that the DrawMaterialToRenderTarget function clears the render target before drawing when this is all set up, so you can’t have trails from previously drawn bits of the render target. I would love to know it is possible to not clear it, and get trails.

1 Like

I found a different way to set up the shader, just use a User Interface Material with a Masked blend mode and Opacity Mask Clip Value of 0.

Regarding trails, one thing you can do is add a discard; to a custom node, and it will actually discard the pixel showing the previous pixel. So the DrawMaterialToRenderTarget function is not clearing the render target before drawing. However I would like to be able to use the alpha channel for trails, not just a 0 or 1 with discard.

Necroing here, but found a possible solution. Figured I’d post it here since I struggled with it myself and came across this post.

First of all: You can use UI Material Domain, you would just have to check Used with Editor Compositing before in the Surface Material Domain. The checkbox value gets saved even if you change the Domain to UI later. You already said you could make it happen with UI but I wanted to clarify the perequisites.
Rest of the settings still apply. The sRGB mode lies in the way Unreal Engine handles Materials. Materials are always(?) outputted in sRGB so if you store it linearly, you get the curve coded into the texture. If you store it with sRGB settings, the values are stored in “sRGB encoded” so back to linear fashion.
If you don’t need alpha channel, you can use Opaque Blend Mode. If you want alpha channel, Masked and Clip Value 0 is the way.

Back to the topic:
You can use a simple Texture Sample to sample from the Render Target you create (you can insert Render Targets into Texture Samples). That way, you can use simple Lerp between the old – sampled – Render Target state and the new one. That Lerp can even be channel specific so you have every freedom needed. You have another texture sample in the shader of course but it’s the only way I have come across in my time fiddling with those beasts.

Another addendum: you don’t need to use “discard”, you can simply output a negative value to the opacity mask and the pixel still gets discarded.