Search Unity

  1. If you have experience with import & exporting custom (.unitypackage) packages, please help complete a survey (open until May 15, 2024).
    Dismiss Notice
  2. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice

Black RenderTextures when calling 2 the same ComputeShader in 2 Update() loops

Discussion in 'Shaders' started by bdcollins18, Sep 11, 2021.

  1. bdcollins18

    bdcollins18

    Joined:
    Sep 11, 2021
    Posts:
    2
    I'm encountering a problem when calling the same ComputeShader Dispatch() on Update() for two (or more) GameObjects.

    I've written the following code to illustrate the issue:
    Code (CSharp):
    1. // Test.cs
    2.  
    3. using System.Collections;
    4. using System.Collections.Generic;
    5. using UnityEngine;
    6.  
    7. public class Test : MonoBehaviour
    8. {
    9.     public ComputeShader _computeShader;
    10.     public CustomRenderTexture _customRenderTexture;
    11.     public Material _material;
    12.     public Renderer _renderer;
    13.  
    14.     void Start()
    15.     {
    16.         _customRenderTexture = new CustomRenderTexture(256, 256);
    17.         _customRenderTexture.enableRandomWrite = true;
    18.         _customRenderTexture.Create();
    19.  
    20.         _material = new Material(Shader.Find("Standard"));
    21.         _material.mainTexture = _customRenderTexture;
    22.  
    23.         _renderer = gameObject.GetComponent<Renderer>();
    24.         _renderer.material = _material;
    25.  
    26.         _computeShader.SetTexture(0, "Result", _customRenderTexture);
    27.         _computeShader.SetFloats("width", _customRenderTexture.width);
    28.         _computeShader.SetFloats("height", _customRenderTexture.height);
    29.     }
    30.  
    31.     void Update() {
    32.         _computeShader.SetFloats("t", Time.time % 2f);
    33.         _computeShader.Dispatch(0, _customRenderTexture.width / 8, _customRenderTexture.height / 8, 1);
    34.     }
    35. }
    Code (CSharp):
    1. // Test.compute
    2.  
    3. #pragma kernel CSMain
    4.  
    5. float width, height;
    6. float t;
    7. RWTexture2D<float4> Result;
    8.  
    9. [numthreads(8,8,1)]
    10. void CSMain (uint3 id : SV_DispatchThreadID)
    11. {
    12.     Result[id.xy] = float4(t * id.x / width, t * id.y / height, 0.0, 0.0);
    13. }
    Putting Test.cs/Test.compute on two planes has the following result:


    The second plane receives only a black texture.

    However, If I duplicate the Test.compute asset, and assign the new asset to Test.cs on the 2nd plane, I get this result:


    Now both planes behave as expected.

    Irregardless of if calling Dispatch() in Update() is bad practice or not, what am I doing wrong here? Is there a different way I should be instantiating my ComputeShader objects in my Test.cs script rather than assigning them in the inspector via a public variable? I hope there isn't something painfully obvious that I'm missing.
     
  2. bdcollins18

    bdcollins18

    Joined:
    Sep 11, 2021
    Posts:
    2
    I've found that calling:
    Code (CSharp):
    1. _computeShader = ComputeShader.Instantiate(_computeShader)
    Is an effective fix. But, I would still like to know if this is the correct/best way to solve this issue.