I am creating a 3D cellular automata for a personal project, and I am using a compute shader to read/write to a uimage3D, but I’m having some weird errors when it comes to checking adjacent voxels. As a test, I decided to set each voxel to the value of the voxel to it’s ‘left’ with wrap around. Here’s the code:
#version 460 core
layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
//This is the size of the width/height/depth of the 3D texture
uniform int uGridSize;
layout(r32ui, binding = 0) uniform uimage3D image;
void main()
{
uint x = gl_GlobalInvocationID.x;
uint y = gl_GlobalInvocationID.y;
uint z = gl_GlobalInvocationID.z;
uvec4 State = imageLoad(image, ivec3(((x - 1) + uGridSize) % uGridSize, y, z ));
imageStore(image, ivec3(x, y, z), State);
}
This works as expected for the first few seconds, but here’s how it looks after a few seconds: (Note, only one voxel has a value of one, the rest are zero, and if a voxel has a value of zero, I don’t render it as a little cube)
As you can see, there’s some kind of smearing happening. I’m not sure where the problem lies. Here’s my texture initialization code and my compute shader code.
glGenTextures(1, &m_3DTexture);
glBindTexture(GL_TEXTURE_3D, m_3DTexture);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage3D(GL_TEXTURE_3D, 0, GL_R32UI, m_GridSize, m_GridSize, m_GridSize, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, m_CellData.data());
glBindImageTexture(0, m_3DTexture, 0, GL_TRUE, 0, GL_READ_WRITE, GL_R32UI);
And the compute shader dispatch code:
glUseProgram(m_ComputeProgramID);
glUniform1i(glGetUniformLocation(m_ComputeProgramID, "uGridSize"), m_GridSize);
glUniform1i(glGetUniformLocation(m_ComputeProgramID, "uStates"), m_States);
glUniform1i(glGetUniformLocation(m_ComputeProgramID, "uMooreNeighborhood"), m_MooreNeighborhood);
glUniform1i(glGetUniformLocation(m_ComputeProgramID, "uSurviveCount"), m_SurviveCount);
glUniform1i(glGetUniformLocation(m_ComputeProgramID, "uBirthCount"), m_BirthCount);
glDispatchCompute((unsigned int)m_GridSize, (unsigned int)m_GridSize, (unsigned int)m_GridSize);
glMemoryBarrier(GL_ALL_BARRIER_BITS);
Thanks for your help!