Quantcast
Channel: Questions in topic: "compute shader"
Viewing all articles
Browse latest Browse all 287

ComputeShader: Accessing array elements within a StructuredBuffer

$
0
0
I have been toying with ComputeShaders for a while now, and have been trying to use them to leverage the hair physics calculations I was doing in my game. The hair is based off a series of points that use springs to create hair. Each strand is a list of these points. I had success moving the physics code into a compute shader for one strand, and would be able to calculate 10,000 hair bodies at solid 60fps on one strand, but multiple strands would crash performance. So I need to instead run a threadgroup for each hair strand, and dispatch these hair strands x amount of times. So I make a structure of hair strands, fill it with a max-sized array of 'hair body' structs. I would then access the hair strand by the groupID, and the hair bodies by the thread index. Theoretically this should work, but I am not having these results. Due to limitations with StrucuredBuffer element sizes being max 2048 bytes, I can only store certain lengths of hair bodies per strand. When I try to change these values and read them from my C# script, they are null. I have provided a test scenario that should duplicate my problem. I have simplified this only to get the base functionality working, which is setting the indexes of the array within the hair strand. The code is below: ShaderTest.cs: public class ShaderTest : MonoBehaviour { public struct TestStruct1 { public int groupID; public int[] threadIDs; } public ComputeShader computeShader; private ComputeBuffer computeBuffer; private int kernelID; void Start() { var stopWatch = new System.Diagnostics.Stopwatch(); TestStruct1[] data = new TestStruct1[256]; for (int i = 0; i < 256; i++) { TestStruct1 s1 = data[i]; s1.threadIDs = new int[50]; } this.kernelID = computeShader.FindKernel("CSMain"); computeBuffer = new ComputeBuffer(256, sizeof(int) + (50 * sizeof(int))); computeBuffer.SetData(data); computeShader.SetBuffer(kernelID, "Buf", computeBuffer); stopWatch.Start(); computeShader.Dispatch(kernelID, 256, 1, 1); computeBuffer.GetData(data); stopWatch.Stop(); Debug.Log("Took: " + stopWatch.ElapsedMilliseconds + " milliseconds to compute"); foreach(TestStruct1 d in data) { Debug.Log(d.threadIDs[0]); // Crashes here } computeBuffer.Release(); } } ShaderTest.compute: #pragma kernel CSMain struct TestStruct1 { int groupID; int threadIDs[50]; }; RWStructuredBuffer Buf; [numthreads(64,1,1)] void CSMain(int3 threadID : SV_GroupThreadID, int3 groupID : SV_GroupID) { if (threadID.x <= 50) { Buf[groupID.x].threadIDs[threadID.x] = 7; } } All I am trying to do in the above code is properly index through the buffer and set each threadID to 7 for proof that this structure works. For whatever reason, it is not giving me the expected results that were so clear before. Any help would be greatly appreciated

Viewing all articles
Browse latest Browse all 287

Trending Articles