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;
}