#How to pass an array of RenderTextures to a compute shader?

1 messages · Page 1 of 1 (latest)

wraith stone
#

Question like in the title. For context, the idea is that I want to generate SDFs for multiple objects on the Unity side and pass them to a compute shader in order to use them for particle collision handling.

tall coral
#

Should be able to bind a texture 2d array with SetTexture

wraith stone
tall coral
#

Well, then you can only pass them one by one.

#

The only way I know that might work is using bindless resources/textures, but I'm not sure if that's possible in a compute shader and unity.

#

How big is the array?

wraith stone
tall coral
#

But like, is there no maximum? And what are you gonna do with all the SDFs in one shader dispatch? Freeze(crash) your GPU? 😅

wraith stone
#

I don't intend for it to interact with too many objects (probably less than 10)

#

I just didn't think that having a limit would be necessary

tall coral
wraith stone
#

That's definitely less than ideal, but I guess I could work with that

tall coral
#

For ideal solution you need dx12/vulkan and unity to support bindless, which it doesn't it seems.

#

At least not yet

wraith stone
tall coral
#

A fixed array should be expanded into individual srvs/texture3d properties with some postfix, like _0, _1, etc by the compiler. If you know the pattern you can loop the textures in C# and generate the names dynamically.

wraith stone
tall coral
wraith stone
wraith stone
# tall coral Share the code

Here it is. Keep in mind that I'm still very much new to writing compute shaders (or shaders in general) so this file might not be too pretty (especially that there are some things that I tried to implement but are not used because I couldn't make them work correctly)

tall coral
#

For the future, share !code properly:

pliant marshBOT
tall coral
#
    for (uint i = 0; i < numOfInteractables; i++)
    {
        float3 localPos = particles[calcId].position - SDFPositions[i];
        if(length(localPos) < 1)
        {
            float3 pos = float3(0.5, 0.5, 0.5);
            particles[calcId].position.y += _SDFTextures[i].SampleLevel(sampler_SDFTextures[i], pos, 0);
        }
    }

numOfInteractables needs to be a constant for the loop to unroll properly, since a non const variable value is not known at compile time. Replace it with a const representing the max numOfInteractables you expect and wrap the contents of the loop in a condition i < numOfInteractables. This should work I think.

wraith stone
tall coral
wraith stone
#

Ah, right

wraith stone
# tall coral ```c++ for (uint i = 0; i < numOfInteractables; i++) { float3 lo...

I rewrote the loop to look like this yet it still gives me the same result

for (uint i = 0; i < 10; i++)
{
    if (i < numOfInteractables)
    {
        float3 localPos = particles[calcId].position - SDFPositions[i];
        if (length(localPos) < 1)
        {
            float3 pos = float3(0.5, 0.5, 0.5);
            particles[calcId].position.y += _SDFTextures[i].SampleLevel(sampler_SDFTextures[i], pos, 0);
        }
    }
}
tall coral
#

What result exactly? Can you share the error?

wraith stone
tall coral
#

Ah, it's a C# side error.

#

I guess you just have to set some dummy textures beyond the ones you're actually using.

wraith stone
#

Sounds like a hack instead of actual solution

tall coral
#

No, it's actually common to assign dummy resources to slots, even if they are not used. I guess unity tries to prevent a potential GPU crash with that error. The C# side doesn't know if the resource is used or not, but it knows that there is a slot and it's unassigned. If the shader tries to read from it, it would likely cause a GPU crash.

#

Though to be honest I don't remember unity throwing an error like that in the past.