3 ^ Grid

Grid  with transform and exponential scale for proportional lines.

Shader code
shader_type canvas_item;

const vec3[4] COL_SIDE = { vec3(1.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0), vec3(1.0, 0.0, 1.0), vec3(0.0, 1.0, 1.0) };
const float GRID_SIZE = 8.0;
const float FACTOR_BASE = 3.0;

uniform vec3 color_grid : source_color = vec3(1.0);
uniform vec3 color_grid_sub : source_color = vec3(0.25);
uniform vec3 color_light : source_color = vec3(0.7, 0.7, 0.5);
uniform bool floor_grid;
uniform bool floor_light;
uniform float grid_pri_step = 3.0;
uniform float grid_sub_step = 3.0;
uniform float light_size = 8.0;
uniform float light_zoom = 1.0;
uniform float line_width = 6.0;
uniform vec2 uv_offset;
uniform float uv_rotation;
uniform float uv_scale = 8.0;

varying float calc_grid_exponent;
varying vec2 calc_grid_pow;
varying float calc_light_exponent;
varying vec2 calc_light_pow;
varying float calc_line_width;

bool get_axis(vec2 pos_abs) {
	return pos_abs.x < calc_line_width / 2.0 || pos_abs.y < calc_line_width / 2.0;
}

bool get_axis_reference_rect(vec2 pos, vec2 off) {
	vec2 pos_abs = abs(pos);
	vec2 off_abs = abs(off);
	
	return sign(pos) == sign(off)
		&& (pos_abs.x < off_abs.x && pos_abs.y < off_abs.y)
		&& (pos_abs.x > off_abs.x - calc_line_width || pos_abs.y > off_abs.y - calc_line_width);
}

bool[4] get_grids(vec2 pos) {
	float lw = calc_line_width / 2.0;
	
	vec2 a = mod(pos + lw, grid_pri_step * calc_grid_pow[0]);
	vec2 b = mod(pos + lw, grid_pri_step * calc_grid_pow[1]);
	vec2 c = mod(pos + lw, grid_pri_step / grid_sub_step * calc_grid_pow[0]);
	vec2 d = mod(pos + lw, grid_pri_step / grid_sub_step * calc_grid_pow[1]);
	
	
	return {
		a.x - lw < lw || a.y - lw < lw,
		b.x - lw < lw || b.y - lw < lw,
		c.x - lw < lw || c.y - lw < lw,
		d.x - lw < lw || d.y - lw < lw
	};
}

float get_light(vec2 pos) {
	pos = pos * light_zoom / FACTOR_BASE;
	
	vec2 a = floor(abs(mod(pos / calc_light_pow[0], light_size) - light_size / 2.0) + 0.5) / light_size;
	vec2 b = floor(abs(mod(pos / calc_light_pow[1], light_size) - light_size / 2.0) + 0.5) / light_size;
	
	return mix(mix(a.x, b.x, fract(calc_light_exponent)), mix(a.y, b.y, fract(calc_light_exponent)), 0.5);
}

float logn(float base, float argument) {
	return log(argument) / log(base);
}

vec2 rotated(vec2 v, float phi) {
	float cosi = cos(phi);
	float sine = sin(phi);
	
	return vec2(cosi * v.x + sine * v.y, cosi * v.y - sine * v.x);
}

float snap(float x, float y) {
	return round(x / y) * y;
}

void vertex() {
	// Called for every vertex the material is visible on.
	calc_grid_exponent = logn(FACTOR_BASE, max(uv_scale, GRID_SIZE) / GRID_SIZE);
	calc_grid_pow[0] = pow(FACTOR_BASE, floor(calc_grid_exponent));
	calc_grid_pow[1] = calc_grid_pow[0] * FACTOR_BASE;
	calc_light_exponent = logn(FACTOR_BASE, max(uv_scale, light_size) / (FACTOR_BASE * light_size));
	calc_light_pow[0] = pow(FACTOR_BASE, floor(calc_light_exponent));
	calc_light_pow[1] = calc_light_pow[0] * FACTOR_BASE;
	calc_line_width = line_width / 1000.0 * uv_scale;
	
	if (floor_grid) {
		calc_grid_exponent = floor(calc_grid_exponent);
	}
	if (floor_light) {
		calc_light_exponent = floor(calc_light_exponent);
	}
}

void fragment() {
	// Called for every pixel the material is visible on.
	vec2 position = rotated(UV - REGION_RECT.zw / 2.0, uv_rotation) * uv_scale + uv_offset;
	bool col_axis = get_axis(abs(position));
	bool col_axis_ref = get_axis_reference_rect(position, uv_offset);
	bool col_axis_ref0 = get_axis_reference_rect(position, -vec2(0.025 * uv_scale));
	bool[4] col_grids = get_grids(position);
	float col_light = get_light(position);
	int off_side = int(mod(snap(atan(-position.y / abs(uv_offset.y), position.x / abs(uv_offset.x)), PI / 2.0) / TAU * 4.0, 4.0));
	int pos_side = int(mod(snap(atan(-position.y, position.x), PI / 2.0) / TAU * 4.0, 4.0));
	
	COLOR.rgb = col_axis ? COL_SIDE[pos_side]
		: col_axis_ref ? COL_SIDE[off_side]
		: col_axis_ref0 ? vec3(1.0)
		: ((col_grids[0] ? color_grid : col_grids[2] ? color_grid_sub : vec3(0.0)) * (1.0 - fract(calc_grid_exponent))
			+ (col_grids[1] ? color_grid : col_grids[3] ? color_grid_sub : vec3(0.0)) * fract(calc_grid_exponent)
			+ col_light * color_light);
}

//void light() {
//	// Called for every pixel for every light affecting the CanvasItem.
//	// Uncomment to replace the default light processing function with this one.
//}
 
Live Preview
Tags
grid
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.

Related shaders

guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments