Search Unity

Resolved How to properly store all values to a compute buffer?

Discussion in 'Shaders' started by GodblessUnity, May 9, 2023.

  1. GodblessUnity

    GodblessUnity

    Joined:
    Sep 7, 2022
    Posts:
    2
    Hi,

    I have followed the three eyed raytracer guide to ray tracing with the aim to trace the propagation of the rays. I therefore want to store the data of each ray. I am new to shaders and therefore my knowledge is lacking.

    The problem I have is that I am unsure on how to store ALL my data into a RWStructuredBuffer. Should I use the SV_GroupIndex with the DispatchId somehow? The current solution is something I randomly found, it seems to work fine as I now can see the data of more rays than before (than by just using id.x or id.y), but I am unsure what I am actually doing here,
     uint index = id.x + id.y * 64;
    . How should one go about this problem? As far as I have seen there are no 2D arrays in HLSL and moreover arrays cannot be sent via compute buffer as it is not a blittable type?

    Edit: All I had to do was to multiply above with the amount the width specified in the dispatch call to get a correct result.

    Code (HLSL):
    1. [numthreads(64,1,1)]
    2. void CSMain(uint3 id : SV_DispatchThreadID, int id2 : SV_GroupIndex)
    3. {
    4.     _Pixel = id.xy;
    5.  
    6.     uint index = id.x + id.y * 64;
    7.  
    8.     // Get the dimensions of the RenderTexture
    9.     uint width, height;
    10.     Result.GetDimensions(width, height);
    11.  
    12.     // Transform pixel to [-1,1] range
    13.     float2 uv = float2((id.xy + _PixelOffset) / float2(width, height) * 2.0f - 1.0f);
    14.  
    15.     // Get a ray for the UVs
    16.     Ray ray = CreateCameraRay(uv);
    17.  
    18.     RayData rayData;
    19.     // Trace and shade the ray
    20.     float3 result = float3(0, 0, 0);
    21.     for (int i = 0; i < 8; i++)
    22.     {
    23.         RayHit hit = Trace(ray);
    24.         result += ray.energy * Shade(ray, hit);
    25.              
    26.         if (!any(ray.energy))
    27.             break;
    28.      
    29.         rayData.direction = ray.direction;
    30.         rayData.energy = ray.energy;
    31.         // we want total distance of one ray
    32.         rayData.origin = ray.origin;
    33.         rayData.distance += hit.distance;
    34.      }
    35.  
    36.     _Rays[index] = rayData;
    37.  
    38.     Result[id.xy] = float4(result, 1);
    39. }
    Code (CSharp):
    1.         // Set the target and dispatch the compute shader
    2.         RayTracingShader.SetTexture(0, "Result", _target);
    3.         int threadGroupsX = Mathf.CeilToInt(Screen.width / 64.0f);
    4.         int threadGroupsY = Mathf.CeilToInt(Screen.height ); /// 8.0f
    5.         RayTracingShader.Dispatch(0, threadGroupsX, threadGroupsY, 1);
    Thanks in advance!
     
    Last edited: May 9, 2023