Procedural Hexagonal Pattern

It”s not a shader, it”s just an algorithm for creating a HEX pattern for your textures2D

Shader code
shader_type spatial;
render_mode blend_mix, depth_draw_opaque, cull_back, diffuse_lambert, specular_schlick_ggx;

uniform vec2 hex_grid_density = vec2(6.0, 6.0); // количество ячеек
uniform float hex_cell_size = 1.0;              // размер гекса
uniform float hex_focus = 6.0;                  // фокусировка цвета внутри гекса

void fragment() {
	vec2 uv = UV;

	// Переворот Y-координаты UV
	vec2 flipped_uv = vec2(uv.x, 1.0 - uv.y);

	// Масштабирование под hex-сетку
	vec2 grid_uv = flipped_uv * hex_grid_density;

	// Коэффициенты преобразования
	float sqrt3_div2 = 1.732 / 2.0;
	float inv_sqrt3 = 1.0 / (1.732);

	float axial_x = grid_uv.x - grid_uv.y * (sqrt3_div2 / 1.5);
	float axial_y = grid_uv.y * inv_sqrt3;
	vec2 axial_coords = vec2(axial_x, axial_y);

	// Нормализация относительно размера клетки
	vec2 cell_coords = axial_coords / vec2(hex_cell_size);
	vec2 floored_coords = floor(cell_coords);

	float cell_diff = floored_coords.x - floored_coords.y;

	// Вспомогательный вектор
	vec3 offsets = vec3(0.0, 1.0, 2.0);
	vec3 temp = vec3(cell_diff) + offsets;

	// Нормализация
	vec3 normalized = temp * vec3(1.0 / 3.0);
	normalized += vec3(2.0 / 3.0);

	// Получаем индексы вершин гексагона
	vec3 hex_index = round(fract(normalized));
	float i0 = hex_index.x;
	float i1 = hex_index.y;
	float i2 = hex_index.z;

	// Подготовка векторов для dot product'ов
	vec3 axis0 = vec3(i2, i0, i1);
	vec3 axis1 = vec3(i1, i2, i0);
	vec3 axis2 = vec3(i0, i1, i2);

	// Получаем локальные координаты внутри клетки
	vec2 local_coords = fract(cell_coords);
	float sum_coords = local_coords.x + local_coords.y;
	float abs_dist = abs(sum_coords - 1.0);

	bool flip_needed = (sum_coords - 1.0) > 0.0;

	vec2 flipped_coords = vec2(1.0) - vec2(local_coords.y, local_coords.x);
	vec2 chosen_coords = mix(local_coords, flipped_coords, float(flip_needed));

	vec3 influence = vec3(abs_dist, chosen_coords.x, chosen_coords.y);

	// Вычисляем веса влияния
	float w0 = dot(axis0, influence);
	float w1 = dot(axis1, influence);
	float w2 = dot(axis2, influence);
	vec3 weights = vec3(w0, w1, w2);

	// Усиление акцента с помощью степени
	vec3 focused_weights = pow(weights, vec3(hex_focus));

	// Нормализация
	float total = dot(focused_weights, vec3(1.0));
	vec3 final_color = focused_weights / vec3(total);

	ALBEDO = final_color;
}
Live Preview
Tags
Algorithm, grid, hex, Procedural, repetition, Terrain3D, tiles, Tilting, VisualShader
The shader code and all code snippets in this post are under CC0 license and can be used freely without the author's permission. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

More from Riko

Related shaders

guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments