How to pass a Array<Image> object to a compute shader as sampler3D ?

Godot Version

4.3.stable.mono

Question

here’s my code:
mapArray is an Array<byte> object (mapArray.Count = 16), and each byte in it is a serialized (16*16)Image data.


I’ m trying to pass this mapArray to compute shader below as a (16,16,16)sampler3D

however when I run this code, There have been some errors


Did I forget to set some options? Or is this method of creating sampler3D inherently incorrect?

Below is the complete code

Blockquote
C# code
GD.Print(“init device”);
RenderingDevice rd = RenderingServer.CreateLocalRenderingDevice();
RDShaderFile shaderFile = GD.Load(“res://Scripts/Compute.glsl”);
RDShaderSpirV shaderByteCode = shaderFile.GetSpirV();
Rid shader = rd.ShaderCreateFromSpirV(shaderByteCode);
Rid pipeline = rd.ComputePipelineCreate(shader);
GD.Print(“init device done”);

    //Buffer uniform
    Rid buf = rd.StorageBufferCreate(256 * sizeof(int));
    RDUniform bufUniform = new RDUniform()
    {
        UniformType = RenderingDevice.UniformType.StorageBuffer,
        Binding = 0
    };
    bufUniform.AddId(buf);


    //Texture uniform
    RDTextureFormat texFormat = new RDTextureFormat()
    {
        Depth = 16,
        Width = 16,
        Height = 16,
        TextureType = RenderingDevice.TextureType.Type3D,
        UsageBits = RenderingDevice.TextureUsageBits.SamplingBit | RenderingDevice.TextureUsageBits.CanUpdateBit,
        Format = RenderingDevice.DataFormat.R8Unorm
    };

    Rid texture = rd.TextureCreate(texFormat, new RDTextureView(), mapArray);
    RDSamplerState samplerState = new RDSamplerState()
    {
        UnnormalizedUvw = true,
    };


    Rid sampler = rd.SamplerCreate(samplerState);
    RDUniform texUniform = new RDUniform()
    {
        UniformType = RenderingDevice.UniformType.SamplerWithTexture,
        Binding = 1
    };
    texUniform.AddId(sampler);
    texUniform.AddId(texture);


    //UniformSet
    Array<RDUniform> uniforms = new Array<RDUniform>();
    uniforms.Add(bufUniform);
    uniforms.Add(texUniform);
    GD.Print("uniforms.Count : ", uniforms.Count);
    Rid uniformSet = rd.UniformSetCreate(uniforms, shader, 0);

    long computeList = rd.ComputeListBegin();

    rd.ComputeListBindComputePipeline(computeList, pipeline);
    rd.ComputeListBindUniformSet(computeList, uniformSet, 0);
    rd.ComputeListDispatch(computeList, 4, 4, 4);
    rd.ComputeListEnd();
    rd.Submit();

    rd.Sync();

    byte[] data = rd.BufferGetData(buf, 0);

Blockquote
Glsl code

#[compute]
#version 450

// Invocations in the (x, y, z) dimension
layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in;

// A binding to the buffer we create in our script
layout(set = 0, binding = 0, std430) restrict buffer MyDataBuffer {
int data;
}my_data_buffer;

layout(set = 0, binding = 1) uniform sampler3D DensityMap;
void main()
{
int gray = int(texture(DensityMap,vec3(gl_GlobalInvocationID.xy,1)).r * 255);
int a = 255;

my_data_buffer.data[gl_GlobalInvocationID.x + gl_GlobalInvocationID.y * 16] = (a << 24) + (gray << 16) + (gray << 8) + gray;

}