Search Unity

Non kernel functions in compute shaders

Discussion in 'Shaders' started by Hicksosaurus, Jan 12, 2022.

  1. Hicksosaurus

    Hicksosaurus

    Joined:
    Apr 12, 2020
    Posts:
    4
    Hello,
    im currently starting with compute shaders and encountered following problem.

    As the following code is not working, how to use functions that dont have a
    #pragma kernel
    inside a shader?

    When adding the Add part directly to the ParticleUpdate function it does work.

    (This is dummy code to show my problem)

    Code (csharp):
    1.  
    2. #pragma kernel ParticleUpdate
    3.  
    4. struct Particle {
    5. float3 color;
    6. float3 position;
    7. }
    8.  
    9. RWStructuredBuffer<Particle> _particles;
    10.  
    11. float Add(float a, float b) {
    12. return a + b;
    13. }
    14.  
    15. [numthreads(1024,1,1)]
    16. void ParticleUpdate (uint3 id : SV_DispatchThreadID) {
    17. _particles[id.x].color.x = Add(_particles[id.x].color.x, 1);
    18. }
    Edit: changed x to b in Add
     
    Last edited: Jan 13, 2022
  2. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,025
    there's no x in there :)

    What doesn't work exactly?
     
  3. Hicksosaurus

    Hicksosaurus

    Joined:
    Apr 12, 2020
    Posts:
    4
    Oh thats a typo from reducing the function to a more readable form. sry
    x has to be b.

    Whats not working is the function call with Add. The shader does not execute with it written like that, but if I do the same addition in ParticleUpdate directly it does execute.

    Edit: Oh wow. I fixed my problem when converting it into the here posted code. So this does now work.
     
    Last edited: Jan 13, 2022
  4. Hicksosaurus

    Hicksosaurus

    Joined:
    Apr 12, 2020
    Posts:
    4
    What i still find confusing is when i change my code to

    Code (CSharp):
    1.  
    2. #pragma kernel ParticleUpdate
    3.  
    4. struct Particle {
    5.     float3 position;
    6.     float3 velocity;
    7.     };
    8.  
    9. RWStructuredBuffer<Particle> _particles;
    10. uniform float _deltaTime;
    11.  
    12. void Move(Particle particle) {
    13.     particle.position += float3(1, 0, 0) * _deltaTime;
    14. }
    15.  
    16. [numthreads(1024,1,1)]
    17. void ParticleUpdate (uint3 id : SV_DispatchThreadID)
    18. {
    19.     Move(_particles[id.x]);
    20. }
    nothing happens.
     
  5. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,025
    When you call it like that, you don't assign it back to the data in _particles, so if you change it to something like
    Particle Move(Particle particle)
    and update the surroundings accordingly, it will work.
     
    Hicksosaurus likes this.
  6. Hicksosaurus

    Hicksosaurus

    Joined:
    Apr 12, 2020
    Posts:
    4
    Oh, I see. I assumed that the parameters are passed by reference instead of value.
    Thanks for helping me out.
     
  7. Neto_Kokku

    Neto_Kokku

    Joined:
    Feb 15, 2018
    Posts:
    1,751
    You can add
    inout
    before a parameter to pass it by reference.
     
    Hicksosaurus likes this.