#How to pass an array of RenderTextures to a compute shader?
1 messages · Page 1 of 1 (latest)
Should be able to bind a texture 2d array with SetTexture
SDFs are represented by a 3D texture though, so I can't really use the Texture2DArray type
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?
It doesn't have a predetermined size as it depends on the amount of objects in the scene that have specific script attached
But like, is there no maximum? And what are you gonna do with all the SDFs in one shader dispatch? Freeze(crash) your GPU? 😅
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
You might be able to have a fixed array of 3d textures, but you're limited to the max count and have to decide it at editing time.
That's definitely less than ideal, but I guess I could work with that
For ideal solution you need dx12/vulkan and unity to support bindless, which it doesn't it seems.
At least not yet
So, how would I go about passing those textures to a fixed size array of Texture3D? I don't think I could use SetTexture for that.
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.
Well, it kinda works but I've encountered an issue. When I try to loop it, I get an error that a texture is not set (even though the loop should not be touching that texture because I'm looping over values lower than the amount of textures passed to the shader)
Might be that the loop is unrolled into sampling the whole array. Try adding a condition before sampling inside I guess. Or disable unrolling the loop.
I tried that but for some reason it tried to somehow unroll over 500 iterations when I did that
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)
For the future, share !code properly:
📃 Large Code Blocks
Use links to services like:
https://paste.mod.gg/, https://hastebin.skyra.pw/, https://paste.ofcode.org/, https://paste.myst.rs/
📃 Inline Code
Surround code with three backquotes. Not quotation marks.
To format as C#, add cs to the first line:
```cs
// Your code here
```
Add a comment with a line number if there is an error message.
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.
The issue is that the value will be variable, so it cannot be constant
And that why I said "replace" and use the variable in an if statement instead.
Ah, right
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);
}
}
}
What result exactly? Can you share the error?
Compute shader (SPH): Property (_SDFTextures[2]) at kernel index (9) is not set
UnityEngine.ComputeShader:Dispatch (int,int,int,int)
SPHOnComputeShader:FixedUpdate () (at Assets/Script/SPHOnComputeShader.cs:250)
Ah, it's a C# side error.
I guess you just have to set some dummy textures beyond the ones you're actually using.
Sounds like a hack instead of actual solution
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.