我有一个
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);
这并不理想。 我已将其设为统一,但这仍然意味着如果我更改纹理的大小,我将需要更新使用此着色器的每个位置。 我仍然想要一个一般性的答案。