Cloud
GLSL Shader
Cloud
Shader loading...
View Source Code
// Cloud shader effect
// Based on volumetric rendering techniques
// Constants to control cloud appearance
#define ITERATIONS 60
#define CLOUD_DENSITY 0.65
#define CLOUD_SPEED 0.15
#define CLOUD_SCALE 2.5
#define CLOUD_DETAIL 2.8
#define CLOUD_HEIGHT 0.4
// Noise function for cloud generation
float noise(vec3 p) {
vec3 i = floor(p);
vec3 f = fract(p);
f = f * f * (3.0 - 2.0 * f);
// Hash function
vec2 uv = (i.xy + vec2(37.0, 17.0) * i.z) + f.xy;
float a = fract(sin(uv.x * 7.5 + uv.y * 3.14) * 753.57);
float b = fract(sin((uv.x + 1.0) * 7.5 + uv.y * 3.14) * 753.57);
float c = fract(sin(uv.x * 7.5 + (uv.y + 1.0) * 3.14) * 753.57);
float d = fract(sin((uv.x + 1.0) * 7.5 + (uv.y + 1.0) * 3.14) * 753.57);
return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);
}
// Fractal Brownian Motion for more detailed clouds
float fbm(vec3 p) {
float f = 0.0;
float weight = 0.5;
float scale = 1.0;
for (int i = 0; i < 5; i++) {
f += weight * noise(p * scale);
weight *= 0.5;
scale *= 2.0;
}
return f;
}
// Main cloud function
float cloudDensity(vec3 p) {
// Adjust height for cloud formation
float height = smoothstep(0.0, CLOUD_HEIGHT, p.y);
height *= smoothstep(1.0, 0.7, p.y);
// Add time-based movement
p.xz += u_time * CLOUD_SPEED;
// Generate cloud pattern
float noise = fbm(p * CLOUD_SCALE);
noise = pow(noise, CLOUD_DETAIL);
return noise * height * CLOUD_DENSITY;
}
// Color functions
vec3 skyColor(vec3 rayDir) {
float sunAmount = max(dot(rayDir, normalize(vec3(0.2, 0.6, 0.3))), 0.0);
vec3 skyCol = mix(vec3(0.3, 0.5, 0.9), vec3(0.8, 0.9, 1.0), rayDir.y * 0.5 + 0.5);
vec3 sunCol = vec3(1.0, 0.8, 0.4);
return mix(skyCol, sunCol, pow(sunAmount, 8.0));
}
void main() {
// Normalized coordinates
vec2 uv = gl_FragCoord.xy / u_resolution.xy;
uv = uv * 2.0 - 1.0;
uv.x *= u_resolution.x / u_resolution.y;
// Ray setup - camera position and direction
vec3 rayOrigin = vec3(0.0, 1.0, -5.0);
vec3 rayDir = normalize(vec3(uv, 1.0));
// Ray marching parameters
float stepSize = 0.1;
float transmittance = 1.0;
vec3 color = vec3(0.0);
// Cloud space transformation
mat3 cloudSpace = mat3(
cos(u_time * 0.05), 0.0, sin(u_time * 0.05),
0.0, 1.0, 0.0,
-sin(u_time * 0.05), 0.0, cos(u_time * 0.05)
);
// Cloud ray marching
for (int i = 0; i < ITERATIONS; i++) {
// Current position along ray
vec3 pos = rayOrigin + rayDir * float(i) * stepSize;
// Transform to cloud space
vec3 cloudPos = cloudSpace * pos;
// Sample cloud density at this position
float density = cloudDensity(cloudPos);
// Skip empty space
if (density > 0.01) {
// Light scattering calculation
float lightDensity = cloudDensity(cloudPos + vec3(0.3, 0.5, 0.2));
float lightFactor = exp(-lightDensity * 2.0);
// Cloud lighting colors
vec3 cloudColor = mix(
vec3(0.8, 0.8, 0.9), // Base cloud color
vec3(1.0, 0.9, 0.8), // Lit cloud color
lightFactor
);
// Accumulate color with transmittance
color += cloudColor * density * stepSize * transmittance;
// Reduce transmittance (more opaque)
transmittance *= exp(-density * stepSize * 2.0);
// Exit early if nearly opaque
if (transmittance < 0.01) {
break;
}
}
}
// Mix with sky background
vec3 backgroundColor = skyColor(rayDir);
color = color + backgroundColor * transmittance;
// Output final color
gl_FragColor = vec4(color, 1.0);
}