81 lines
2.8 KiB
Text
81 lines
2.8 KiB
Text
|
shader_type canvas_item;
|
||
|
|
||
|
// Noise texture.
|
||
|
uniform sampler3D noise: repeat_enable;
|
||
|
|
||
|
// Planet.
|
||
|
uniform float size = 100.; // Size in pixels, not including atmosphere.
|
||
|
uniform float rotationSpeed = 0.05;
|
||
|
uniform sampler2D albedo; // Left side = water color (deep to shallow), right size = terrain color (low to high).
|
||
|
|
||
|
// Atmosphere.
|
||
|
uniform vec4 atmosphereColor: source_color = vec4(0., .3, 1., .3);
|
||
|
uniform float atmosphereSize = .3; // Range: [0, 1]
|
||
|
|
||
|
// Weather.
|
||
|
uniform float cloudsSize = 0.05;
|
||
|
uniform float cloudsDensity = 0.22;
|
||
|
uniform float cloudsTurbulence = 0.01;
|
||
|
uniform float windSpeed = 0.03;
|
||
|
|
||
|
// Zoom level assuming a planet of normalized size.
|
||
|
varying float zoom;
|
||
|
|
||
|
void vertex() {
|
||
|
zoom = 4. / (size * CANVAS_MATRIX[0][0]);
|
||
|
}
|
||
|
|
||
|
vec4 blend(vec4 bg, vec4 fg) {
|
||
|
float alpha = fg.a + bg.a * (1. - fg.a);
|
||
|
vec3 color = (fg.rgb * fg.a + bg.rgb * bg.a * (1. - fg.a)) / alpha;
|
||
|
return vec4(color, alpha);
|
||
|
}
|
||
|
|
||
|
vec4 drawPlanet(float r, vec3 p) {
|
||
|
float angle = TIME * rotationSpeed;
|
||
|
//mat3 rotX = mat3(vec3(1., 0., 0.), vec3(0., cos(angle), -sin(angle)), vec3(0., sin(angle), cos(angle)));
|
||
|
mat3 rotY = mat3(vec3(cos(angle), 0., -sin(angle)), vec3(0., 1., 0.), vec3(sin(angle), 0., cos(angle)));
|
||
|
//mat3 rotZ = mat3(vec3(cos(angle), -sin(angle), 0.), vec3(sin(angle), cos(angle), 0.), vec3(0., 0., 1.));
|
||
|
|
||
|
float height = texture(noise, p * 0.3 * rotY).r;
|
||
|
float rand = texture(noise, p * 0.3 * rotY + vec3(0.1, 0.2, 0.3)).r * .5 + .5;
|
||
|
//float rand = texture(noise, p + vec3(n + TIME * 0.02)).r;
|
||
|
|
||
|
vec3 color = texture(albedo, vec2(height, ((p.y + rand * sign(p.y)) * .5 + 1.) * .5)).rgb;
|
||
|
vec3 lit = max(vec3(0.), color * dot(p, vec3(0., 0., 1.)));
|
||
|
|
||
|
return vec4(lit, smoothstep(0., zoom, r));
|
||
|
}
|
||
|
|
||
|
vec4 drawClouds(float r, vec3 p) {
|
||
|
float angle = TIME * 0.08;
|
||
|
mat3 rotY = mat3(vec3(cos(angle), 0., -sin(angle)), vec3(0., 1., 0.), vec3(sin(angle), 0., cos(angle)));
|
||
|
|
||
|
float angle2 = TIME * (rotationSpeed - windSpeed);
|
||
|
mat3 rotY2 = mat3(vec3(cos(angle2), 0., -sin(angle2)), vec3(0., 1., 0.), vec3(sin(angle2), 0., cos(angle2)));
|
||
|
|
||
|
float rand = texture(noise, p * 0.5 * rotY2 + vec3(0., 0., TIME * cloudsTurbulence)).r * .5 + .5;
|
||
|
float rand2 = texture(noise, p * 0.8 * rotY2 + vec3(0., 0., rand)).r * .5 + .5;
|
||
|
|
||
|
return vec4(vec3(1.), smoothstep(1. - cloudsDensity - cloudsSize, 1. - cloudsSize, rand2) * smoothstep(0., .3, r * 3.));
|
||
|
}
|
||
|
|
||
|
vec4 drawAtmosphere(float r) {
|
||
|
return vec4(atmosphereColor.rgb, smoothstep(1.-atmosphereSize, 1., r + 1.) * atmosphereColor.a);
|
||
|
}
|
||
|
|
||
|
void fragment() {
|
||
|
float r = length(UV - .25) * -8. + 1.;
|
||
|
vec2 xy = UV * 8. - 2.;
|
||
|
float z = sqrt(1. - xy.x*xy.x - xy.y*xy.y);
|
||
|
vec3 p = vec3(xy, z);
|
||
|
|
||
|
vec4 atmosphere = drawAtmosphere(r);
|
||
|
vec4 planet = drawPlanet(r, p);
|
||
|
vec4 clouds = drawClouds(r, p);
|
||
|
COLOR = blend(blend(atmosphere, planet), clouds);
|
||
|
|
||
|
// DEBUG
|
||
|
//COLOR = vec4(p, smoothstep(0., zoom, r));
|
||
|
}
|