website/assets/shaders/sky.wgsl

50 lines
1.4 KiB
WebGPU Shading Language
Raw Normal View History

2026-09-28 21:50:36 +00:00
#import bevy_sprite::mesh2d_vertex_output::VertexOutput
#import bevy_sprite::mesh2d_view_bindings::globals
fn hash(p: vec2<f32>) -> f32 {
return fract(sin(dot(p, vec2<f32>(127.1, 311.7))) * 43758.5453);
}
fn noise(p: vec2<f32>) -> f32 {
let i = floor(p);
let f = fract(p);
let u = f * f * (3.0 - 2.0 * f);
return mix(
mix(hash(i), hash(i + vec2<f32>(1.0, 0.0)), u.x),
mix(hash(i + vec2<f32>(0.0, 1.0)), hash(i + vec2<f32>(1.0, 1.0)), u.x),
u.y,
);
}
fn fbm(p: vec2<f32>) -> f32 {
var value = 0.0;
var amplitude = 0.5;
var q = p;
for (var i = 0; i < 5; i++) {
value += amplitude * noise(q);
q *= 2.0;
amplitude *= 0.5;
}
return value;
}
@fragment
fn fragment(mesh: VertexOutput) -> @location(0) vec4<f32> {
let t = globals.time;
// uv.y is 0 at the top of the quad
let height = 1.0 - mesh.uv.y;
let horizon = vec3<f32>(0.98, 0.85, 0.72);
let zenith = vec3<f32>(0.45, 0.68, 0.92);
var color = mix(horizon, zenith, smoothstep(0.0, 1.0, height));
// Two layers of slowly drifting clouds
let p = mesh.world_position.xy / 300.0;
let clouds = fbm(p + vec2<f32>(t * 0.03, 0.0)) * 0.6
+ fbm(p * 2.0 + vec2<f32>(t * 0.05, t * 0.01)) * 0.4;
let cover = smoothstep(0.45, 0.75, clouds);
color = mix(color, vec3<f32>(1.0), cover * 0.8);
return vec4<f32>(color, 1.0);
}