Help with understanding how to use compute shaders with 3D textures.

Hi, I’m trying to generate a 3D texture and then display it using raymarching using a compute shader and a normal shader, however i’m having difficulty when moving the 3d texture to the gpu and to the render shader.

It seems that in my code at the moment, the compute shader is returning a 2D texture, giving me:
Error assigning 2D texture to 3D texture property ‘_texture’: Dimensions must match

Could i please have some help to figure out how to do this properly?

Compute shader:

#pragma kernel CSMain



RWTexture3D<float4> Result;
int arms;
float3 sro;
int width[8];
int px[8];
int py[8];

float lineDistance(float2 p, float2 lineStart, float2 lineEnd)
{

    float lineLength = distance(lineStart, lineEnd);
    float lx = lineEnd.x - lineStart.x;
    float ly = lineEnd.y - lineStart.y;
    float px = p.x - lineStart.x;
    float py = p.y - lineStart.y;

    float tI = (lx * px + ly * py) / pow(lineLength, 2);
    float dP = (lx * py - ly * px) / lineLength;

    if (tI >= 0 && tI <= 1)
        return abs(dP);
    else
        return min(distance(p, lineStart), distance(p, lineEnd));
}
   
float2 rotation(float2 rotateThis, float2 aroundPoint, float angle)
{
    float rx = rotateThis.x - aroundPoint.x;
    float ry = rotateThis.y - aroundPoint.y;
    return float2(
            cos(angle) * rx - sin(angle) * ry + aroundPoint.x,
            sin(angle) * rx + cos(angle) * ry + aroundPoint.y
            );

}
float4 build(float3 v, float3 stat, int arms, int width[8], int px[8], int py[8])
{
    float1 d = distance(float2(stat.y,stat.y), float2(v.x, v.z));
   
    if (stat.y > d)
    {
        return float4(0, 0, 0, 0);
    }
    float2 pixel = rotation(v.xy, float2(stat.y, stat.y), stat.x * d);
    float r = 0;
    for (int a = 0; a < arms; a++)
    {
        float l = lineDistance(pixel, lerp(0, float2(px[a], py[a]), stat.z), float2(px[a], py[a]));
       
        float result;
        if (d / stat.y < stat.z)
        {
            result = clamp((width[a] - l - abs((d + v.z) / stat.y - stat.z) * width[a]) / width[a], 0, 1);
        }
        else
        {
            result = clamp((width[a] - l - abs((d + v.z) / stat.y - stat.z) * width[a] / (1 - stat.z)) / width[a], 0, 1);

        }
        if (r > result)
        {
            result = r;
        }
    }
    return float4(r,r,r,r);
}


[numthreads(32, 32, 1)]
void CSMain(uint3 id : SV_DispatchThreadID)
{   
    Result[id.xyz] = build(float3(id.x, id.y, id.z), sro, arms, width, px,py);

}

Component:

using UnityEngine;
using System.Collections;

[ExecuteInEditMode]
public class SphericalFog : MonoBehaviour
{
    protected MeshRenderer sphericalFogObject;
    public Material sphericalFogMaterial;
    public float scaleFactor = 1;
    [SerializeField]
    public ComputeShader computeShader;
    [SerializeField]
    private int seed = 200;
    [SerializeField]
    private int scale = 256;
    [SerializeField]
    private Vector3 center;
    [SerializeField]
    private int samples = 100;
    void OnEnable ()
    {
        sphericalFogObject = gameObject.GetComponent<MeshRenderer>();
        if (sphericalFogObject == null)
            Debug.LogError("Volume Fog Object must have a MeshRenderer Component!");
       
        //Note: In forward lightning path, the depth texture is not automatically generated.
        if (Camera.main.depthTextureMode == DepthTextureMode.None)
            Camera.main.depthTextureMode = DepthTextureMode.Depth;
        UpdateCompute();
        sphericalFogObject.material = sphericalFogMaterial;
       
    }
    void UpdateCompute()
    {
        //int r1 = galaxyRes - 1;
        float scalefactor = 1024f / scale;
        //swirl = new ByteMatrix2D(galaxyRes);

        System.Random random = new System.Random(seed);
        float d = (Mathf.Tan(2.746f * ((float)random.NextDouble() - 0.5f)) * 0.2f);

        float speed = d / 10 * scalefactor;
        float vertScale = Mathf.Abs(speed);

        int arms = random.Next(1, 8);
        float off = (float)(random.NextDouble()) / 1.5f;

        bool even = false;

        int[] px = new int[8];
        int[] py = new int[8];

        Vector2 center = new Vector3();
        int r1 = scale - 1;


        //int width = random.Next((int)((1 - Mathf.Abs(d)) * scale), scale);
        int[] width = new int[8];

        for (byte arm = 0; arm < arms; arm++)
        {

            if (!even)
            {

                even = true;

                int side = random.Next(1, 4);
                switch (side)
                {
                    case 1:
                        px[arms] = 0;
                        py[arms] = random.Next(0, r1);
                        break;
                    case 2:
                        px[arms] = r1;
                        py[arms] = random.Next(0, r1);
                        break;
                    case 3:
                        px[arms] = random.Next(0, r1);
                        py[arms] = 0;
                        break;
                    default:
                        px[arms] = random.Next(0, r1);
                        py[arms] = r1;
                        break;
                }
            }
            else
            {
                even = false;


                px[arms] = Mathf.Abs(px[arms] - scale);
                py[arms] = Mathf.Abs(py[arms] - scale);

            }
            width[arm] = random.Next((int)((1 - Mathf.Abs(d)) * scale), scale);
            //Vector2 offset = Vector2.Lerp(center, point[arms], off);


        }
        computeShader.SetVector("sro", new Vector3(speed, scale, off));
        computeShader.SetVector("center", center);
      
       
        computeShader.SetInt("arms", arms);
        computeShader.SetInts("width", width);//SetVectorArray("_p", point);
        computeShader.SetInts("px", px);
        computeShader.SetInts("py", py);
        //RWTexture3D<float3> Result;

        RenderTexture myRt;

        myRt = new RenderTexture(scale, scale, scale);
        myRt.enableRandomWrite = true;
        myRt.isPowerOfTwo = true;
        myRt.volumeDepth = scale;
        myRt.Create();

        int kernelHandle = computeShader.FindKernel("CSMain");
        //computeShader.SetInt("RandOffset", (int)(Time.timeSinceLevelLoad * 100));
       
        computeShader.SetTexture(kernelHandle, "Result", myRt);

        computeShader.Dispatch(kernelHandle, scale / 32, scale / 32, scale / 1);

       
        sphericalFogMaterial.SetTexture("_texture", myRt);
    }
    void Update ()
    {
        float radius = (transform.lossyScale.x + transform.lossyScale.y + transform.lossyScale.z) / 6;
        Material mat = Application.isPlaying ? sphericalFogObject.material : sphericalFogObject.sharedMaterial;
        if (mat)
            mat.SetVector ("FogParam", new Vector4(transform.position.x, transform.position.y, transform.position.z, radius * scaleFactor));
    }
}

And the raymarch shader, though i dont think the problem is here:

// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'

Shader"FX/Spherical Fog" {
    Properties {
        _FogBaseColor ("Fog Base Color", Color) = (0,1,1,1)
        _FogDenseColor ("Fog Dense Color", Color) = (1,1,1,1)
        _InnerRatio ("Inner Ratio", Range (0.0, 0.9999)) = 0.5
        _Density ("Density", Range (0.0, 10.0)) = 10.0
        _ColorFalloff ("Color Falloff", Range (0.0, 50.0)) = 16.0
        _texture("3D Texture", 3D) = ""{}
    //_sro ("Scale Radius Offset", float3) = float3(100,128,0)

    //_texture("3D Texture", texture)
    //_samples("Samples", int) = 100
    }
    
    Category {
        Tags { "Queue"="Transparent+99" "IgnoreProjector"="True" "RenderType"="Transparent" }
        Blend SrcAlpha OneMinusSrcAlpha
        Cull Off Lighting Off ZWrite Off
        ZTest Always
        
        SubShader {
            Pass {
                CGPROGRAM
                #pragma target 3.0
                #pragma vertex vert
                #pragma fragment frag
                #include "UnityCG.cginc"
                //#include "Assets\Compute\Galaxy.compute"
                
inline float CalcVolumeFogIntensity(
                    float3 sphereCenter,
                    float sphereRadius,
                    float innerRatio,
                    float density,
                    float3 cameraPosition,
                    float3 viewDirection,
                    float maxDistance,
                    sampler3D myTexture
                   
                ) {
                    // Local is the cam position in local space of the sphere.
                    float3 local = cameraPosition - sphereCenter;
                   
                    // Calculate ray-sphere intersection
                    float fA = dot (viewDirection, viewDirection);
                    float fB = 2 * dot (viewDirection, local);
                    float fC = dot(local, local) - sphereRadius * sphereRadius;
                    float fD = fB * fB - 4 * fA * fC;
                   
                    // Early out of no intersection.
                    if (fD <= 0.0f)
                        return 0;
                    
                    float recpTwoA = 0.5 / fA;
                    float DSqrt = sqrt (fD);
                    // Distance to front of sphere (0 if inside sphere).
                    // This is the distance from the camera where sampling should begin.
                    float dist = max ((-fB - DSqrt) * recpTwoA, 0);
                    // Distance to back of sphere
                    float dist2 = max ((-fB + DSqrt) * recpTwoA, 0);
                    
                     // Max sampling depth should be minimum of back of sphere or solid surface hit.
                    float backDepth = min (maxDistance, dist2);
                    // Calculate initial sample dist and distance between samples.
                    float sample = dist;
                    float step_distance = (backDepth - dist) / 10;
                   
                    // The step_contribution is a value where 0 means no reduction in clarity and
                    // 1 means 100% reduction in clarity.
                    // The step_contribution approaches 1 as the sample distance increases.
                    float step_contribution = (1 - 1 / pow (2, step_distance)) * density;
                   
                    // Calculate value at the center needed to make the value be 1 at the desired inner ratio.
                    // This high value does not actually produce high density in the center, since it's clamped to 1.
                    float centerValue = 1 / (1 - innerRatio);
                   
                    // Initially there's no fog, which is full clarity.
                    float clarity = 1;
                    for ( int seg = 0; seg < 10; seg++ )
                    {
                        float3 position = local + viewDirection * sample;
                        float val = saturate (centerValue * (1 - length (position) / sphereRadius));
                        float sample_fog_amount = saturate (val * step_contribution * tex3D (myTexture, position).x);
                        clarity *= (1 - sample_fog_amount);
                        sample += step_distance;
                    }
                    return (1 - clarity);
                }
                
                fixed4 _FogBaseColor;
                fixed4 _FogDenseColor;
                float _InnerRatio;
                float _Density;
                float _ColorFalloff;
                sampler2D _CameraDepthTexture;
                uniform float4 FogParam;
                uniform sampler3D _texture;

                struct v2f {
                    float4 pos : SV_POSITION;
                    float3 view : TEXCOORD0;
                    float4 projPos : TEXCOORD1;
                };
                
                v2f vert (appdata_base v) {
                    v2f o;
                    float4 wPos = mul (unity_ObjectToWorld, v.vertex);
                    o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
                    o.view = wPos.xyz - _WorldSpaceCameraPos;
                    o.projPos = ComputeScreenPos (o.pos);
                    
                    // Move projected z to near plane if point is behind near plane.
                    float inFrontOf = ( o.pos.z / o.pos.w ) > 0;
                    o.pos.z *= inFrontOf;
                    return o;
                }
                
                half4 frag (v2f i) : COLOR {
                    half4 color = half4 (1,1,1,1);
                    float depth = LinearEyeDepth (UNITY_SAMPLE_DEPTH (tex2Dproj (_CameraDepthTexture, UNITY_PROJ_COORD (i.projPos))));
                    float3 viewDir = normalize (i.view);
                   
                    // Calculate fog density.
                    // Scale by factor 1000 to avoid precision errors for large volumes.
                    float fog = CalcVolumeFogIntensity (
                        FogParam.xyz * 0.001,
                        FogParam.w * 0.001,
                        _InnerRatio,
                        _Density * 1000,
                        _WorldSpaceCameraPos * 0.001,
                        viewDir,
                        depth * 0.001,
                        _texture);
                   
                    // Calculate ratio of dense color.
                    float denseColorRatio = pow (fog, _ColorFalloff);
                   
                    // Set color based on denseness and alpha based on raw calculated fog density.
                    color.rgb = lerp (_FogBaseColor.rgb, _FogDenseColor.rgb, denseColorRatio);
                    color.a = fog * lerp (_FogBaseColor.a, _FogDenseColor.a, denseColorRatio);
                    return color;
                }
                ENDCG
            }
        }
    }
    Fallback "VertexLit"
}

I figured out this problem almost immediately after posting this, For anyone with similar problems, its quite simple.

You need to set the dimensions of the render texture, like this:
myRt.dimension = UnityEngine.Rendering.TextureDimension.Tex3D;