This browser has no WebGPU, so the sketch cannot run here. The program is below, and it runs in a current Chrome, Edge or Safari.
Sand 3D
&sandboxSz = 32;
&FROM_NX = mlt(
lrg(#(1,-1,0), 0),
lrg(#(1,0,0), 0),
lrg(#(2,0,0), 0)
);
&FROM_PZ = mlt(
lrg(#(0,-1,-1), 0),
lrg(#(0,0,-1), 0),
lrg(#(1,0,-1), 0),
lrg(#(-1,0,-1), 0)
);
&FROM_NZ = mlt(
lrg(#(0,-1,1), 0),
lrg(#(0,0,1), 0),
lrg(#(1,0,1), 0),
lrg(#(-1,0,1), 0),
lrg(#(0,0,2), 0)
);
&UP = mlt(
lrg(#(0,1,0), 0),
lrg(#(1,1,0), 0),
lrg(#(-1,1,0), 0),
lrg(#(0,1,1), 0),
lrg(#(0,1,-1), 0)
);
#randRot{
dim = (&sandboxSz,&sandboxSz,1);
set = mlt(srand(1,2,3), PI);
}
#newGrain{
dim = (&sandboxSz,&sandboxSz,1);
run = mlt(sml(rand(step), 0.01), sml(dst(C, 0), 0.3));
val_dom = UNIT;
}
&newGrain = mlt( eql(mod(step, 2),0), mlt(sml(C.y,-0.9), #newGrain[C.x, C.z , 0]));
&NOT_TOP = lrg(C.y, -0.9);
#sandbox{
dim = (&sandboxSz,&sandboxSz,&sandboxSz);
bound = CLAMP;
val_dom = UNIT;
set = (0);
run =
add(
&newGrain,
// ==================================================
// KEEP CURRENT GRAIN
//
// Stay if:
// - we reached the floor
// - or every possible downward route is blocked
// ==================================================
mlt(
lrg(#, 0),
max(
lrg(C.y, 0.9),
&UP
)
),
// ==================================================
// STRAIGHT DOWN
//
// Grain directly above falls into this empty voxel.
// ==================================================
mlt(
eql(#, 0),
lrg(#(0,-1,0), 0)
),
// ==================================================
// +X
//
// Source is (-1,-1,0).
// Its straight-down voxel is blocked.
// ==================================================
mlt(
eql(#, 0),
lrg(C.y, -0.9),
lrg(#(-1,-1,0), 0),
lrg(#(-1,0,0), 0)
),
// ==================================================
// -X
//
// Straight down and +X were blocked.
// ==================================================
mlt(eql(#, 0),&FROM_NX),
// ==================================================
// +Z
//
// Straight down, +X and -X were blocked.
// ==================================================
mlt(eql(#, 0), &FROM_PZ),
// ==================================================
// -Z
//
// Straight down, +/-X and +Z were blocked.
// ==================================================
mlt(eql(#, 0), &FROM_NZ)
);
}
~A{
dim = (&sandboxSz,&sandboxSz,&sandboxSz);
i_scl = mlt(lrg(#sandbox, 0), 1.7);
i_pos = C;
i_rot = #randRot;
shape = ICO;
col = (1);
rot = (0, 0, PI);
pos = (0, 0.5, 0);
}
{
= (0.9);
= (0.3);
}