Kelsidavis-WoWee/assets/shaders/clouds.frag.glsl

64 lines
1.5 KiB
Text
Raw Normal View History

#version 450
layout(push_constant) uniform Push {
vec4 cloudColor;
float density;
float windOffset;
} push;
layout(location = 0) in vec3 vWorldDir;
layout(location = 0) out vec4 outColor;
float hash(vec2 p) {
return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);
}
float noise(vec2 p) {
vec2 i = floor(p);
vec2 f = fract(p);
f = f * f * (3.0 - 2.0 * f);
float a = hash(i);
float b = hash(i + vec2(1.0, 0.0));
float c = hash(i + vec2(0.0, 1.0));
float d = hash(i + vec2(1.0, 1.0));
return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);
}
float fbm(vec2 p) {
float val = 0.0;
float amp = 0.5;
for (int i = 0; i < 4; i++) {
val += amp * noise(p);
p *= 2.0;
amp *= 0.5;
}
return val;
}
void main() {
vec3 dir = normalize(vWorldDir);
float altitude = dir.z; // Z is up in the Z-up world coordinate system
if (altitude < 0.0) discard;
vec2 uv = dir.xy / (altitude + 0.001); // XY is the horizontal plane
uv += push.windOffset;
float cloud1 = fbm(uv * 0.8);
float cloud2 = fbm(uv * 1.6 + 5.0);
float cloud = cloud1 * 0.7 + cloud2 * 0.3;
cloud = smoothstep(0.35, 0.65, cloud) * push.density;
float edgeBreak = noise(uv * 4.0);
cloud *= smoothstep(0.2, 0.5, edgeBreak);
float horizonFade = smoothstep(0.0, 0.15, altitude);
cloud *= horizonFade;
float edgeSoftness = smoothstep(0.0, 0.3, cloud);
float alpha = cloud * edgeSoftness;
if (alpha < 0.01) discard;
outColor = vec4(push.cloudColor.rgb, alpha);
}