Halloween is around the corner and I may have something to help you decorating, if you have a spare projector to aim at some bushes or a spare display to hide behind something translucent.

I hereby release this video under the CC0 license, which means you can use it any way you like.

The video was created using a self-written shader inside Godot Engine on public domain silhouette pictures from Pixabay, which were converted to a signed distance field texture by my good old sdfgen (which was my first Rust-lang project by the way).

This is how it looks projected onto a bush.

Thanks to all the awesome artists, who release assets under free licenses. These are the artworks used in the video.

This is the shader source code.

shader_type canvas_item;

const float BRIGHTNESS_DST = 0.002;
const float TIME_DST = 0.2;
const float TIME_MULTIPLIER = 0.1;
const vec4 COLOR_INNER = vec4(1.0, 1.0, 1.0, 1.0);
const vec4 COLOR_OUTER = vec4(0.0, 0.0, 0.0, 1.0);

uniform sampler2D noise;

float gradient(float x, float dst) {
	if (x < (0.5 - dst)) {
		return 0.0;
	} else if (x > (0.5 + dst)) {
		return 1.0;
	}
	return (x-(0.5 - dst)) / (2.0 * dst);
}

vec2 offset(int id) {
	int y = id / 3;
	int x = id % 3;
	return vec2(float(x) * 0.25, float(y) * 0.25);
}

void fragment() {
	int id = int(TIME * TIME_MULTIPLIER) % 9;
	int nextid = (id + 1) % 9;
	float subtimeRaw = fract(TIME * TIME_MULTIPLIER);
	float subtime = gradient(subtimeRaw, TIME_DST);
	float t1 = texture(TEXTURE, UV * vec2(0.25, 0.25) + offset(id)).r;
	float t2 = texture(TEXTURE, UV * vec2(0.25, 0.25) + offset(nextid)).r;
	float triag = 1.0 - abs(2.0 * subtime - 1.0);
	float noiseF =  ((texture(noise, UV + (vec2(0.0,1.0) * (TIME * TIME_MULTIPLIER * 2.0))).r) - 0.5) * (triag * 0.5 + 0.5) * 0.1;
	float brightness = gradient(mix(t1, t2, subtime) + noiseF, mix(BRIGHTNESS_DST, 0.01, triag));
	COLOR = mix(COLOR_INNER, COLOR_OUTER, brightness);
}

The input “TEXTURE” is nine 1024x1024 signed distance fields arranged in a 3x3 grid in the top left of a 4096x4096 texture. The input “noise” is a standard noise texture provided by the Godot engine.

I hope you like the video and find a good use for it. Happy Halloween!