SOURCE / PINNED RELEASE
Made of little things.
Safe Sand · Material studies
- Release
- 9101a9cd9fb4…
- Author-recorded commit
- 75d98e1b8edb…
- License
- LICENSE
- Author’s source reference
- nostr://npub182jczunncwe0jn6frpqwq3e0qjws7yqqnc3auccqv9nte2dnd63scjm4rf/wss%3A%2F%2Fgit.napplet.soy%2F/n-7682e55a791
Archive hash verified: 6c8ddabeb31100e1…. The source-to-build association is the author’s claim; it has not been independently rebuilt.
// Adapted from av/safe-sand, e27bafa. See THIRD_PARTY.md for provenance.
export const HEADER = `#version 300 es
precision highp float;
precision highp int;
precision highp sampler2D;
`;
export const COMMON = `
uniform vec4 uPal[8];
uniform vec4 uSize;
uniform vec4 uSize2;
uniform vec4 uFric;
uniform vec4 uLook;
uniform vec4 uMaterial;
uint pcg(uint v) {
uint state = v * 747796405u + 2891336453u;
uint word = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u;
return (word >> 22u) ^ word;
}
float rnd(uint i, uint s) { return float(pcg(i * 32u + s) >> 8) / 16777215.0; }
float rnd3(uint i, uint s, uint f) { return float(pcg(pcg(i * 32u + s) + f * 1664525u) >> 8) / 16777215.0; }
struct Grain {
float r;
float kind;
float mu;
vec3 col;
float sparkle;
float transl;
float aspect;
};
vec3 pickColor(float u) {
vec3 c = uPal[7].rgb;
for (int k = 7; k >= 0; k--) { if (u <= uPal[k].a) c = uPal[k].rgb; }
return c;
}
Grain grain(uint i) {
Grain g;
float u = rnd(i, 0u);
float gs = sqrt(-2.0 * log(max(rnd(i, 1u), 1e-6))) * cos(6.2831853 * rnd(i, 2u));
if (u < uSize.w) {
g.kind = 2.0;
g.r = mix(uSize2.x, uSize2.y, pow(rnd(i, 3u), 2.2));
g.mu = rnd(i, 23u) < 0.6 ? mix(0.1, 0.22, rnd(i, 4u)) : mix(0.3, 0.5, rnd(i, 4u));
} else if (u < uSize.w + uSize.z) {
g.kind = 1.0;
g.r = mix(uSize2.z, uSize2.w, pow(rnd(i, 3u), 1.5));
g.mu = rnd(i, 23u) < 0.35 ? mix(uFric.x * 0.6, uFric.x * 1.2, rnd(i, 4u)) : mix(uFric.x * 1.6, uFric.y, rnd(i, 4u)) * 0.85;
} else {
g.kind = 0.0;
g.r = clamp(uSize.x * exp(uSize.y * gs), 0.045, 0.42);
g.mu = rnd(i, 23u) < 0.25 ? mix(uFric.x * 0.6, uFric.x * 1.2, rnd(i, 4u)) : mix(uFric.x * 1.6, uFric.y, rnd(i, 4u));
}
float cu = rnd(i, 5u);
vec3 c = pickColor(cu);
float bright = 0.78 + 0.44 * rnd(i, 6u);
vec3 tint = vec3(1.0) + (vec3(rnd(i, 7u), rnd(i, 8u), rnd(i, 9u)) - 0.5) * 0.1;
g.col = c * bright * tint;
if (g.kind == 2.0) {
float sk = rnd(i, 12u);
vec3 st = sk < 0.3 ? vec3(0.27, 0.26, 0.245) : sk < 0.45 ? vec3(0.055, 0.055, 0.058) : sk < 0.6 ? vec3(0.42, 0.35, 0.26) : sk < 0.7 ? vec3(0.28, 0.16, 0.09) : sk < 0.8 ? vec3(0.58, 0.56, 0.52) : sk < 0.9 ? vec3(0.15, 0.18, 0.145) : vec3(0.14, 0.155, 0.18);
g.col = mix(st * bright, g.col * 0.8, 0.3);
}
float lum = dot(g.col, vec3(0.3, 0.55, 0.15));
g.sparkle = step(0.7, rnd(i, 10u)) * smoothstep(0.08, 0.35, lum) * uFric.w;
g.transl = smoothstep(0.12, 0.6, lum) * (g.kind == 2.0 ? 0.15 : 0.6);
g.aspect = mix(0.7, 1.0, rnd(i, 11u));
if (uMaterial.x == 1.0) { g.aspect = 1.0; g.transl = 1.2; g.sparkle = 2.0; }
if (uMaterial.x == 2.0) { g.aspect = 0.28; g.transl = 0.0; g.sparkle = 1.5; }
if (uMaterial.x == 3.0) { g.aspect = 0.8; g.sparkle = 5.0; g.transl = 0.1; }
return g;
}
`;
