| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- 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);
- }
|