'How to sample each pixel in a TextureCube in compute shader in Unity?

Currently I want to do some calculations on each pixel in a Cubemap in Unity and output the new Cubemap. Since I can't write to TextureCube, I use a RWTexture2DArray. The problem is that I don't know how to convert the thread ID to TextureCube's sample direction vector. The compute shader looks like this:


SamplerState _PointClampSampler;

TextureCube<float4> Color;
RWTexture2DArray<float4> Result;

// Consider the resolution of Cubemap is 1024
// Dispatch the kernel:
// cmd.DispatchCompute(shader, kernelId, 1024 / 8, 1024 / 8, 1);

[numthreads(8, 8, 1)]
void DoCompute(uint3 id : SV_DispatchThreadID) {
    for(int i = 0; i < 6; i++) {
        // Convert thread ID to direction vector
        float3 dir = ?????;

        float4 color = Color.SampleLevel(_PointClampSampler, dir, 0);
        float4 newColor = DoSomething(color);

        Result[???] = newColor;
    }
}

And I've tried the following 3 methods:

  1. Convert Cubemap to a Texture2DArray and just sample each pixel in each face with thread ID. This works perfectly but at the cost of extra 6 Graphics.CopyTexture() calls.

  2. Before dispatching the kernel, creating a ray array which contains some pre-computed direction vectors. Each ray points from a sphere center to a surface pixel. However the step is fixed and hard to find an optimal value.

List<Vector3> GenerateDirections(int step) {
    var dirs = new List<Vector3>();

    steps = Mathf.FloorToInt(360f / step);

    x = Quaternion.Euler(Vector3.right * step);
    y = Quaternion.Euler(Vector3.up * step);
    z = Quaternion.Euler(Vector3.forward * step);

    var dir = Vector3.right;
    
    for (var x = 0; x < steps / 2; x++) {
        dir = z * dir;
        for (int y = 0; y < steps; y++) {
            dir = x * dir;
            dirs.Add(dir);
        }
    }

    return dirs;
}
  1. I found some code in this GitHub repo. I tried his code but the face order of the output Cubemap is incorrect. I don't understand what it actually does, though :(


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source