How can I properly use a RenderTexture generated from a Compute Shader as the background of a VisualElement?

I am trying to use a RenderTexture synthesized by a Compute Shader as the background image of a VisualElement but it is not working.

The Compute Shader I’m using is Unity’s default Compute Shader (right click > Create > Shader > Compute Shader).

My VisualElement is defined as this:

<engine:VisualElement name="testComputeShaderGroup" style="flex-grow: 1;">
    <engine:VisualElement name="testComputeShaderCanvas" style="width: 256px; height: 256px; border-left-color: rgb(255, 255, 255); border-right-color: rgb(255, 255, 255); border-top-color: rgb(255, 255, 255); border-bottom-color: rgb(255, 255, 255); border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; align-self: center; margin-top: 5px; margin-right: 5px; margin-bottom: 5px; margin-left: 5px; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px;" />
    <engine:Label text="ComputeShader canvas" style="color: rgb(255, 255, 255); -unity-text-align: upper-center;" />
</engine:VisualElement>

The code to create the RenderTexture, run the ComputeShader, and set the VisualElement backgroundImage is this:

RenderTexture renderTexture = new(256, 256, 24);
renderTexture.enableRandomWrite = true;
renderTexture.Create();

ComputeShader computeShader = AssetDatabase.LoadAssetAtPath<ComputeShader>("Assets/Shaders/Compute/MyTestComputeShader.compute");
computeShader.SetTexture(0, "Result", renderTexture);
computeShader.Dispatch(0, renderTexture.width / 8, renderTexture.height / 8, 1);

uIDocument.rootVisualElement.Q("testComputeShaderCanvas").style.backgroundImage = Background.FromRenderTexture(renderTexture);

I’m positive the RenderTexture content is correct and is properly assigned as the backgroundImage as shown by the UI Toolkit Debugger in runtime:

Unfortunately, the RenderTexture is not shown in Runtime, the VisualElement does not show the RenderTexture as its background.

I tried marking the VisualElement dirty to force a repaint but that didn’t help:

uIDocument.rootVisualElement.Q("testComputeShaderCanvas").MarkDirtyRepaint();

Does anyone knows what am I missing to be able to use the RenderTexture as the VisualElement’s backgroundImage?

Thx in advance for any reply or suggestion :slight_smile:

This is how the UI renders in runtime … the VisualElement does not show the RenderTexture as its background:

I found my-ish error. The error was that the compute shader code was setting the alpha channel of the RenderTexture to 0 making it transparent. I just had to change the shader code example to set the alpha channel to 1 and now it renders opaque and I can see the RenderTexture as the background of VisualElements. For example:

Here is the fixed code in case someone else stumbles with this too:

// Each #kernel tells which function to compile; you can have many kernels
#pragma kernel CSMain

// Create a RenderTexture with enableRandomWrite flag and set it
// with cs.SetTexture
RWTexture2D<float4> Result;

[numthreads(8,8,1)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
    // TODO: insert actual code here!

    //Result[id.xy] = float4(id.x & id.y, (id.x & 15)/15.0, (id.y & 15)/15.0, 0.0); // Original code, makes the pixel transparent
    Result[id.xy] = float4(id.x & id.y, (id.x & 15) / 15.0, (id.y & 15) / 15.0, 1.0); // Modified code, makes the pixel opaque
}