The Best Darn Grid Shader (Yet) for Godot

Copy of shader from this cool guy!)

https://bgolus.medium.com/the-best-darn-grid-shader-yet-727f9278b9d8

Shader code
shader_type spatial;

uniform int scale_0 : hint_range(1, 1024, 1);
uniform int scale_1 : hint_range(1, 1024, 1);

uniform float line_scale_0 : hint_range(0.001, 1, 0.001);
uniform float line_scale_1 : hint_range(0.001, 1, 0.001);

uniform vec4 color_0 : source_color;
uniform vec4 color_1 : source_color;


float pristineGrid( vec2 uv, vec2 lineWidth)
{
    vec2 ddx = dFdx(uv);
    vec2 ddy = dFdy(uv);
	
    vec2 uvDeriv = vec2(length(vec2(ddx.x, ddy.x)), length(vec2(ddx.y, ddy.y)));
    bvec2 invertLine = bvec2(lineWidth.x > 0.5, lineWidth.y > 0.5);
	
    vec2 targetWidth = vec2(
      invertLine.x ? 1.0 - lineWidth.x : lineWidth.x,
      invertLine.y ? 1.0 - lineWidth.y : lineWidth.y
      );
	
    vec2 drawWidth = clamp(targetWidth, uvDeriv, vec2(0.5));
    vec2 lineAA = uvDeriv * 1.5;
    vec2 gridUV = abs(fract(uv) * 2.0 - 1.0);
	
    gridUV.x = invertLine.x ? gridUV.x : 1.0 - gridUV.x;
    gridUV.y = invertLine.y ? gridUV.y : 1.0 - gridUV.y;
	
    vec2 grid2 = smoothstep(drawWidth + lineAA, drawWidth - lineAA, gridUV);

    grid2 *= clamp(targetWidth / drawWidth, 0.0, 1.0);
    grid2 = mix(grid2, targetWidth, clamp(uvDeriv * 2.0 - 1.0, 0.0, 1.0));
    grid2.x = invertLine.x ? 1.0 - grid2.x : grid2.x;
    grid2.y = invertLine.y ? 1.0 - grid2.y : grid2.y;
    return mix(grid2.x, 1.0, grid2.y);
}

void vertex() 
{
	//UV = VERTEX.xz;
}

void fragment() 
{
	vec3 grid_0 = vec3(pristineGrid(UV * float(scale_0), vec2(line_scale_0)));
	vec3 grid_1 = vec3(pristineGrid(UV * float(scale_1), vec2(line_scale_1)));
	
	vec3 grid_3 = mix(grid_1 * color_1.rgb, grid_0 * color_0.rgb, grid_0);
	
	ALBEDO =  grid_3;
}
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

Dashed Grid (The Best Darn Grid Shader (Yet))

world coordinates grid b&w shader

Grid shader tutorial

Subscribe
Notify of
guest

4 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
von
von
1 year ago

could you upload the complete godot project?
thanks!

1337GameDev
1337GameDev
1 year ago

I added ability to set a background color, as well as alpha channel.

shader_type spatial;

uniform int scale_0 : hint_range(1, 1024, 1);
uniform int scale_1 : hint_range(1, 1024, 1);

uniform float line_scale_0 : hint_range(0.001, 1, 0.001);
uniform float line_scale_1 : hint_range(0.001, 1, 0.001);

uniform vec4 color_0 : source_color;
uniform vec4 color_1 : source_color;

uniform vec4 background_color : source_color;

float pristineGrid( vec2 uv, vec2 lineWidth)
{
  vec2 ddx = dFdx(uv);
  vec2 ddy = dFdy(uv);
	
  vec2 uvDeriv = vec2(length(vec2(ddx.x, ddy.x)), length(vec2(ddx.y, ddy.y)));
  bvec2 invertLine = bvec2(lineWidth.x > 0.5, lineWidth.y > 0.5);
	
  vec2 targetWidth = vec2(
   invertLine.x ? 1.0 - lineWidth.x : lineWidth.x,
   invertLine.y ? 1.0 - lineWidth.y : lineWidth.y
   );
	
  vec2 drawWidth = clamp(targetWidth, uvDeriv, vec2(0.5));
  vec2 lineAA = uvDeriv * 1.5;
  vec2 gridUV = abs(fract(uv) * 2.0 - 1.0);
	
  gridUV.x = invertLine.x ? gridUV.x : 1.0 - gridUV.x;
  gridUV.y = invertLine.y ? gridUV.y : 1.0 - gridUV.y;
	
  vec2 grid2 = smoothstep(drawWidth + lineAA, drawWidth - lineAA, gridUV);

  grid2 *= clamp(targetWidth / drawWidth, 0.0, 1.0);
  grid2 = mix(grid2, targetWidth, clamp(uvDeriv * 2.0 - 1.0, 0.0, 1.0));
  grid2.x = invertLine.x ? 1.0 - grid2.x : grid2.x;
  grid2.y = invertLine.y ? 1.0 - grid2.y : grid2.y;
  return mix(grid2.x, 1.0, grid2.y);
}

void vertex() 
{
	//UV = VERTEX.xz;
}

void fragment() 
{
	vec4 grid_0 = vec4(pristineGrid(UV * float(scale_0), vec2(line_scale_0)));
	vec4 grid_1 = vec4(pristineGrid(UV * float(scale_1), vec2(line_scale_1)));
	
	//calculate color given both grid colors mixed
	//pristineGrid returns 0 or 1, so it'll choose one grid color or the other
	vec4 gridsMixed = mix(grid_1 * color_1.rgba, grid_0 * color_0.rgba, grid_0);
	//whether we are drawing the background (1.0) or either grid (0.0)
	float drawBackground = clamp(1.0 - (1.0 * (grid_0.r + grid_1.r)), 0.0, 1.0);
	
	//mix colors of either grid and background, based on what we are drawing
	vec4 finalColorToDraw = mix(gridsMixed, background_color, drawBackground);
	ALBEDO = finalColorToDraw.rgb;
	ALPHA = finalColorToDraw.a;
}
TheYellowArchitect
1 month ago
Reply to  1337GameDev

This makes the shader great, background color and alpha channel is much-needed. Though the peak improvement would be a 5×4 grid having lines match 5×4 instead of 5×5 or 4×4

TheYellowArchitect
1 month ago

A 5×4 grid, has lines matching 5×5 or 4×4 feelsbadman