Skip to content

Instantly share code, notes, and snippets.

@yonatan
Forked from gam0022/zozuar-cloud.glsl
Last active April 25, 2022 06:54
Show Gist options
  • Save yonatan/18483ee051b57f79f481d17925fab642 to your computer and use it in GitHub Desktop.
Save yonatan/18483ee051b57f79f481d17925fab642 to your computer and use it in GitHub Desktop.
// Commented version of https://twitter.com/zozuar/status/1441384708441456651
// Google-translated (with some editing) from @gam0022's version
float i, // Ray marching loop counter
e, // Volume density (the smaller the value, the higher the density)
s, // FBM scale (and loop counter)
g, // Ray's distance (also used for tunnel twirl and camera prespective)
k = .01; // Handy constant
// Ray marching loop
for (
o++;// A shorter way to do o=vec4(1)
i++ < 1e2;// Ray marching steps
g += max(k, e * .2)// Small steps (.01 distance) through high density (negative e) areas
) {
// Camera control
vec3 p = vec3(
(FC.xy - .6 * r) / r.y * g + // .6*r places the tunnel a bit off-center, multiply by g for perspective
r / r * rotate2D(t + g * .5) * .5,// Add tunnel twirl, r/r is vec2(1)
g + t / .3// Move forward (t is time)
);
// Initial value of volume density. Reduce the density only in the center of the camera.
// The volume density is higher when the value is negative.
e = .3 - dot(p.xy, p.xy);
// Calculate volume density with FBM
for (s = 2.; s < 2e2; s /= .6)
p.yz *= rotate2D(s),// Rotate to avoid artifacts, the amount doesn't really matter, s is just short
e += abs(dot(sin(p * s + t * s * .2) / s,// p is multiplied and the result is divided by s (the fbm scale),
// t * s * .2 makes the clouds change shape over time
p - p + 1.)); // p-p+1. is a short way to write vec3(1)
// Color by volume (aka - the tricky bit)
//*
o += o.w * // Transparency level, which goes down to 0 as we march and accumulate color from the volume
min(
e * o// Multiply the latest result by density. Note that e can be negative
+ (sin(vec4(1, 2, 3, 1) - p.z * .3) * .6 - .4),// sin() based palette. w should really always be 1,
// but it's not too bad like this.
k)// Should be "0.0" so the result is never positive, but k (0.01) is shorter.
* k;// Coefficient adjustment with k = 0.01
/*/
// Actually, if you want to shave off some more bytes you can lose the o.w and the min() like so:
o+=(o*e+sin(vec4(1,2,3,1)-p.z*.3)*.4-.6)*k; // It's not quite as nice but still ok-ish looking
//*/
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment