Live Version:
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;
}
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;
uv.x += iTime * 0.1;
//uv.y += 0.5;
uv *= 5.0;
vec4 color = vec4(0.0);
float blur = 0.005;
float id = floor(uv.x);
float n = fract(sin(id * 234.12) * 3854.3) * 2.0 - 1.0;
float x = n * 0.3;
float y = GetHeight(uv.x);
// Ground
color += S(blur, -blur, uv.y + y);
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);
// Visualize coords
//color.rb = uv;
color = mix(color, tree, tree.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