shader_type canvas_item; const float base_line_width = 2.0f; const float base_square_size = 11.0f; const float base_center_size = 11.0f; // 使用数组传递点 uniform vec2 points[4]; uniform vec4 square_color: source_color; uniform vec4 square_line_color: source_color; uniform bool editable; varying vec2 pixel_pos; varying float line_width; varying float square_size; varying float center_size; int in_square(vec2 center, vec2 m) { float dx = abs(m.x - center.x); float dy = abs(m.y - center.y); bool on_edge = (abs(dx - square_size) <= line_width && dy <= square_size) || (abs(dy - square_size) <= line_width && dx <= square_size); bool inside = dx <= square_size && dy <= square_size; return on_edge ? 0 : (inside ? 1 : -1); } int in_line(vec2 p1, vec2 p2, vec2 m) { vec2 v = p2 - p1, w = m - p1; float sq_len = dot(v, v); if (sq_len < 0.001) return length(w) <= line_width ? 0 : -1; float t = clamp(dot(w, v) / sq_len, 0.0, 1.0); return length(m - (p1 + t * v)) <= line_width ? 0 : -1; } int in_center(vec2 center, vec2 m) { float dis = distance(center, m); if (dis < line_width * 2.0) return 0; if (center_size - line_width < dis && dis < center_size + line_width) return 0; return -1; } int detect_pixel(vec2 check_points[9], vec2 pos) { for (int i = 0; i < 8; i++) { // 前8个是正方形检测 int result = in_square(check_points[i], pos); if (result >= 0) return result; } for (int i = 0; i < 4; i++) { // 边线检测 int result = in_line(points[i], points[(i + 1) % 4], pos); if (result >= 0) return result; } // 中心区域检测 return in_center(check_points[8], pos); } void vertex() { pixel_pos = (MODEL_MATRIX * vec4(VERTEX, 0.0, 1.0)).xy; float scale = length(vec2(CANVAS_MATRIX[0][0], CANVAS_MATRIX[1][1])); line_width = base_line_width / scale; square_size = base_square_size / scale; center_size = base_center_size / scale; } void fragment() { vec2 check_points[9] = { // 角点 points[0], points[1], points[2], points[3], // 边中点 (points[0] + points[1]) / 2.0, (points[1] + points[2]) / 2.0, (points[2] + points[3]) / 2.0, (points[3] + points[0]) / 2.0, // 中心点 (points[0] + points[2]) / 2.0 }; int point_mode = -1; if (editable) point_mode = detect_pixel(check_points, pixel_pos); else for (int i = 0; i < 4; i++) { // 边线检测 int result = in_line(check_points[i], check_points[(i + 1) % 4], pixel_pos); if (result >= 0) point_mode = 0; } if (point_mode == 0) COLOR = square_line_color; else if(point_mode == 1) COLOR = square_color; else COLOR = texture(TEXTURE, UV); }