You can easily generalize for n dimensions by (albeit incredible slow!!!!):
ClearAll@Sandpile
Sandpile[x_SparseArray] := Sandpile@Normal@x
Normal@Sandpile[s_List] ^:= s
Sandpile /: Sandpile[a_List] + Sandpile[n_Integer] := Sandpile@a + Sandpile[ConstantArray[n, Dimensions@a]]
Sandpile /: Sandpile[a_List] + Sandpile[b_List] /; Dimensions@a === Dimensions@b := Module[
{sum, temp, rest, sides},
sum = a + b;
sides = Permutations@Append[ConstantArray[0, {ArrayDepth@a - 1}], 1];
sides = Join[sides, -sides];
While[Max@sum >= 4,
sum = ArrayPad[sum, 1, 0];
temp = Quotient[sum, 4];
sum -= 4 temp;
sum += Total[RotateLeft[temp, ##1] & /@ sides];
sum = ArrayPad[sum, -1]
];
Sandpile@sum
]
Sandpile$Colors = {0 -> Black, 1 -> Yellow, 2 -> Blue, 3 -> Red, _Integer -> Pink};
Format[Sandpile[t_List /; ArrayDepth@t <= 2]] := ArrayPlot[If[ArrayDepth@t == 1, {t}, t] /. Sandpile$Colors,
ImageSize -> 400, Frame -> False]
Format[Sandpile[t_List /; ArrayDepth@t == 3]] := ListDensityPlot3D[t, ImageSize -> 400, Axes -> False,
ColorFunction -> (Blend[{{0, Black}, {1, Yellow}, {2, Blue}, {3, Red}}, #] &),
ColorFunctionScaling -> False, SphericalRegion -> True, Boxed -> False]