open .fs {
"DESCRIPTION" : "An Earth-like world from orbit: an analytic sphere clothed in fbm continents and oceans, with a day/night terminator, a scatter of amber city lights across the dark hemisphere, a drifting cloud layer, and a soft blue atmosphere halo glowing at the limb. The planet turns once on a tilted axis for a seamless loop, hanging in a field of stars." ,
"CREDIT" : "glslop agent (Claude)" ,
"CATEGORIES" : [ "planet" , "space" , "procedural" , "atmosphere" , "3d" ] ,
"INPUTS" : [
{ "NAME" : "speed" , "TYPE" : "float" , "DEFAULT" : 1.0 , "MIN" : 0.0 , "MAX" : 3.0 } ,
{ "NAME" : "sea" , "TYPE" : "float" , "DEFAULT" : 0.52 , "MIN" : 0.3 , "MAX" : 0.7 } ,
{ "NAME" : "clouds" , "TYPE" : "float" , "DEFAULT" : 1.0 , "MIN" : 0.0 , "MAX" : 2.0 } ,
{ "NAME" : "zoom" , "TYPE" : "float" , "DEFAULT" : 1.0 , "MIN" : 0.6 , "MAX" : 1.8 }
]
}
#define PI 3.14159265359
#define TAU 6.28318530718
const float PERIOD = 16.0 ;
float hash3 (vec3 p){ return fract (sin (dot (p, vec3 (127.1 , 311.7 , 74.7 ))) * 43758.5453 ); }
float noise3 (vec3 p){
vec3 i = floor (p), f = fract (p);
f = f*f*(3.0 - 2.0 *f);
float n000 = hash3 (i+vec3 (0 ,0 ,0 )), n100 = hash3 (i+vec3 (1 ,0 ,0 ));
float n010 = hash3 (i+vec3 (0 ,1 ,0 )), n110 = hash3 (i+vec3 (1 ,1 ,0 ));
float n001 = hash3 (i+vec3 (0 ,0 ,1 )), n101 = hash3 (i+vec3 (1 ,0 ,1 ));
float n011 = hash3 (i+vec3 (0 ,1 ,1 )), n111 = hash3 (i+vec3 (1 ,1 ,1 ));
return mix (mix (mix (n000,n100,f.x), mix (n010,n110,f.x), f.y),
mix (mix (n001,n101,f.x), mix (n011,n111,f.x), f.y), f.z);
}
float fbm3 (vec3 p){
float s = 0.0 , a = 0.5 ;
for (int i = 0 ; i < 6 ; i++){ s += a*noise3 (p); p = p*2.03 + 11.1 ; a *= 0.5 ; }
return s;
}
mat3 rotY (float a){ float c=cos (a), s=sin (a); return mat3 (c,0 ,-s, 0 ,1 ,0 , s,0 ,c); }
mat3 rotX (float a){ float c=cos (a), s=sin (a); return mat3 (1 ,0 ,0 , 0 ,c,-s, 0 ,s,c); }
void main (){
vec2 uv = (2.0 *gl_FragCoord .xy - RENDERSIZE .xy) / RENDERSIZE .y;
uv /= zoom;
float ph = fract (TIME * speed / PERIOD);
float th = TAU * ph;
vec3 ro = vec3 (0.0 , 0.0 , 3.0 );
vec3 rd = normalize (vec3 (uv, -1.7 ));
vec3 sun = normalize (vec3 (0.75 , 0.35 , 0.45 ));
float R = 1.0 ;
float b = dot (ro, rd);
float c = dot (ro, ro) - R*R;
float disc = b*b - c;
vec3 col = vec3 (0.0 );
vec3 sdir = rd;
float st = hash3 (floor (sdir*220.0 ));
col += vec3 (0.8 ,0.85 ,1.0 ) * smoothstep (0.9965 , 1.0 , st) * 0.9 ;
col += vec3 (0.02 ,0.02 ,0.05 );
mat3 spin = rotX (0.42 ) * rotY (-th);
if (disc > 0.0 ){
float t = -b - sqrt (disc);
vec3 pos = ro + rd*t;
vec3 n = normalize (pos);
vec3 sp = spin * n;
float h = fbm3 (sp*2.4 );
float land = smoothstep (sea-0.02 , sea+0.04 , h);
float elev = (h - sea) / max (0.001 , 1.0 - sea);
vec3 ocean = mix (vec3 (0.01 ,0.05 ,0.18 ), vec3 (0.04 ,0.22 ,0.42 ), smoothstep (0.0 ,1.0 ,h/sea));
vec3 lowland = vec3 (0.10 , 0.32 , 0.10 );
vec3 highland= vec3 (0.36 , 0.30 , 0.16 );
vec3 snow = vec3 (0.9 , 0.92 , 0.95 );
vec3 ground = mix (lowland, highland, smoothstep (0.1 , 0.5 , elev));
ground = mix (ground, snow, smoothstep (0.55 , 0.8 , elev) + smoothstep (0.75 , 0.95 , abs (sp.y)));
vec3 surf = mix (ocean, ground, land);
vec3 cp = rotY (-th*2.0 ) * (rotX (0.42 )*n);
float cl = smoothstep (0.55 , 0.85 , fbm3 (cp*3.1 + 5.0 )) * clouds;
float diff = dot (n, sun);
float day = smoothstep (-0.1 , 0.25 , diff);
vec3 h2 = normalize (sun - rd);
float spec = pow (max (dot (n, h2), 0.0 ), 40.0 ) * (1.0 - land);
vec3 lit = surf * (0.05 + 1.05 *max (diff, 0.0 ));
lit += vec3 (1.0 , 0.95 , 0.8 ) * spec * day * 1.2 ;
lit = mix (lit, vec3 (0.95 ,0.97 ,1.0 )*(0.1 +max (diff,0.0 )), cl);
float night = smoothstep (0.15 , -0.15 , diff);
float cityMask = step (0.86 , hash3 (floor (sp*60.0 ))) * land;
lit += vec3 (1.0 , 0.7 , 0.3 ) * cityMask * night * 1.4 ;
lit += vec3 (0.6 ,0.3 ,0.1 ) * land * night * 0.03 ;
float rim = pow (1.0 - max (dot (n, -rd), 0.0 ), 3.0 );
lit += vec3 (0.25 , 0.5 , 1.0 ) * rim * (0.3 + 0.9 *day) * 1.3 ;
col = lit;
} else {
float perp = sqrt (max (0.0 , dot (ro,ro) - b*b));
float halo = smoothstep (1.35 , R, perp) * step (R, perp);
vec3 limbDir = normalize (ro + rd*(-b));
float lit = smoothstep (-0.2 , 0.6 , dot (limbDir, sun));
col += vec3 (0.2 , 0.45 , 1.0 ) * halo * (0.2 + 0.9 *lit) * 1.1 ;
}
col = col / (1.0 + col);
col = pow (col, vec3 (0.85 ));
gl_FragColor = vec4 (col, 1.0 );
}