Files
fps_project_1/addons/terrain_3d/extras/hex_grid.gdshaderinc
2025-03-31 14:14:50 -05:00

67 lines
2.1 KiB
Plaintext

// Copyright © 2025 Cory Petkovsek, Roope Palmroos, and Contributors.
// This shader snippet draws a hex grid
// To use it, add this line to the top of your shader:
// #include "res://addons/terrain_3d/extras/hex_grid.gdshaderinc"
// And this line at the bottom of your shader:
// draw_hex_grid(uv2, _region_texel_size, w_normal, ALBEDO);
mat2 rotate2d(float _angle) {
return mat2(vec2(cos(_angle),-sin(_angle)), vec2(sin(_angle), cos(_angle)));
}
void draw_hex_grid(vec2 uv, float texel_size, vec3 normal, inout vec3 albedo) {
float hex_size = 0.02;
float line_thickness = 0.04;
vec2 guv = (uv - vec2(0.5 * texel_size)) / hex_size;
// Convert UV to axial hex coordinates
float q = (sqrt(3.0) / 3.0 * guv.x - 1.0 / 3.0 * guv.y);
float r = (2.0 / 3.0 * guv.y);
// Cube coordinates for the hex (q, r, -q-r)
float x = q;
float z = r;
float y = -x - z;
// Round to the nearest hex center
vec3 rounded = round(vec3(x, y, z));
vec3 diff = abs(vec3(x, y, z) - rounded);
// Fix rounding errors
if (diff.x > diff.y && diff.x > diff.z) {
rounded.x = -rounded.y - rounded.z;
} else if (diff.y > diff.z) {
rounded.y = -rounded.x - rounded.z;
} else {
rounded.z = -rounded.x - rounded.y;
}
// Find the hex center in UV space
vec2 hex_center = vec2(
sqrt(3.0) * rounded.x + sqrt(3.0) / 2.0 * rounded.z,
3.0 / 2.0 * rounded.z
);
// Relative position within the hex
vec2 local_pos = guv - hex_center;
vec2 lines_uv = local_pos;
float line = 1.0;
for (int i = 0; i < 6; i++) {
vec2 luv = lines_uv * rotate2d(radians(60.0 * float(i) + 30.0));
float dist = abs(dot(luv + vec2(0.90), vec2(0.0, 1.0)));
line = min(line, dist);
}
// Filter lines by slope
float slope = 4.; // Can also assign to (auto_slope * 4.) to match grass placement
float slope_factor = clamp(dot(vec3(0., 1., 0.), slope * (normal - 1.) + 1.), 0., 1.);
// Draw hex grid
albedo = mix(albedo, vec3(1.0), smoothstep(line_thickness + 0.02, line_thickness, line) * slope_factor);
// Draw Hex center dot
albedo = mix(albedo, vec3(0.0, 0.5, 0.5), smoothstep(0.11, 0.10, length(local_pos)) * slope_factor);
}