OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-tps / addons / sky3d_extended / shaders / noise.gdshaderinc

70 lines · gdshaderinc ref:
// Shared procedural noise functions for cloud rendering
// Hash-based (no texture dependency) - suitable for GPU evaluation

// --- Hash functions ---

float hash21(vec2 p) {
	// High-quality hash using 3-component mixing (same family as hash22)
	vec3 p3 = fract(vec3(p.xyx) * vec3(0.1031, 0.1030, 0.0973));
	p3 += dot(p3, p3.yzx + 33.33);
	return fract((p3.x + p3.y) * p3.z);
}

vec2 hash22(vec2 p) {
	vec3 p3 = fract(vec3(p.xyx) * vec3(0.1031, 0.1030, 0.0973));
	p3 += dot(p3, p3.yzx + 33.33);
	return fract((p3.xx + p3.yz) * p3.zy);
}

// --- Value noise ---

float value_noise(vec2 p) {
	vec2 i = floor(p);
	vec2 f = fract(p);
	// Quintic interpolation (C2 continuous — no visible grid artifacts)
	f = f * f * f * (f * (f * 6.0 - 15.0) + 10.0);

	float a = hash21(i);
	float b = hash21(i + vec2(1.0, 0.0));
	float c = hash21(i + vec2(0.0, 1.0));
	float d = hash21(i + vec2(1.0, 1.0));

	return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);
}

// --- Worley noise (cellular) ---

float worley_noise(vec2 p) {
	vec2 i = floor(p);
	vec2 f = fract(p);
	float min_dist = 1.0;

	for (int y = -1; y <= 1; y++) {
		for (int x = -1; x <= 1; x++) {
			vec2 neighbor = vec2(float(x), float(y));
			vec2 point = hash22(i + neighbor);
			vec2 diff = neighbor + point - f;
			min_dist = min(min_dist, length(diff));
		}
	}
	return min_dist;
}

// --- Voronoi noise ---

float voronoi_noise(vec2 p) {
	vec2 i = floor(p);
	vec2 f = fract(p);
	float min_dist = 1.0;

	for (int y = -1; y <= 1; y++) {
		for (int x = -1; x <= 1; x++) {
			vec2 neighbor = vec2(float(x), float(y));
			vec2 point = hash22(i + neighbor);
			float d = length(neighbor + point - f);
			min_dist = min(min_dist, d);
		}
	}
	return min_dist;
}