В Godot 4 шейдер не закрашивает правильные пиксели

У меня есть TileSet, и я пытаюсь применить пользовательские Shader и ShaderMaterial к одной из моих плиток. Однако он не затеняет нужную область. Я новичок как в Godot, так и в разработке игр, но все, что я прочитал, похоже, указывает на то, что мой код правильный.

shader_type canvas_item;

uniform vec2 points[3]; // Polygon points
uniform vec2 atlas_id; // atlas position within the TileSet
uniform vec2 tile_size = vec2(32.0, 32.0);
uniform vec4 modulate_color : source_color;

// code generated by Copilot
bool point_in_triangle(vec2 p, vec2 p0, vec2 p1, vec2 p2) {
    vec2 v0 = p2 - p0;
    vec2 v1 = p1 - p0;
    vec2 v2 = p - p0;

    float dot00 = dot(v0, v0);
    float dot01 = dot(v0, v1);
    float dot02 = dot(v0, v2);
    float dot11 = dot(v1, v1);
    float dot12 = dot(v1, v2);

    float invDenom = 1.0 / (dot00 * dot11 - dot01 * dot01);
    float u = (dot11 * dot02 - dot01 * dot12) * invDenom;
    float v = (dot00 * dot12 - dot01 * dot02) * invDenom;

    return (u >= 0.0) && (v >= 0.0) && (u + v < 1.0);
}

void fragment() {
  vec2 top_left_px = atlas_id * tile_size;
  vec2 pixel_coordinate = UV / TEXTURE_PIXEL_SIZE;
  pixel_coordinate[0] = mod(pixel_coordinate[0], tile_size[0]);
  vec2 relative_coord = pixel_coordinate - top_left_px;

  // Check if the current fragment is inside the triangle
  if (point_in_triangle(relative_coord, points[0], points[1], points[2])) {
    COLOR *= modulate_color;
  }
}

Текстура моего TileSet имеет размер 256x256 с плитками 32x32.

Я пытаюсь заштриховать треугольники в третьем ряду с помощью шейдера. Это результат приведенного выше кода.

Хоть убей, я не могу понять, что я делаю не так. Если бы мне пришлось угадывать, то это расчет vec2 pixel_coordinate = UV / TEXTURE_PIXEL_SIZE;. Я просто не понимаю почему и не нашел хорошего способа отладки шейдера без отладчика или printf.

Редактировать

Когда я жестко запрограммировал размер текстуры, он работает отлично.

  vec2 pixel_coordinate = UV * vec2(256.0, 256.0);

Это вряд ли идеально. Я сделал его однородным, но это по-прежнему означает, что если я когда-нибудь изменю размер текстуры, мне придется обновить каждое место, где я использую этот шейдер. Мне все же хотелось бы общего ответа.

У меня не было времени полностью продумать логику point_in_triangle, но dot01 * dot01 кажется мне странным. Поскольку остальная часть функции очень симметрична, я ожидаю, что одна из них будет dot10.

0x5453 07.08.2024 23:31

Я почти уверен, что это не код обнаружения треугольника. Я заменил код простой проверкой, находится ли он в прямоугольнике, содержащем треугольник, и позиции по-прежнему отклоняются от тех же полей.

dx_over_dt 08.08.2024 00:03
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Просто отключите заполнение текстуры в конфигурации TileSet, шейдер применяется к исходной текстуре и не учитывает заполнение, отсюда и странное масштабирование.

Другие вопросы по теме