Going further than the tutorial:
- Added the horizon color effects
- Changed the moon
- Added a little changes to things like the stars
Live Version:
Try clicking and dragging with your mouse!
GLSL / ShaderToy Code
#define S(a, b, t) smoothstep(a, b, t)
float createTaperBox(vec2 point, float bottomWidth, float topWidth, float yBottom, float yTop, float blur) {
// Bottom edge
float m = S(-blur, blur, point.y - yBottom);
// Top edge
m *= S(blur, -blur, point.y - yTop);
// Sides, mirrored
point.x = abs(point.x);
float w = mix(bottomWidth, topWidth, (point.y - yBottom) / (yTop - yBottom));
m *= S(blur, -blur, point.x - w);
return m;
}
vec4 createTree(vec2 uv, vec3 color, float blur) {
// --- Trunk ---
float m = createTaperBox(uv, 0.03, 0.03, -0.05, 0.25, blur);
// --- Canopy 1 ---
m += createTaperBox(uv, 0.2, 0.1, 0.25, 0.5, blur);
// --- Canopy 2 ---
m += createTaperBox(uv, 0.15, 0.05, 0.5, 0.75, blur);
// --- Top ---
m += createTaperBox(uv, 0.1, 0.0, 0.75, 1.0, blur);
float shadow = createTaperBox(uv - vec2(0.2, 0.0), 0.1, 0.5, 0.15, 0.25, blur);
shadow += createTaperBox(uv + vec2(0.25, 0.0), 0.1, 0.5, 0.45, 0.5, blur);
shadow += createTaperBox(uv - vec2(0.2, 0.0), 0.1, 0.5, 0.7, 0.75, blur);
color -= shadow * 0.8;
//m = 1.0;
return vec4(color, m);
}
float GetHeight(float x) {
return sin(x * 0.435) + sin(x) * 0.3;
}
vec4 createLayer(vec2 uv, float blur) {
vec4 color = vec4(0.0);
float id = floor(uv.x);
float n = fract(sin(id * 256.12) * 6854.3) * 2.0 - 1.0;
float x = n * 0.3;
float y = GetHeight(uv.x);
// Ground
float ground = S(blur, -blur, uv.y + y);
color += ground;
y = GetHeight(id + 0.5 + x);
uv.x = fract(uv.x) - 0.5;
vec4 tree = createTree((uv - vec2(x, -y)) * vec2(1.0, 1.0 + n * 0.25), vec3(1.0), blur);
color = mix(color, tree, tree.a);
color.a = max(ground, tree.a);
return color;
}
float Hash21(vec2 point) {
point = fract(point * vec2(1462.34, 1026.75));
point += dot(point, point + 864.23);
return fract(point.x * point.y);
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
// Normalized pixel coordinates (from 0 to 1)
// Move origin to the center
vec2 uv = (fragCoord - 0.5 * iResolution.xy) / iResolution.y;
vec2 mouse = (iMouse.xy / iResolution.xy) * 2.0 - 1.0;
float time = iTime * 0.3;
//uv.x += iTime * 0.1;
//uv.y += 0.5;
//uv *= 5.0;
float blur = 0.005;
// Initialize color
vec4 color = vec4(0.0);
vec4 layer;
color *= 0.0;
float twinkle = dot(length(sin(uv + time)), length(cos(uv * vec2(22.0, 6.7) - time * 3.0)));
twinkle = sin(twinkle * 10.0) * 0.5 + 0.5 * 4.5;
float dawn = S(-0.75, 0.4, -uv.y);
float stars = pow(Hash21(uv), 60.0 * twinkle);
color += stars;
color.rgb -= vec3(0.5, 0.9, 0.1);
color += dawn;
//float moon = S(0.01, -0.01, length(uv + vec2(-0.65, -0.275)) - 0.1);
float moon = S(0.0075, -0.0035, length(uv - vec2(0.47, 0.29)) - 0.1);
moon *= S(-0.075, 0.005, length(uv - vec2(0.43, 0.325)) - 0.175);
color.rgb += vec3(0.6);
color += moon;
for (float i = 0.0; i < 1.0; i += 1.0 / 7.0) {
float scale = mix(10.0, 1.0, i);
blur = mix(0.02, 0.005, i);
layer = createLayer(uv * scale + vec2(time + i * 50.0, i) - mouse, blur);
layer.rgb *= (1.0 - i) * vec3(0.3, 0.5, 1.0) * 1.2;
color = mix(color, layer, layer.a);
}
layer = createLayer(uv + vec2(time , 1.0) - mouse, blur * 3.0);
color = mix(color, layer * 0.002, layer.a);
float thickness = 1.0 / iResolution.y;
// See axes
//if (abs(uv.x) < thickness) { color.g = 1.0; }
//if (abs(uv.y) < thickness) { color.r = 1.0; }
// Output to screen
fragColor = color;
}
Tutorial I followed:
Resources:
ShaderToy