在 Godot 4 中,着色器未对正确的像素进行着色

问题描述 投票:0回答:1

我有一个

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。

TileSet texture

我正在尝试使用着色器对第三行的三角形进行着色。 这是上面代码的结果。

Result of shader

对于我的一生,我无法弄清楚我做错了什么。 如果非要我猜的话,那就是

vec2 pixel_coordinate = UV / TEXTURE_PIXEL_SIZE;
的计算。 我只是不明白为什么,并且还没有找到在没有调试器或 printf 的情况下调试着色器的好方法。

编辑

当我对纹理大小进行硬编码时,效果非常好。

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

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

shader godot fragment-shader godot4
1个回答
0
投票

只需在 TileSet 配置中禁用纹理填充,着色器将应用于原始纹理并且不知道填充,因此会出现奇怪的缩放。

© www.soinside.com 2019 - 2024. All rights reserved.