#version 430 core layout(local_size_x = 16, local_size_y = 16) in; // Read-write access to the current grid layout(r8ui, binding = 0) coherent uniform uimage2D state; uniform ivec2 u_gridSize; uniform vec2 u_brushPos; // in grid-space (cells) uniform float u_brushRadius; // in cells uniform int u_mode; // 0 = none, 1 = add sand, -1 = erase void main() { ivec2 pos = ivec2(gl_GlobalInvocationID.xy); if (pos.x >= u_gridSize.x || pos.y >= u_gridSize.y) { return; } if (u_mode == 0) { return; } // Center of this cell in grid coords vec2 cellCenter = vec2(pos) + vec2(0.5); float dist = length(cellCenter - u_brushPos); if (dist > u_brushRadius) { return; } const uint AIR = 0u; const uint SAND = 1u; if (u_mode > 0) { // left click: fill with sand imageStore(state, pos, uvec4(SAND, 0u, 0u, 0u)); } else if (u_mode < 0) { // right click: erase sand imageStore(state, pos, uvec4(AIR, 0u, 0u, 0u)); } }