diff --git a/src/shaders/sandPhysics.frag b/src/shaders/sandPhysics.frag index db32fc8..e07520b 100644 --- a/src/shaders/sandPhysics.frag +++ b/src/shaders/sandPhysics.frag @@ -32,11 +32,14 @@ void main() { } // read 2x2 block + // index mapping (GL coords — Y increases upward): + // [2][3] <- top row (y offset 1, higher Y) + // [0][1] <- bottom row (y offset 0, lower Y) vec4 cells[4]; float behaviors[4]; float densities[4]; for (int i = 0; i < 4; i++) { - ivec2 p = blockBase + ivec2(i % 2, 1 - i / 2); + ivec2 p = blockBase + ivec2(i % 2, i / 2); cells[i] = texelFetch(uWorld, p, 0); vec4 props = texelFetch(uMaterialProps, ivec2(int(cells[i].r), 0), 0); behaviors[i] = props.r; @@ -44,22 +47,17 @@ void main() { } // capture blocked state before vertical swaps modify the arrays - bool col0Blocked = (behaviors[0] == BEHAVIOR_SOLID || behaviors[2] == BEHAVIOR_SOLID || densities[0] <= densities[2]); - bool col1Blocked = (behaviors[1] == BEHAVIOR_SOLID || behaviors[3] == BEHAVIOR_SOLID || densities[1] <= densities[3]); + // "blocked" = column is settled (top lighter/equal to bottom) or contains solid + bool col0Blocked = (behaviors[0] == BEHAVIOR_SOLID || behaviors[2] == BEHAVIOR_SOLID || densities[2] <= densities[0]); + bool col1Blocked = (behaviors[1] == BEHAVIOR_SOLID || behaviors[3] == BEHAVIOR_SOLID || densities[3] <= densities[1]); // random seed for this block this frame uint seed = hash(uint(blockBase.x) * 7919u + uint(blockBase.y) * 6271u + uint(uFrame) * 3571u); - // try vertical gravity: column 0 (indices 0, 2) and column 1 (indices 1, 3) - // top=0,1 bottom=2,3 - // block layout: - // [0][1] <- top row - // [2][3] <- bottom row - // if top is movable and top.density > bottom.density, swap - + // vertical gravity: top cells (2,3) fall to bottom (0,1) if heavier for (int col = 0; col < 2; col++) { - int top = col; // 0 or 1 - int bot = col + 2; // 2 or 3 + int top = col + 2; // 2 or 3 — top row (higher Y) + int bot = col; // 0 or 1 — bottom row (lower Y) if (behaviors[top] != BEHAVIOR_SOLID && behaviors[bot] != BEHAVIOR_SOLID) { if (densities[top] > densities[bot]) { @@ -74,41 +72,39 @@ void main() { } } - // try diagonal: if top cell still has high density and couldn't fall straight - // for top-left (0): can it go diagonal to bottom-right (3)? - // for top-right (1): can it go diagonal to bottom-left (2)? - // only if the cell directly below is blocked (same or higher density) + // diagonal: if a top cell couldn't fall straight down, try diagonal + // top-left (2) -> bottom-right (1), top-right (3) -> bottom-left (0) bool tryLeftFirst = (seed & 1u) == 0u; if (tryLeftFirst) { - // try 0->3 diagonal (top-left to bottom-right) - if (col0Blocked && behaviors[0] != BEHAVIOR_SOLID && behaviors[3] != BEHAVIOR_SOLID && - densities[0] > densities[3]) { - vec4 tmp = cells[0]; cells[0] = cells[3]; cells[3] = tmp; - float tmpB = behaviors[0]; behaviors[0] = behaviors[3]; behaviors[3] = tmpB; - float tmpD = densities[0]; densities[0] = densities[3]; densities[3] = tmpD; + // try 2->1 diagonal (top-left to bottom-right) + if (col0Blocked && behaviors[2] != BEHAVIOR_SOLID && behaviors[1] != BEHAVIOR_SOLID && + densities[2] > densities[1]) { + vec4 tmp = cells[2]; cells[2] = cells[1]; cells[1] = tmp; + float tmpB = behaviors[2]; behaviors[2] = behaviors[1]; behaviors[1] = tmpB; + float tmpD = densities[2]; densities[2] = densities[1]; densities[1] = tmpD; } - // try 1->2 diagonal (top-right to bottom-left) - if (col1Blocked && behaviors[1] != BEHAVIOR_SOLID && behaviors[2] != BEHAVIOR_SOLID && - densities[1] > densities[2]) { - vec4 tmp = cells[1]; cells[1] = cells[2]; cells[2] = tmp; - float tmpB = behaviors[1]; behaviors[1] = behaviors[2]; behaviors[2] = tmpB; - float tmpD = densities[1]; densities[1] = densities[2]; densities[2] = tmpD; + // try 3->0 diagonal (top-right to bottom-left) + if (col1Blocked && behaviors[3] != BEHAVIOR_SOLID && behaviors[0] != BEHAVIOR_SOLID && + densities[3] > densities[0]) { + vec4 tmp = cells[3]; cells[3] = cells[0]; cells[0] = tmp; + float tmpB = behaviors[3]; behaviors[3] = behaviors[0]; behaviors[0] = tmpB; + float tmpD = densities[3]; densities[3] = densities[0]; densities[0] = tmpD; } } else { - // try 1->2 first - if (col1Blocked && behaviors[1] != BEHAVIOR_SOLID && behaviors[2] != BEHAVIOR_SOLID && - densities[1] > densities[2]) { - vec4 tmp = cells[1]; cells[1] = cells[2]; cells[2] = tmp; - float tmpB = behaviors[1]; behaviors[1] = behaviors[2]; behaviors[2] = tmpB; - float tmpD = densities[1]; densities[1] = densities[2]; densities[2] = tmpD; + // try 3->0 first + if (col1Blocked && behaviors[3] != BEHAVIOR_SOLID && behaviors[0] != BEHAVIOR_SOLID && + densities[3] > densities[0]) { + vec4 tmp = cells[3]; cells[3] = cells[0]; cells[0] = tmp; + float tmpB = behaviors[3]; behaviors[3] = behaviors[0]; behaviors[0] = tmpB; + float tmpD = densities[3]; densities[3] = densities[0]; densities[0] = tmpD; } - // try 0->3 - if (col0Blocked && behaviors[0] != BEHAVIOR_SOLID && behaviors[3] != BEHAVIOR_SOLID && - densities[0] > densities[3]) { - vec4 tmp = cells[0]; cells[0] = cells[3]; cells[3] = tmp; - float tmpB = behaviors[0]; behaviors[0] = behaviors[3]; behaviors[3] = tmpB; - float tmpD = densities[0]; densities[0] = densities[3]; densities[3] = tmpD; + // try 2->1 + if (col0Blocked && behaviors[2] != BEHAVIOR_SOLID && behaviors[1] != BEHAVIOR_SOLID && + densities[2] > densities[1]) { + vec4 tmp = cells[2]; cells[2] = cells[1]; cells[1] = tmp; + float tmpB = behaviors[2]; behaviors[2] = behaviors[1]; behaviors[1] = tmpB; + float tmpD = densities[2]; densities[2] = densities[1]; densities[1] = tmpD; } }