shader_type spatial; // Use global coordinate uniform bool world_uv = false; // Use the uv of the object instead of the vertex as a coordinate uniform bool object_uv = false; uniform vec2 object_uv_scale = vec2(1.0); // Render group_uniforms render; // Color preset index: 0 == disabled/custom uniform int preset_color : hint_range(0, 8, 1) = 0; uniform vec3 base_color : source_color = vec3(0.0); uniform float metalic : hint_range(0.0, 1.0, 0.001) = 0.25; uniform float roughness : hint_range(0.0, 1.0, 0.001) = 0.75; // Main grid group_uniforms grid; uniform float grid_scale = 1.0; uniform float grid_width : hint_range(0.0, 1.0, 0.001) = 0.01; uniform vec4 grid_color : source_color = vec4(vec3(0.8), 1.0); // Inside grid group_uniforms inside_grid; uniform float inside_scale : hint_range(0.0, 10.0, 1) = 1.0; uniform float inside_width : hint_range(0.0, 1.0, 0.001) = 0.01; uniform vec4 inside_color : source_color = vec4(0.8); // Checker grid group_uniforms checkered_grid; uniform bool checkered = true; uniform bool sub_checkered_grid = false; uniform vec3 checkered_color : source_color = vec3(0.25); uniform float checkered_blend_color : hint_range(0.0, 1.0, 0.001) = 0.1; // NOTE - When using texture, enable LOD generation and reimport the texture group_uniforms albedo_texture; uniform bool use_inside_uv = false; uniform bool use_albedo_color = false; uniform sampler2D albedo_texture : hint_default_transparent, filter_linear_mipmap; uniform float albedo_alpha : hint_range(0.0, 1.0, 0.001) = 0.5; // Preset colors const vec3 PRESET_COLORS[8] = { vec3(0.2, 0.2, 0.208), // Dark vec3(1.0, 0.0, 0.22), // Red vec3(1.0, 0.549, 0.0), // Orange vec3(1.0, 0.753, 0.0), // Yellow vec3(0.106, 0.851, 0.467), // Green vec3(0.318, 0.502, 0.78), // Blue vec3(0.616, 0.133, 0.98), // Purple vec3(0.827, 0.839, 0.851) // Light }; const float EPSILON = 0.0001; varying vec3 vertex_uv; varying vec3 vertex_normal; // Fix preset colors, base RAW vec3 srgb_to_linear(vec3 color) { return mix( pow((color.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), color.rgb * (1.0 / 12.92), lessThan(color.rgb, vec3(0.04045)) ); } float grid_structure(vec3 uv, float width, float mult) { vec3 uv_deriv = fwidth(uv); uv_deriv = max(uv_deriv, EPSILON); vec3 line_AA = uv_deriv * 1.5; vec3 width_value = 1.0 - vec3(width); vec3 target_width = width > 0.5 ? width_value : 1.0 - width_value; vec3 draw_width = clamp(target_width, uv_deriv, vec3(0.5)); vec3 grid_uv = abs(fract(uv * mult) * 2.0 - 1.0); grid_uv = width > 0.5 ? 1.0 - grid_uv : grid_uv; // Blend normal sides float blend_value = 1.0; vec3 blend_normal = abs(normalize(cross(dFdy(uv), dFdx(uv)))); vec3 blend_factor = smoothstep(blend_value - EPSILON, blend_value + EPSILON, blend_normal); blend_factor = width > 0.5 ? 1.0 - blend_factor : blend_factor; vec3 grid_normal_a = width > 0.5 ? vec3(-1.0) : grid_uv; vec3 grid_normal_b = width > 0.5 ? grid_uv : vec3(1.0); grid_uv = mix(grid_normal_a, grid_normal_b, blend_factor); vec3 grid_base = smoothstep(draw_width + line_AA, draw_width - line_AA, grid_uv); grid_base *= clamp(target_width / draw_width, EPSILON, 1.0); grid_base = mix(grid_base, target_width, clamp(uv_deriv * 2.0 - 1.0, EPSILON, 1.0)); grid_base = width > 0.5 ? 1.0 - grid_base : grid_base; return mix(mix(grid_base.x, 1.0, grid_base.y), 1.0, grid_base.z); } float checkered_grid(vec3 uv, float subdivide) { // Checkered grid vec3 board_uv = floor(uv - 0.5 - subdivide + EPSILON); float board = mod((board_uv.x) + (board_uv.y) + (board_uv.z), 2.0); // Blend normal sides float blend_value = 1.0; vec3 blend_normal = abs(normalize(cross(dFdy(uv), dFdx(uv)))); vec3 blend_factor = smoothstep(blend_value - EPSILON, blend_value + EPSILON, blend_normal); // Filter AA vec3 smooth_uv = abs(fract(uv - subdivide) * 2.0 - 1.0); smooth_uv = mix(smooth_uv, vec3(1.0), blend_factor); vec3 uv_deriv = fwidth(uv); uv_deriv = max(uv_deriv, EPSILON); vec3 uv_AA = uv_deriv * 4.0; float smooth_value = 1.0; float smooth_edge = smoothstep(0.0, uv_AA.x * smooth_value, smooth_uv.x); smooth_edge *= smoothstep(0.0, uv_AA.y * smooth_value, smooth_uv.y); smooth_edge *= smoothstep(0.0, uv_AA.z * smooth_value, smooth_uv.z); vec3 moire_step = smoothstep(vec3(1.0), vec3(0.0), uv_deriv); float moire_range = (moire_step.x * moire_step.y * moire_step.z); // Applay AA/Moire blend color board = mix(0.0, board, smooth_edge); board = mix(0.05, board, moire_range); return board; } vec4 triplanar_texture(sampler2D tex, vec3 uv, bool sub) { uv = sub ? uv : uv * 0.5 + 0.5; vec4 albedo_x = texture(tex, object_uv ? uv.xy : uv.zy); vec4 albedo_y = texture(tex, object_uv ? uv.xy : uv.xz); vec4 albedo_z = texture(tex, uv.xy); vec3 tri_normal = vec3(0.0); vec2 blend_normal = abs(normalize(vertex_normal.xz)); tri_normal.xz = max(vec2(0.0), blend_normal - 0.67); tri_normal.xz /= max(0.00001, dot(tri_normal.xz, vec2(1.0))); tri_normal.y = clamp((abs(vertex_normal.y) - 0.675) * 80.0, 0.0, 1.0); tri_normal.xz *= (1.0 - tri_normal.y); vec4 albedo = ( albedo_x * tri_normal.x + albedo_y * tri_normal.y + albedo_z * tri_normal.z ); return albedo; } void vertex() { vertex_normal = NORMAL; vertex_uv = mix(VERTEX, (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz, float(world_uv)); vertex_uv = mix(vertex_uv, vec3(UV * object_uv_scale, 0.0), float(object_uv)); vertex_uv *= vec3(1.0, -1.0, 1.0); } void fragment() { vec3 base_uv = vertex_uv * grid_scale; // Base Grid float base_grid = grid_structure(base_uv, grid_width, 0.5); // Inside Grid float inside_factor = mod(inside_scale, 2.0) < EPSILON ? 0.5 : 0.0; float inside_reduce = floor(inside_scale / 2.0) - (abs(inside_factor - 0.5) < EPSILON ? 1.0 : 0.0); vec3 inside_uv = base_uv * (inside_scale - inside_factor - inside_reduce); float inside_grid = grid_structure(inside_uv - (0.5 - inside_factor), inside_width, 1.0); inside_grid = inside_scale < EPSILON ? 0.0 : inside_grid; inside_grid = mix(inside_grid, 0.0, smoothstep(0.0 - EPSILON, 0.5 + EPSILON, base_grid)); // Checkerboard vec3 checker_uv = mix(base_uv / 2.0, base_uv, float(sub_checkered_grid)); float checkerboard = 0.0; checkerboard = checkered ? checkered_grid(checker_uv, sub_checkered_grid ? 0.5 : 0.0) : 0.0; // Albedo texture(triplanar) vec4 albedo = triplanar_texture( albedo_texture, use_inside_uv ? inside_uv - 0.5 - (0.5 - inside_factor) : base_uv, use_inside_uv ); // Color vec3 color = base_color; color = preset_color != 0 ? srgb_to_linear(PRESET_COLORS[preset_color - 1]) : color; // Grayscale if (use_albedo_color == false) { float gray = dot(albedo.rgb, vec3(0.299, 0.587, 0.114)); albedo.rgb = vec3(gray); } // Applay texture/base color/checkered vec3 board = mix(color, checkered_color, checkerboard * checkered_blend_color); albedo.rgb = use_albedo_color ? albedo.rgb : albedo.rgb * board; // Mix Color vec3 grid_a = mix(board, mix(board, albedo.rgb, albedo.a), albedo_alpha); vec3 grid_b = mix(grid_a, inside_color.rgb, inside_grid * inside_color.a); vec3 grid = mix(grid_b, grid_color.rgb, base_grid * grid_color.a); ALBEDO = grid; METALLIC = metalic; ROUGHNESS = roughness; }